Jersey ContainerRequestFilter 未触发
Posted
技术标签:
【中文标题】Jersey ContainerRequestFilter 未触发【英文标题】:Jersey ContainerRequestFilter not triggered 【发布时间】:2013-06-22 10:05:20 【问题描述】:我正在尝试使用 ContainerRequestFilter
对基于 Tomcat 的 Jersey 应用程序执行一些身份验证。我关注了this document。
问题:过滤器永远不会被触发
过滤器类:
@Provider
public class AuthFilter implements ContainerRequestFilter
@Override
public void filter(ContainerRequestContext requestContext)
throws IOException
// MY AUTHENTICATION CODE GOES HERE
web.xml 文件:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
id="debate-rest"
version="3.0">
<display-name>rest</display-name>
<servlet>
<servlet-name>Jersey REST Service</servlet-name>
<servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
<init-param>
<param-name>com.sun.jersey.spi.container.ContainerRequestFilters</param-name>
<param-value>com.hck.debate.rest.security.AuthFilter</param-value>
</init-param>
<init-param>
<param-name>jersey.config.server.provider.packages</param-name>
<param-value>com.hck.debate.rest.controller</param-value>
</init-param>
<init-param>
<param-name>com.sun.jersey.api.json.POJOMappingFeature</param-name>
<param-value>true</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Jersey REST Service</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
【问题讨论】:
【参考方案1】:我们在 ResourceConfig 实现类中缺少以下调用:
register(CorrelationIdFilter.class);
【讨论】:
【参考方案2】:我对 JAX-RS 2 有同样的问题,球衣和下面的注释修复了它
@PreMatching
【讨论】:
但这会改变语义!添加此方法仅会影响何时调用过滤器。我严重怀疑这会改变任何东西的配置! 谢谢,这正是我所需要的。【参考方案3】:对于在 MULE ESB 中遇到此问题的任何人。 记得注册路径:
<jersey:resources doc:name="REST">
<component doc:name="rest component">
<spring-object bean="endpoit"/>
</component>
<jersey:package packageName="path @Provider-s"/>
</jersey:resources >
【讨论】:
【参考方案4】:如果您像我一样被卡住,请注意 TomEE 1.7.X 使用 JAX-RS 1.1,它不包括 ContainerRequestFilter。
【讨论】:
【参考方案5】:好吧,我没明白jersey.config.server.provider.packages
init 参数不仅需要引用服务类(API 端点),还需要引用所有类,包括过滤器。
现在可以了:
<init-param>
<param-name>jersey.config.server.provider.packages</param-name>
<param-value>com.hck.debate.rest.controller;com.hck.debate.rest.security</param-value>
</init-param>
<init-param>
<param-name>com.sun.jersey.spi.container.ContainerRequestFilters</param-name>
<param-value>com.hck.debate.rest.security.AuthFilter</param-value>
</init-param>
【讨论】:
你上面的代码和 TomCat 一样工作,也许它和 Glas Fish 不同 默认行为是递归扫描,所以你也可以只使用单个基础包com.hck.debate.rest
还要注意com.sun.jersey.spi.container.ContainerRequestFilters
和com.sun.jersey.api.json.POJOMappingFeature
是没用的。这些是 Jersey 1.x 属性。它们对 Jersey 2.x 没有影响
另请注意,默认情况下,包扫描是递归的。所以不用列出多个包,只需声明一个基本包,如com.hck.debate.rest
,它会递归扫描所有子包。
仅供参考,扫描是为了获取带有@Provider
和@Path
注释的类,因此您需要确保还具有@Provider
注释。【参考方案6】:
我使用了 com.sun.jersey 而不是 javax.ws.rs,它可以工作
import com.sun.jersey.spi.container.ContainerRequestFilter
import com.sun.jersey.spi.container.ContainerRequest
Dropwizard 用户需要这样做
environment.jersey().getResourceConfig()
.getContainerRequestFilters()
.add(filter);
【讨论】:
从而创建依赖于你不应该依赖的包的代码。【参考方案7】:您可以使用JerseyServletFactory
手动注册ContainerRequestFilter
,而不是使用@Provider
注释:
JerseyServletFactory jerseyServletFactory = new JerseyServletFactory(config);
HttpServlet myServiceServlet = jerseyServletFactory.create(myResource);
// Register your ContainerRequestFilter like this
jerseyServletFactory.addRequestFilter(new MyFilter());
httpServer.register(myServiceServlet, "/api");
httpServer.start();
【讨论】:
这段代码应该放在哪里? @jon 在初始化期间。我将我的代码放在JettyHttpServer
的创建和开始之间,以及需要在开始时初始化的其他内容(数据源、资源、DAO 等)
我也做了同样的事情,现在我想调用 servlet 的销毁(用于一些自定义清理任务)。我无法获取此过滤器的引用以在关闭事件中调用销毁。【参考方案8】:
一些提示:
-
确保您使用的是 JAX-RS 2.17 版。
确保您在过滤器中使用了正确的导入:
import javax.ws.rs.container.ContainerRequestContext;
import javax.ws.rs.container.ContainerRequestFilter;
添加@Provider
注解
【讨论】:
“@Provider”真的有必要吗? 是的,它将组件注释为某物的提供者。它用于扩展基本的 JAX-RS 功能。【参考方案9】:我还必须将 @Provider JAX-RS 注释添加到我的过滤器中。 这使得过滤器可以在 JAX-RS 扫描阶段被发现。
@Provider
public class MyAppFilter implements ContainerRequestFilter
// filter logic
【讨论】:
这里没有注释什么都没有发生 “@Provider”真的有必要吗? 是的,我只需要添加@Provider 注释。包裹扫描已正确设置【参考方案10】:将过滤器与球衣搭配使用的最低要求:
为过滤器类添加@Provider注解 过滤器类的命名空间必须包含在'jersey.config.server.provider.packages' init-param中不需要任何其他设置(例如,'com.sun.jersey.spi.container.ContainerRequestFilters' init-param 或 ResourceConfig)
【讨论】:
“@Provider”真的有必要吗? 是的。 Jersey 将只加载指定命名空间中标记的类以上是关于Jersey ContainerRequestFilter 未触发的主要内容,如果未能解决你的问题,请参考以下文章
Jersey:是不是可以覆盖 Jersey filter() 的返回类型?
将使用 jersey 1.x 的 java 代码转换为 jersey 2.x