我需要Jersey 2.x中的Interceptor,它提供了对请求,响应和与Web服务的路径匹配的方法的引用。Jersey中是否存在类似于Spring的HandlerInterceptor的拦截器
类似的东西到春天的的HandlerInterceptor。
要求:
- 需要对 Class用于注解 - 执行下面的检查,只有当需要由球衣调用相应的方法不是使用自定义注解。
- 请求 - 获取/设置属性并获取会话对象来验证用户。
- 响应 - 重新定向的情况下,任何验证,甚至调用相应Methos之前失败的呼叫。
春等效代码:
public class WebServiceInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
try {
SkipWebServiceIntercept skipWebService = handler.getClass().getAnnotation(SkipWebServiceIntercept.class);
if (skipWebService != null) {
return Boolean.TRUE;
}
...
if(securityFails)
{
if ("XMLHttpRequest".equals(request.getHeader("X-Requested-With"))) {
response.setCharacterEncoding("utf-8");
response.setContentType("application/json");
PrintWriter out = response.getWriter();
String json;
...
out.println(json);
return Boolean.FALSE;
}
else {
response.sendRedirect(redirectUrl);
}
}
else
{
return Boolean.TRUE;
}
}catch (Exception e) {
log.error("Exception in preHandle, redirecting to Login page", e);
return LoginUtil.redirectToLogin(request, response);
}
}
}
我发现
- ReaderInterceptor的引用 - 这只是提供了类的注释。无法访问请求/响应。
- ContainerRequestFilter - 提供请求对象但不提供注释/响应。
- ContainerResponseFilter - 给请求&响应。但是在调用Web服务/方法之后。
有任何其它方式这可以在不使用过滤器来实现。因为只有当相应的Web服务存在时,我才需要进行此处理。 另一方面,使用/ *的过滤器将始终执行这些验证,即使资源未找到。
编辑: 感谢@peeskillet answer这是我如何实现它。
@Provider
public class ResourceInterceptor implements DynamicFeature {
@Override
public void configure(ResourceInfo resourceInfo, FeatureContext context) {
System.out.println("Resource Interceptor called");
if (resourceInfo.getResourceClass() != null
&& resourceInfo.getResourceClass().getAnnotation(SkipWebServiceIntercept.class) != null)
return;
context.register(LoginFilter.class);
}
}
@Slf4j
public class LoginFilter implements ContainerRequestFilter {
@Context
private HttpServletRequest request;
@Context
private ServletContext servletContext;
@Override
public void filter(ContainerRequestContext requestContext) throws IOException {
try {
WebApplicationContext springContext = WebApplicationContextUtils.getWebApplicationContext(servletContext);
CookieAuthenticator cookieAuthenticator = springContext.getBean(CookieAuthenticator.class);
HttpSession session = request.getSession(true);
...
//发送JSON /对象回到作为响应
...
String json = gson.toJson(resposeJson);
Response response = new ResponseBuilderImpl().encoding(StandardCharsets.UTF_8.name())
.type(MediaType.APPLICATION_JSON).entity(json).build();
requestContext.abortWith(response);
...
//或发送URL背面
...
URI uri = new URI(baseUrl + redirectUrl + "?refback=" + url);
requestContext.abortWith(Response.temporaryRedirect(uri).build());
...
两者的方法完美地工作,类似于HandlerInterce春天的ptor。
使用'ContainerRequestFilter'的是,我不会有响应对象与我的问题。我可以访问ResourceInfo来检查注释,但如果验证失败,那么我将不得不从过滤器本身重定向而不调用资源。 使用** Servlet过滤器**我可以使用response.sendRedirect()来实现这一点。我如何使用ContainerRequestFilter来做到这一点?我探索了ContainerRequestContext的所有API,但无法找到响应。 那么有没有办法从ContainerRequestFilter重定向到另一个URL呢? –
您可以使用'requestContext.abortWith(Response)'...('Response.seeOther(...)'进行重定向) –
或者您可以抛出异常并在[ExceptionMapper]中处理重定向(https:// jersey.java.net/documentation/latest/representations.html#d0e6665) –