代码之家  ›  专栏  ›  技术社区  ›  Nick Spacek

从cxf拦截器确定目标服务/方法

  •  5
  • Nick Spacek  · 技术社区  · 14 年前

    我想为ApacheCxfJAX-RS实现编写一个拦截器,它检查特定注释的目标服务/方法,并为该注释做一些特殊的处理。

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

    谢谢!

    4 回复  |  直到 10 年前
        1
  •  8
  •   Daniel Kulp    14 年前

    如果拦截器在链中运行得相当晚(如用户逻辑 阶段),您应该能够执行以下操作:

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

    它应该为您提供绑定的方法,这样您就可以 类或注释等…

        2
  •  4
  •   Nick Spacek    14 年前

    啊。我没有具体说明我使用的是cxf的jax-rs部分;不确定这是否会影响DanielKulp的答案,但他的解决方案实际上对我不起作用。我认为这是因为cxf在处理JAX-R时做的事情不同。

    我找到了CXF的来源 [JAXRSInInterceptor][1] 我在代码中看到这个拦截器将方法信息放入 Exchange 像这样的对象:

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

    ……期间 UNMARSHAL 相位,根据 CXF interceptor docs 发生在 *_LOGICAL 相位。所以通过写一个 Interceptor 处理 USER_LOGICAL 第一阶段可以做到:

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

    …进入那里 Method Class<?> Service 处理电话!

        3
  •  1
  •   raksja    11 年前

    这是公认的答案之后相当长的一段时间。但是,在

    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");
    }
    
        4
  •  0
  •   Kirby    10 年前

    根据最初审问者的回答,我想出了这个

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