2010-11-18 6 views
5

Je voudrais écrire un intercepteur pour l'implémentation Apache CXF JAX-RS qui inspecte le service/la méthode cible pour une annotation particulière et effectue un traitement spécial pour cette annotation.Détermination du service/méthode cible à partir de CXF Interceptor

Je n'arrive pas à trouver quoi que ce soit dans la documentation de l'intercepteur qui explique comment procéder. Quelqu'un a-t-il une idée?

Merci!

Répondre

4

Ah. Je n'ai pas précisé que j'utilisais la partie JAX-RS de CXF; Je ne sais pas si cela a une incidence sur la réponse de Daniel Kulp, mais sa solution n'a pas vraiment fonctionné pour moi. Je crois que c'est parce que CXF fait les choses différemment en manipulant JAX-RS.

je suis tombé sur la source pour [JAXRSInInterceptor][1] de CXF et j'ai vu dans ce code que intercepteur met l'information de méthode dans l'objet Exchange comme ceci:

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

... pendant la phase UNMARSHAL, qui selon le CXF interceptor docs se produit avant la phase *_LOGICAL. En écrivant un Interceptor qui gère la phase USER_LOGICAL je peux faire:

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

... pour avoir accès là-bas pour la Method et Class<?> du Service traitement de l'appel!

+0

Cela retournera de mauvais résultats si vous utilisez des sous-ressources! L'ORI retourné sera celui utilisé pour sélectionner la méthode du localisateur de sous-ressource, mais pas la méthode du gestionnaire acutal –

+1

Fonctionne parfaitement, si vous avez besoin du nom de la méthode, utilisez 'operationResInfo.getMethodToInvoke(). GetName();' –

+0

Et si vous avez besoin de la classe use 'operationResInfo.getMethodToInvoke(). getDeclaringClass()' – fafl

8

Si l'intercepteur fonctionne assez tard dans la chaîne (comme la phase USER_LOGICAL ), vous devriez être en mesure de faire quelque chose comme:


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

Cela devrait vous donner la méthode qui a été lié en sorte que vous pouvez obtenir la classe déclarée ou les annotations, etc ...

+0

Aha, c'est le genre de chose que je cherchais, mais je suppose que je ne connaissais pas la terminologie CXF à parcourir les classes. :) Je vais donner un coup de feu, merci! –

+1

MethodDispatched est obsolète. Pouvez-vous s'il vous plaît suggérer une autre alternative? J'utilise les phases PRE_STREAM & RECEIVE – Harish

1

C'est assez depuis la réponse acceptée. Mais il y a quelques abstractions de soutien fournies dans le

cxf-rt-core-2.7.3.jar 

Un dans qui est org.apache.cxf.interceptor.security.AbstractAuthorizingInInterceptor

extrait de l'échantillon de la source pourrait être une bonne référence.

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

bâtiment au large de la réponse de l'interrogateur d'origine, je suis venu avec cette

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; 
} 
Questions connexes