如何解决Jersey 1.x JAX-RS:一般未处理的异常 java.lang.IllegalStateException
我们在 jersey 1.13 (jax-rs 1.x
) 上构建了旧 API,并部署到 glassfish 3.1.2 服务器。我们有多个 ContainerRequestFilters
并且通过 web.xml
配置相同。以下是示例参考:
<servlet>
<servlet-name>ApplyRestfulService</servlet-name>
<servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>
.....
<init-param>
<param-name>com.sun.jersey.spi.container.ContainerResponseFilters</param-name>
<param-value>com.api.filter.CorsFilter</param-value>
</init-param>
<init-param>
<param-name>com.sun.jersey.spi.container.ContainerRequestFilters</param-name>
<param-value>
com.api.filter.CorsFilter,com.api.filter.AuthenticationFilter,com.api.filter.AuthorizationFIlter
</param-value>
</init-param>
</servlet>
我的理解是请求过滤器将在调用资源之前按照上面定义的顺序执行,即
第一个CorsFilter
--> AuthenticationFIlter
--> AuthorizationFIlter
--> Some API Resource
在 AuthenticationFilter 中,我们将自定义 securityContext 对象设置为 ContainerRequest
以在下一个过滤器中使用,如下所示
@Provider
public class AuthenticationFilter implements ContainerRequestFilter {
private static final Logger logger = Logger.getLogger(AuthenticationFilter.class) ;
private static final String PREFIX_JWT = "JWT ";
@Override
public ContainerRequest filter(ContainerRequest request) {
AuthenticationResponse authenticationResponse = someJWTAuthenticationMethod(request);
request.setSecurityContext(new Authorizer(authenticationResponse));
return request;
}
Authorizer 是一个实现 SecurityContext
的自定义类。在 SecurityContext 中设置响应的意图是在下一个过滤器中获取它,即 AuthorizationFilter
。我们使用@Context
注解读取SecurityContext
如下图
@Provider
@ApplicationScoped
public class AuthorizationFilter implements ContainerRequestFilter {
@Context
private SecurityContext context;
@Inject
private SomeDAO someDAO;
@Override
public ContainerRequest filter(ContainerRequest request) {
String accountId = ((AuthenticationResponse) context.getUserPrincipal()).getSomeId();
UserPrincipal user = getUser(accountId);
request.setSecurityContext(new Authorizer(user));
}
return request;
}
这似乎一切正常,但是当我们尝试访问 AuthenticationFilter RequestFilter 中的 Exception
时,很多时候我们都低于 SecurityContext
:
[#|2021-03-02T07:24:55.486+0000|INFO|oracle-glassfish3.1.2|javax.enterprise.system.std.com.sun.enterprise.server.logging|_ThreadID=40;_ThreadName=http-thread-pool-8080(5);|ERROR [http-thread-pool-8080(5)] - General unhandled exception
java.lang.IllegalStateException
at com.sun.jersey.server.impl.ThreadLocalHttpContext.getRequest(ThreadLocalHttpContext.java:82)
at com.sun.jersey.server.impl.application.WebApplicationImpl$2.invoke(WebApplicationImpl.java:287)
at com.sun.proxy.$Proxy226.getUserPrincipal(UnkNown Source)
at com.api.filter.AuthorizationFilter.filter(AuthorizationFilter.java:36)
at com.api.filter.AuthorizationFilter$Proxy$_$$_WeldClientProxy.filter(AuthorizationFilter$Proxy$_$$_WeldClientProxy.java)
at com.sun.jersey.server.impl.application.WebApplicationImpl._handleRequest(WebApplicationImpl.java:1454)
at com.sun.jersey.server.impl.application.WebApplicationImpl._handleRequest(WebApplicationImpl.java:1400)
at com.sun.jersey.server.impl.application.WebApplicationImpl.handleRequest(WebApplicationImpl.java:1349)
at com.sun.jersey.server.impl.application.WebApplicationImpl.handleRequest(WebApplicationImpl.java:1339)
at com.sun.jersey.spi.container.servlet.WebComponent.service(WebComponent.java:416)
at com.sun.jersey.spi.container.servlet.ServletContainer.service(ServletContainer.java:537)
at com.sun.jersey.spi.container.servlet.ServletContainer.service(ServletContainer.java:708)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:770)
当我们重新启动 glassfish 服务器时,问题得到解决,但这更多地只是一种解决方法,而不是真正的解决方案。
这可能是因为 AuthenticationFIlter
是 ApplicationScoped
并且当多个线程访问 API 时导致上述错误?
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。