2010-11-18 81 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; 
}