我想爲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