2010-11-18 50 views
5

我想为Apache CXF JAX-RS实现编写拦截器,该拦截器检查特定注释的目标服务/方法并对该注释执行一些特殊处理。确定来自CXF拦截器的目标服务/方法

我似乎无法在拦截器文档中找到描述如何执行此操作的任何内容。有没有人有任何想法?

谢谢!

回答

4

啊。我没有指定我使用CXF的JAX-RS部分;不知道这是否会影响Daniel Kulp的回答,但他的解决方案对我来说并不适用。我相信这是因为CXF在处理JAX-RS时做了不同的事情。

我在源来抓CXF的[JAXRSInInterceptor][1]和我的代码看到此拦截器把方法信息到Exchange对象,像这样:在UNMARSHAL阶段

message.getExchange().put(OperationResourceInfo.class, ori);

...其中根据CXF interceptor docs发生在*_LOGICAL阶段之前。因此,通过编写Interceptor处理该USER_LOGICAL阶段我可以这样做:

message.getExchange().get(OperationResourceInfo.class)

...在那里得到的MethodServiceClass<?>处理呼叫的访问!

+0

如果您使用子资源,这将返回错误的结果!返回的ORI将是用于选择子资源定位器方法的一个,但不是实际的处理器方法 – 2013-08-28 15:18:35

+1

如果您需要方法名称,只需使用'operationResInfo.getMethodToInvoke()。getName();' – 2016-06-24 09:01:45

+0

你需要类使用'operationResInfo.getMethodToInvoke()。getDeclaringClass()' – fafl 2016-11-14 09:48:44

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); 

这应该给你,在这样你就可以绑定的方法得到宣布的 类或注释等...

+0

啊哈,这是那种我一直在寻找的东西,但我想我不知道在CXF的术语来遍历类。 :)我会给那一枪,谢谢! – 2010-11-20 12:02:40

+1

MethodDispatched已弃用。你能否提出其他建议?我正在使用PRE_STREAM&RECEIVE阶段 – Harish 2013-06-07 08:10:16

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"); 
} 
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; 
}