来到新公司,看了一下框架,使用了一个jersey的RESTful的API,之前听都没听过,也不知道是个什么鸟东东,抽空看了一下他的简单使用方法和原理,记录一下。

一、web.xml配置

<servlet><servlet-name>JerseyServlet</servlet-name><servlet-class>com.xxx.servlet.MatrixServlet</servlet-class><init-param><param-name>com.sun.jersey.spi.container.ContainerRequestFilters</param-name><param-value>com.xxx.InternalAuthResourceFilter</param-value></init-param><init-param><param-name>com.sun.jersey.spi.container.ResourceFilters</param-name><param-value>com.xxx.RoleApiResourceFilterFactor</param-value></init-param>
</servlet>
<servlet-mapping><servlet-name>JerseyServlet</servlet-name><url-pattern>/*</url-pattern>
</servlet-mapping>

二、源码解析

1、首先在web.xml中声明一个servlet,然后在这个servlet中初始化了两个Filter。我们都知道Filter是拦截请求的,那么问题来了,这两个Filter不是显示的初始声明在web.xml中的,那么他们是怎么起到拦截请求的作用的呢。
进入到MatrixServlet中发现他的继承关系是这样的:

2、首先我们都知道,servlet要是实现javax.servlet接口,web容器在初始化servlet的时候都会调用次接口的init()方法。我们在MatrixServlet中重写它的init()方法:

/*** Initiate the Web component.** @param webConfig the Web configuration.** @throws javax.servlet.ServletException in case of an initialization failure*/protected void init(WebConfig webConfig) throws ServletException {webComponent = (app == null)? new InternalWebComponent(): new InternalWebComponent(app);webComponent.init(webConfig);}

3、在init()方法中调用一下webComponent.init(webConfig)方法初始化web容器。进入到对应方法内,代码如下:

/*** Initiate the Web component.** @param webConfig the Web configuration.* @throws javax.servlet.ServletException in case of any initialization error*/public void init(WebConfig webConfig) throws ServletException {config = webConfig;if (resourceConfig == null)resourceConfig = createResourceConfig(config);if (config.getConfigType() == WebConfig.ConfigType.FilterConfig &&resourceConfig.getFeature(ServletContainer.FEATURE_FILTER_FORWARD_ON_404)) {useSetStatusOn404 = true;}load();Object o = resourceConfig.getProperties().get(ResourceConfig.PROPERTY_CONTAINER_NOTIFIER);if (o instanceof List) {List list = (List) o;for (Object elem : list) {if (elem instanceof ContainerNotifier) {ContainerNotifier crf = (ContainerNotifier) elem;crf.addListener(this);}}} else if (o instanceof ContainerNotifier) {ContainerNotifier crf = (ContainerNotifier) o;crf.addListener(this);}}

4、我们发现其中都是根据加载到的config进行容器配置,此文的目的是找到两个Filter是怎么注册到容器中的,所以相关配置就不讨论了。我们发现此方法中有一个load()方法,进入到load()方法,代码如下:

/*** Load the Web application. This will create, configure and initiate* the web application.*/public void load() {WebApplication _application = create();configure(config, resourceConfig, _application);initiate(resourceConfig, _application);application = _application;}

5、发现是进行WebApplication的创建和配置,其中有一步initiate(resourceConfig, _application),进入到此方法内,代码如下:

/*** Initiate the {@link WebApplication}.* <p/>* This method will be called once at initiation and for* each reload of the Web application.* <p/>* An inheriting class may override this method to initiate the* Web application with different parameters.** @param rc the Resource configuration* @param wa the Web application*/protected void initiate(ResourceConfig rc, WebApplication wa) {wa.initiate(rc);}

6、继续进入代码:

@Override
public void initiate(final ResourceConfig rc, final IoCComponentProviderFactory _provider) {Errors.processWithErrors(new Errors.Closure<Void>() {@Overridepublic Void f() {Errors.setReportMissingDependentFieldOrMethod(false);_initiate(rc, _provider);return null;}});
}

7、发现调用的是另一个_initiate(rc, _provider)方法,此方法有点长,几百行,所以只列出需要的部分代码,在1252行有这样一句代码:

filterFactory.init(resourceConfig);

8、进入到此方法:

public void init(ResourceConfig resourceConfig) {// Initiate request filtersrequestFilters.addAll(getFilters(ContainerRequestFilter.class,resourceConfig.getContainerRequestFilters()));requestFilters.addAll(providerServices.getServices(ContainerRequestFilter.class));// Initiate response filtersresponseFilters.addAll(getFilters(ContainerResponseFilter.class, resourceConfig.getContainerResponseFilters()));responseFilters.addAll(providerServices.getServices(ContainerResponseFilter.class));// Initiate resource filter factoriesresourceFilterFactories.addAll(getFilters(ResourceFilterFactory.class, resourceConfig.getResourceFilterFactories()));resourceFilterFactories.addAll(providerServices.getServices(ResourceFilterFactory.class));resourceFilterFactories.add(new AnnotationResourceFilterFactory(this));
}

9、其中有两句:

requestFilters.addAll(getFilters(ContainerRequestFilter.class,resourceConfig.getContainerRequestFilters()));
resourceFilterFactories.addAll(getFilters(ResourceFilterFactory.class, resourceConfig.getResourceFilterFactories()));

10、而两个方法中对应的第二个参数继续点进去会发现:

public static final String PROPERTY_CONTAINER_REQUEST_FILTERS = "com.sun.jersey.spi.container.ContainerRequestFilters";
public List getContainerRequestFilters() {return getFilterList(PROPERTY_CONTAINER_REQUEST_FILTERS);
}
public static final String PROPERTY_RESOURCE_FILTER_FACTORIES ="com.sun.jersey.spi.container.ResourceFilters";
public List getResourceFilterFactories() {return getFilterList(PROPERTY_RESOURCE_FILTER_FACTORIES);
}

11、获取的就是我们在web.xml中配置的两个Filter,所以当请求来到服务器的时候,就会被这两个Filter拦截,进而就可以在这两个自定义Filter的filter()方法中实现我们对请求的校验等操作。

jersey的简单使用原理(jersey1.15版本)相关推荐

  1. 深入剖析Glide源码-4.15版本(一)

    文章目录 深入剖析Glide源码-4.15版本(一) 一行代码进行图片加载 一.生命周期管理 Glide初始化 RequestManager构建 1. 传入activity时 RequestManag ...

  2. 云原生生态周报 Vol.9| K8s v1.15 版本发布

    本周作者 | 衷源.心贵 业界要闻 1.Kubernetes Release v1.15 版本发布,新版本的两个主题是持续性改进和可扩展性.(https://github.com/kubernetes ...

  3. SQL注入详解和简单绕过原理

    1.什么是SQL 结构化查询语言(Structured Query Language)简称SQL SQL使我们有能力访问数据库 2.什么是SQL注入 用户提交的数据可以被数据库解析执行 如果用户随随便 ...

  4. (转)简单代码生成器原理剖析(二)

    原文地址:http://www.cnblogs.com/OceanEyes/archive/2012/03/08/codebuilder.html 上篇<简单代码生成器原理剖析(一)>分析 ...

  5. 微信二次修改微信号_微信号怎么改第二次?微信7.0.15版本改微信号方法解析

    微信7.0.15版本是最近出来的一个版本,可以修改微信号,赢得了很多用户的关注,那么具体的修改方法是什么?下面就是对相关内容的介绍,感兴趣的话可以一起来了解下. 微信支持修改微信号操作流程 在7.0. ...

  6. 使用pdfbox2.0.15版本,将pdf文件转为图片时,中文显示乱码

    一.问题 在项目中使用pdfbox2.0.15版本,将pdf文件转成图片,在windows本地转换正常,发布到linux服务器,转换后图片中的中文出现部分乱码,显示都是方块□□□. 二.分析 1.日志 ...

  7. 机器人辅助的符文天赋_LOL6.15版本机器人辅助天赋符文出装全攻略

    在LOL6.15版本中,机器人的潜力很强,各大赛区对于机器人的选择率和胜率都是榜单上名列前茅的,那么LOL6.15版本机器人辅助天赋加点该怎么加?符文该怎么搭配?出装该怎么选择?下面今日首发小编就为大 ...

  8. 计算机网络版本变动,云顶之弈9.15版本变动讲解 如何因对新版本节奏

    今天云顶之弈更新了全新的9.15版本,上个版本流行的强势阵容羁绊目前都被大刀削弱,因此不少玩家开始寻找新的阵容玩法.目前可以说是云顶之弈最大的一次更新,环境变动明显,不少玩法思路都将重组,因此每个人都 ...

  9. Linux移植:正点原子阿尔法IMX6ULL开发板Linux内核源码移植详细步骤(4.1.15版本内核)

    Linux移植:正点原子阿尔法IMX6ULL开发板Linux内核源码移植详细步骤(4.1.15版本内核) 文章目录 Linux移植:正点原子阿尔法IMX6ULL开发板Linux内核源码移植详细步骤(4 ...

最新文章

  1. eas库存状态调整单不能反审核_仓储管理笔记:库存差错、毁损赔偿、自用管理、组织架构.........
  2. typecho 去掉index.php,Typecho设置伪静态去掉url中的index.php
  3. android版本迭代,多盟:android2.3仍是主流 iOS新版本迭代加
  4. 2021芜湖高考成绩查询,2021芜湖市地区高考成绩排名查询,芜湖市高考各高中成绩喜报榜单...
  5. Maven(一):Maven安装及Eclipse配置
  6. MacOS使用top命令查看进程使用内存
  7. Python 数据结构与算法 —— 从分治的角度看快速排序、归并排序
  8. NO.4 计算有序数组的平方
  9. 官网下载mysql连接驱动jar包教程
  10. 码农小汪-锁 LOCK
  11. 设定自己的100个人生目标
  12. Ubuntu18.04 安装运行windows程序(qq 微信 caj阅读器等)+解决wine中文乱码
  13. 数据库服务器,sql
  14. 911报警电话数据分析
  15. 好友推荐(列转行,help_topic_id)
  16. python画位势高度图_气候变化位势高度
  17. 《Adobe InDesign CS5中文版经典教程》—第1课1.2节工作区简介
  18. python手写板,机器语言之手写识别_源码时代Python公开课|Python培训
  19. python爬取物流信息_python爬虫快递查询系统(源码)
  20. Nodejs等待一段时间

热门文章

  1. 在Python中使用OpenCV进行直线检测
  2. 如何选择MySQL中除一列外的所有列
  3. Excel打开UTF-8编码CSV文件乱码的问题
  4. 判断三角形是逆时针还是顺时针
  5. Android8.1 MTK平台 Dialer修改(来电全屏、归属地显示)
  6. Reactive思考
  7. 2021北京信息科技大学光电学院调剂复试经历
  8. CANopen对象字典
  9. 笑破你肚皮的夜间护花行动
  10. 剑指offer刷题(一刷)笔记 2019.12.15