我想为Apache CXF JAX-RS实现编写拦截器,该拦截器检查特定注释的目标服务/方法并对该注释执行一些特殊处理。确定来自CXF拦截器的目标服务/方法
我似乎无法在拦截器文档中找到描述如何执行此操作的任何内容。有没有人有任何想法?
谢谢!
我想为Apache CXF JAX-RS实现编写拦截器,该拦截器检查特定注释的目标服务/方法并对该注释执行一些特殊处理。确定来自CXF拦截器的目标服务/方法
我似乎无法在拦截器文档中找到描述如何执行此操作的任何内容。有没有人有任何想法?
谢谢!
啊。我没有指定我使用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)
...在那里得到的Method
和Service
的Class<?>
处理呼叫的访问!
如果拦截还算运行尾盘链(如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);
这应该给你,在这样你就可以绑定的方法得到宣布的 类或注释等...
啊哈,这是那种我一直在寻找的东西,但我想我不知道在CXF的术语来遍历类。 :)我会给那一枪,谢谢! – 2010-11-20 12:02:40
MethodDispatched已弃用。你能否提出其他建议?我正在使用PRE_STREAM&RECEIVE阶段 – Harish 2013-06-07 08:10:16
自从被接受的答案以来,它已经有一段时间了。但也有在
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");
}
建设掉原来询问的回答,我想出了这个
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;
}
如果您使用子资源,这将返回错误的结果!返回的ORI将是用于选择子资源定位器方法的一个,但不是实际的处理器方法 – 2013-08-28 15:18:35
如果您需要方法名称,只需使用'operationResInfo.getMethodToInvoke()。getName();' – 2016-06-24 09:01:45
你需要类使用'operationResInfo.getMethodToInvoke()。getDeclaringClass()' – fafl 2016-11-14 09:48:44