我想为Apache CXF JAX-RS实现编写一个拦截器,该实现检查特定注释的目标服务/方法,并对该注释进行一些特殊处理。
我似乎无法在拦截器文档中找到描述如何执行此操作的任何内容。有没有人有任何想法?
谢谢!
答案 0 :(得分:8)
如果拦截器在链中运行得相当晚(如USER_LOGICAL 阶段),你应该能够做类似的事情:
Exchange exchange = msg.getExchange();
BindingOperationInfo bop = exchange.get(BindingOperationInfo.class);
MethodDispatcher md = (MethodDispatcher)
exchange.get(Service.class).get(MethodDispatcher.class.getName());
Method meth = md.getMethod(bop);
那应该给你绑定的方法,这样你就可以得到声明的 类或注释等......
答案 1 :(得分:4)
阿。我没有说明我使用的是CXF的JAX-RS部分;不确定这是否会影响Daniel Kulp的答案,但他的解决方案实际上并不适合我。我相信这是因为CXF在处理JAX-RS时会做出不同的事情。
我遇到了CXF [JAXRSInInterceptor][1]
的源代码,我在该代码中看到这个拦截器正在将方法信息放入Exchange
对象中,如下所示:
message.getExchange().put(OperationResourceInfo.class, ori);
...在UNMARSHAL
阶段,根据CXF interceptor docs发生在*_LOGICAL
阶段之前。因此,通过编写处理Interceptor
阶段的USER_LOGICAL
,我可以做到:
message.getExchange().get(OperationResourceInfo.class)
...要访问Method
Class<?>
来处理通话的Service
和{{1}}!
答案 2 :(得分:1)
自接受答案以来已经有一段时间了。但
中提供的支持抽象很少cxf-rt-core-2.7.3.jar
其中一个是org.apache.cxf.interceptor.security.AbstractAuthorizingInInterceptor
来自源代码的示例摘录可能是一个很好的参考。
protected Method getTargetMethod(Message m) {
BindingOperationInfo bop = m.getExchange().get(BindingOperationInfo.class);
if (bop != null) {
MethodDispatcher md = (MethodDispatcher)
m.getExchange().get(Service.class).get(MethodDispatcher.class.getName());
return md.getMethod(bop);
}
Method method = (Method)m.get("org.apache.cxf.resource.method");
if (method != null) {
return method;
}
throw new AccessDeniedException("Method is not available : Unauthorized");
}
答案 3 :(得分:0)
建立原始审讯者的回答,我想出了这个
public UserContextInterceptor() {
super(Phase.USER_LOGICAL);
}
@Override
public void handleMessage(Message message) {
if(StringUtils.isEmpty(getHeader("some-header-name", message))) {
final Method method = getTargetMethod(message);
if(isAnnotated(method.getDeclaringClass().getAnnotations()) || isAnnotated(method.getAnnotations())) {
final Fault fault = new Fault(new LoginException("Missing user id"));
fault.setStatusCode(HttpServletResponse.SC_UNAUTHORIZED);
throw fault;
}
}
}
private static Method getTargetMethod(Message message) {
final Exchange exchange = message.getExchange();
final OperationResourceInfo resource = exchange.get(OperationResourceInfo.class);
if(resource == null || resource.getMethodToInvoke() == null) {
throw new AccessDeniedException("Method is not available");
}
return resource.getMethodToInvoke();
}
private static boolean isAnnotated(Annotation[] annotations) {
for(Annotation annotation : annotations) {
if(UserRequired.class.equals(annotation.annotationType())) {
return true;
}
}
return false;
}