java从Jersey筛选器或拦截器内部访问资源方法参数。或者将AOP与资源方法一起使用
我试图在每个请求上使用用户ID丰富SLF4J MDC。问题是ID可以通过多种方式传递,有时作为路径参数传递,有时在正文中传递,有时由首先解密它的自定义ValueFactoryProvider
注入
如果我能以某种方式访问所有注入的(即,已反序列化的)参数值,我就能轻松处理所有这些情况
例如
对于资源,例如:
@GET
//@Encrypted params are injected by a custom ValueFactoryProvider
public Something getSomething(@Encrypted("userId") String userId) {
return ...;
}
@POST
public Something getSomething(@RequestBody RequestWithUserId requestWithUserId) {
return ...;
}
我可以有一个过滤器,例如:
public class MdcFilter implements ContainerRequestFilter, ContainerResponseFilter {
@Context
private ResourceInfo resourceInfo;
@Override
public void filter(ContainerRequestContext requestContext) throws IOException {
Method theMethod = resourceInfo.getResourceMethod();
for (Parameter parameter : theMethod.getParameters()) {
//Deal with the @Encrypted case
if (parameter.isAnnotationPresent(Encrypted.class) && parameter.getAnnotation(Encrypted.class).value().equals("userId")) {
MDC.put("userId", somehowGetTheValue());
}
//Deal with the @RequestBody case
if (parameter.isAnnotationPresent(RequestBody.class) && parameter.getType().equals(RequestWithUserId.class)) {
MDC.put("userId", ((RequestWithUserId)somehowGetTheValue()).getUserId());
}
... //other possibilities
}
}
@Override
public void filter(ContainerRequestContext requestContext, ContainerResponseContext responseContext) throws IOException {
MDC.clear();
}
}
但是我看不到一种实现somehowGetTheValue
的方法,无论是从ContainerRequestFilter
拦截器还是其他任何东西
# 1 楼答案
你可以这样得到它
基本上,这个想法是复制流并进行任何处理,然后将流设置回原来的位置。因为如果您不这样做,那么在您的控制器方法中,您将得到null,因为流已经被读取
# 2 楼答案
Jersey在引擎盖下使用HK2进行依赖注入。而香港2号则有AOP support。用例的一个选项是使用此AOP支持。您所需要做的就是实现一个^{} 和一个^{} 。在
MethodInterceptor
中,可以从MethodInvocation
获取所有参数,也可以从Method
获取参数注释要使用拦截器,请配置
InterceptionService
您可以确定应该在
getMethodInterceptors()
方法中拦截哪个方法。如果应该拦截该方法,则返回拦截器列表,否则返回null。处理这个问题的一种常见方法是创建一个自定义注释,然后只对方法进行注释。在上述方法中,只需检查要使这一切正常工作,您只需向HK2注册
InteceptionService
。您可以在AbstractBinder
中执行此操作,这是Jersey应用程序中用于配置DI的内容您可以在this GitHub repo中看到一个完整的示例。在HK2网站上也有一个官方的例子。请参见文章顶部的“AOP支持”链接