
引言
本篇介绍 flea-jersey模块下的flea-jersey-server 子模块,该模块封装了通用的POST
、PUT
、DELETE
和 GET
资源。

1. 服务端依赖
项目内容可至GitHub 查看 flea-jersey-server
相关依赖如下:
1 2 3 4 5 6
| <dependency> <groupId>com.huazie.fleaframework</groupId> <artifactId>flea-jersey-server</artifactId> <version>2.0.0</version> </dependency>
|
2. 服务端接入步骤
- 服务端自定义资源入口类,继承 FleaResourceConfig;
- 服务端自定义资源,并配置到资源表中;
- 服务端自定义资源服务,并配置到资源服务表中;
- 服务端完成资源服务的业务逻辑开发,配置国际码和错误码映射关系。
3. 具体接入讲解
3.1 资源入口类定义
FleaResourceConfig ,即Flea 资源配置类,作为 Jersey 应用的资源入口,用于配置 Web 应用程序。
该类初始化时,从 Flea Jersey 资源表中,获取定义的所有资源包名; 并将所有资源包都添加到扫描组件中,以待被递归扫描(包括所有嵌套包)。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
| public abstract class FleaResourceConfig extends ResourceConfig {
private static final FleaLogger LOGGER = FleaLoggerProxy.getProxyInstance(FleaResourceConfig.class);
public FleaResourceConfig() { init(); }
private void init() { List<String> resourcePackages = null; try { WebApplicationContext webApplicationContext = ContextLoader.getCurrentWebApplicationContext(); FleaConfigDataSpringBean springBean = webApplicationContext.getBean(FleaConfigDataSpringBean.class); resourcePackages = springBean.getResourcePackages(); } catch (Exception e) { if (LOGGER.isErrorEnabled()) { LOGGER.error1(new Object() {}, "Exception occurs when getting resource packages : \n", e); } }
if (CollectionUtils.isNotEmpty(resourcePackages)) { if (LOGGER.isDebugEnabled()) { LOGGER.debug1(new Object() {}, "scan packages : {}", resourcePackages); } packages(resourcePackages.toArray(new String[0])); } register(MultiPartFeature.class); } }
|
另外每个接入 Flea Jersey 的应用,都需创建 Flea 资源配置的子类,作为其发布的资源的入口;并在该类上标记注解 ApplicationPath
, 其值为该应用对外发布的资源的相对访问路径。
对于 FleaFS 应用而言,就是如下的 FleaFS 资源入口类:
1 2 3 4 5 6 7 8 9
| @ApplicationPath("/fleafs/*") public class FleaFSResourceConfig extends FleaResourceConfig {
public FleaFSResourceConfig() { super(); FleaJerseyFilterConfig.setFilePath("flea/jersey/fleafs-jersey-filter.xml"); } }
|
这里我们在入口类的无参构造方法中,可以看到设置 Jersey 过滤器配置文件路径的代码,下面来介绍下这个配置文件:
3.2 Jersey 过滤器配置文件
FleaFS Jersey 过滤器配置文件,该文件中可定义FleaFS应用下的接口处理的前置、业务服务、后置和异常过滤器链,并导入了公共的 flea jersey 接口过滤器公共配置文件。
1 2 3 4 5 6 7 8 9 10 11
| <?xml version="1.0" encoding="UTF-8"?> <jersey> <filter-chain> <before> <filter clazz="com.huazie.ffs.jersey.filter.FleaFSAuthCheckFilter" order="3" desc="FleaFS业务授权校验过滤器"/> </before> </filter-chain> <import resource="flea/jersey/flea-jersey-filter.xml"/> </jersey>
|
flea jersey 接口过滤器公共配置文件,该文件中包含了Flea Jersey默认的前置、业务服务、后置和异常过滤器链,I18N国际化映射配置等信息。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47
| <?xml version="1.0" encoding="UTF-8"?>
<jersey>
<filter-chain>
<before> <filter clazz="com.huazie.fleaframework.jersey.server.filter.impl.DataPreCheckFilter" order="1" desc="数据预校验过滤器"/> <filter clazz="com.huazie.fleaframework.jersey.server.filter.impl.AuthCheckFilter" order="2" desc="授权校验过滤器"/> </before>
<service> <filter clazz="com.huazie.fleaframework.jersey.server.filter.impl.InvokeServiceFilter" order="1" desc="服务调用过滤器"/> </service>
<after> <filter clazz="com.huazie.fleaframework.jersey.server.filter.impl.JerseyLoggerFilter" order="1" desc="Jersey日志记录过滤器"/> </after>
<error> <filter clazz="com.huazie.fleaframework.jersey.server.filter.impl.ErrorFilter" order="1" desc="异常过滤器"/> </error>
</filter-chain>
<filter-i18n-error> <i18n-error-mapping i18nCode="ERROR-JERSEY-FILTER0000000003" errorCode="100000">请求报文不能为空</i18n-error-mapping> <i18n-error-mapping i18nCode="ERROR-JERSEY-FILTER0000000004" errorCode="100001">请求公共报文不能为空</i18n-error-mapping> <i18n-error-mapping i18nCode="ERROR-JERSEY-FILTER0000000005" errorCode="100002">请求业务报文不能为空</i18n-error-mapping> <i18n-error-mapping i18nCode="ERROR-JERSEY-FILTER0000000006" errorCode="100003">请求公共报文入参【{0}】不能为空</i18n-error-mapping> <i18n-error-mapping i18nCode="ERROR-JERSEY-FILTER0000000008" errorCode="100004">未能找到指定资源服务配置数据【service_code = {0} ,resource_code = {1}】</i18n-error-mapping> <i18n-error-mapping i18nCode="ERROR-JERSEY-FILTER0000000009" errorCode="100005">请检查服务端配置【service_code = {0} ,resource_code = {1}】:【{2} = {3}】非法</i18n-error-mapping> <i18n-error-mapping i18nCode="ERROR-JERSEY-FILTER0000000010" errorCode="100006">资源【{0}】下的服务【{1}】请求异常:配置的出参【{2}】与服务方法【{3}】出参【{4}】类型不一致</i18n-error-mapping> <i18n-error-mapping i18nCode="ERROR-AUTH-COMMON0000000007" errorCode="100007">用户【user_id = {0}】不存在或已失效!</i18n-error-mapping> <i18n-error-mapping i18nCode="ERROR-AUTH-COMMON0000000008" errorCode="100008">账户【account_id = {0}】不存在或已失效!</i18n-error-mapping> <i18n-error-mapping i18nCode="ERROR-AUTH-COMMON0000000021" errorCode="100009">资源【resource_code = {0}】不存在或已失效!</i18n-error-mapping> <i18n-error-mapping i18nCode="ERROR-AUTH-COMMON0000000022" errorCode="100010">账户【account_id = {0}】没有权限调用归属于系统【system_account_id = {1}】的资源【{2}】</i18n-error-mapping> <i18n-error-mapping i18nCode="ERROR-AUTH-COMMON0000000023" errorCode="100011">当前资源【{0}】不属于指定系统【system_account_id = {1}】,请确认!</i18n-error-mapping> <i18n-error-mapping i18nCode="ERROR-JERSEY-COMMON0000000000" errorCode="100012">【{0}】获取失败,请检查!</i18n-error-mapping> <i18n-error-mapping i18nCode="ERROR-JERSEY-COMMON0000000001" errorCode="100013">【{0}】不能为空,请检查!</i18n-error-mapping> </filter-i18n-error>
</jersey>
|
3.3 资源定义
REST服务的核心是对外公布的资源API。如下 DownloadResource 下载资源类由注解 Path
修饰,其资源路径为 download
。
1 2 3 4 5 6 7 8 9 10 11 12
| @Path("download") public class DownloadResource extends FleaJerseyFGetResource implements JerseyPostResource {
@Override public FleaJerseyResponse doPostResource(FleaJerseyRequest request) { return doResource(request); }
}
|
下载资源类继承 FleaJerseyFGetResource
,即 Flea Jersey文件GET资源【它只包含了文件GET资源API】。同时实现 JerseyPostResource
接口,即Jersey POST 资源接口【它只包含 POST资源API】。
这里主要考虑下载资源仅支持文件的下载【通过 FleaJerseyFGetResource
】和下载的鉴权【通过 JerseyPostResource
】。
有了下载资源类,下面就需要我们配置该资源;
资源配置在 flea_jersey_resource 表中,需要新增如下配置:

应用服务启动后,FleaFSResourceConfig 会扫描所有定义的资源包,即将如上resource_packages 字段定义的包都扫描一遍,这样这些包内所有资源类所提供的资源路径将被映射到内存中。详细内容可参考 FleaResourceConfig。
3.3 资源服务定义
3.3.1 资源服务接口
IFleaDownloadSV
即下载资源的资源服务接口,如下贴出的是下载授权的资源服务方法。
1 2 3 4 5 6 7 8 9 10 11
| public interface IFleaDownloadSV {
OutputDownloadAuthInfo downloadAuth(InputDownloadAuthInfo input) throws CommonException; }
|
3.3.2 资源服务实现类
FleaDownloadSVImpl
即下载资源的资源服务实现类
1 2 3 4 5 6 7 8
| @Service public class FleaDownloadSVImpl implements IFleaDownloadSV {
@Override public OutputDownloadAuthInfo downloadAuth(InputDownloadAuthInfo input) throws CommonException { return null; } }
|
3.3.3 资源服务配置
有了资源服务接口和实现类,下面就需要进行资源服务配置,该配置在 flea_jersey_res_service 表中,如下所示:

其中 flea_jersey_res_service
的表结构如下:
字段名 |
中文描述 |
service_code |
服务编码 |
resource_code |
资源编码 |
service_interfaces |
资源服务接口类 |
service_method |
资源服务方法 |
service_input |
资源服务入参 |
service_output |
资源服务出参 |
3.3.4 资源服务调用
上述资源服务调用逻辑, 可参考 服务调用过滤器 InvokeServiceFilter。
InvokeServiceFilter
, 即资源服务调用过滤器实现,它是Flea Jersey接口的核心逻辑。
首先,它从请求公共报文中获取资源编码【RESOURCE_CODE
】和服务编码【SERVICE_CODE
】;
接着,根据它俩获取相关资源服务配置数据,其中包括资源服务接口、方法、出入参【由服务提供方约定】等;
再接着,根据服务接口,从Web应用上下文中获取Spring注入的服务;
然后,从请求业务对象中,取请求业务报文JSON串,并转换为资源服务方法的入参对象;
再然后,通过反射调用对应的资源服务方法,并获取资源服务方法的出参对象;
最后,将出参对象转换成业务返回报文JSON串,并添加至响应业务对象中返回。
3.4 资源服务业务逻辑开发
如下简单演示了资源服务的业务逻辑开发:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| @Override public OutputDownloadAuthInfo downloadAuth(InputDownloadAuthInfo input) throws Exception { String fileId = input.getFileId(); if (StringUtils.isBlank(fileId)) { throw new ServiceException("ERROR-SERVICE0000000001", "fileId"); }
OutputDownloadAuthInfo output = new OutputDownloadAuthInfo(); output.setToken(RandomCode.toUUID());
return output; }
|
3.5 国际码和错误码映射
代码中出现 ERROR-SERVICE0000000001
的异常,需要配置如下国际码和错误码的映射关系:
(国际码和错误码映射配置表 flea_jersey_i18n_error_mapping
)

当然,我们也可以像3.2中,在过滤器配置文件中添加国际码和错误码的映射关系配置。
1 2 3 4 5 6 7 8 9
| <?xml version="1.0" encoding="UTF-8"?> <jersey>
<filter-i18n-error> <i18n-error-mapping i18nCode="ERROR-SERVICE0000000001" errorCode="110001">入参【{0}】不能为空</i18n-error-mapping> </filter-i18n-error> </jersey>
|
总结
至此,Flea RESTful接口服务端接入已经完成。下篇 Huazie 将介绍 Flea RESTful 接口客户端接入,并以此来调用本篇介绍的下载资源服务,敬请期待!