zoukankan      html  css  js  c++  java
  • CXF

    没想到要弄这么一个东西。

    起初只是想用interceptor记录一下webservice调用日志,后来却被要求在页面展示。

    展示容易,但只是展示webservice的地址无法让用户从中明白什么。

    那么我可以把url和具体说明作为一对键值,但是这对键值配置到哪里比较好?

    文件? db? 我不想每增加一个方法就到别的地方再配置一次键值,写到注解也许是个不错的方法。

    这就需要我在方法被调用后在获得对应的Method对象。

    当然,实现这个效果的方法有很多种,这里主要讲如何在CXF Interceptor中获取。

    顺便一提,我是在web应用里配置Spring+CXF,拦截器只是简单继承了JAXRSIn/OutInterceptor。

    比如,我有一个这样的方法:

    
    @GET
    @Path("/hello")
    @Consumes({"*/*"})
    public String Hello(){
    
      return "Hello Alvez!";
    
    }
    
    

    我需要在调用结束后记录这个方法的名字 ,但不能是"Hello",而是"哈罗"。

    那就定义一个注解并给方法加上:

    
    @Target({ElementType.METHOD})
    @Retention(RetentionPolicy.RUNTIME)
    public @interface Description {
      public String value(); 
    }
    
    
    
    @GET
    @Path("/hello")
    @Consumes({"*/*"})
    @Description("哈罗")
    public String Hello(){
      return "Hello Alvez!";
    }
    
    

    好了,接下来就是从拦截器获得调用信息了。

    InInterceptor还是OutInterceptor?

    无论是哪一个,当我们重写了handleMessage时就自然地想到从Message对象中获取。

    当然,如果你发现正在使用的方法参数列表中没有Message类型,也许你可以这样做。

    
    Message message =  JAXRSUtils.getCurrentMessage();
    
    

    因为这个例子中使用到的JAXIn/OutInterceptor继承的是AbstractPhaseInterceptor<Message>,我们就可以理所当然地得到message对象。

    
    public class JAXRSInInterceptor extends AbstractPhaseInterceptor {
          //..      
    }
    

    但一个Message里面却有不少内容,Exchange、Destination、Attachment、InterceptorChain,继续递归下去,如果不明白他们分别代表什么就无从找起。

    也许我想用一个org.apache.cxf.service.invoker.MethodDispatcher(2.6.x中是org.apache.cxf.frontend.MethodDispatcher )

    而理由仅仅是因为他有一个通过BindingOperationInfo对象获取java.lang.reflect.Method对象的方法:

    
    public class JAXRSInInterceptor extends AbstractPhaseInterceptor {
          //..      
    }
    
    

    这样我就可以在拦截器中这样使用:

    
    Exchange exchange = message.getExchange();
    BindingOperationInfo bindingOperationInfo = exchange.getBindingOperationInfo();
    
    SimpleMethodDispatcher methodDispatcher = new SimpleMethodDispatcher();
    Method method = methodDispatcher.getMethod(bindingOperationInfo);
    
    

    但很遗憾,exchange里哪来的bindingOperationInfo?

    那exchange里有什么? 既然他是Map的子类,我可以看看他的keyset,发现outInterceptor中的message.getExchange().keySet()如下:

    org.apache.cxf.rest.message
    org.apache.cxf.resource.operation.name
    org.apache.cxf.interceptor.LoggingMessage.ID
    org.apache.cxf.endpoint.ConduitSelector
    org.apache.cxf.jaxrs.model.OperationResourceInfo
    org.apache.cxf.service.object.last
    org.apache.cxf.endpoint.Endpoint
    org.apache.cxf.service.Service
    root.resource.class
    service.root.provider
    service.root.instance
    org.apache.cxf.Bus
    org.apache.cxf.binding.Binding
    Accept
    Content-Type

    看到可以获取OperationResourceInfo,Request/ResponseHandler接口的默认方法中也包括这个参数,只是这两个接口已经在新版本中不能用了。(http://cxf.apache.org/docs/30-migration-guide.html)

    但也提供了替代的方法(http://cxf.apache.org/docs/jax-rs.html)

    e.g.我们可以从message中获得一切想要的信息,比如被调用过的方法;

    
    OperationResourceInfo resourceInfo = (OperationResourceInfo) ex.get("org.apache.cxf.jaxrs.model.OperationResourceInfo");
    ClassResourceInfo classResourceInfo = resourceInfo.getClassResourceInfo();
    Path path = classResourceInfo.getPath();
    Class<?> resourceClass = classResourceInfo.getResourceClass();
    Method annotatedMethod = resourceInfo.getAnnotatedMethod();
    Annotation[] declaredAnnotations = annotatedMethod.getDeclaredAnnotations();
    Description annotation = annotatedMethod.getAnnotation(Description.class);
    
    

    上面的Description就是文章开始时定义的注解,这样小问题就解决了。

  • 相关阅读:
    java中不常见的keyword:strictfp,transient
    D3DXMatrixMultiply 函数
    expect
    char* 和char[]的差别
    下载安装tomcat6.0
    Eclipse或SVN—怎样在Eclipse中安装SVNclient插件
    sharepoint 訪问缩略图
    斜率优化专题1——bzoj 1597 [Usaco2008 Mar] 土地购买 题解
    phpmywind教程:关于日期函数调用整理
    linux服务之smtp
  • 原文地址:https://www.cnblogs.com/kavlez/p/4070012.html
Copyright © 2011-2022 走看看