记一次Spring AOP拦截处理CXF WebService的失败经历

11 篇文章 0 订阅
3 篇文章 0 订阅

需要实现一个功能,即记录每次webservice服务调用的一些参数,比如调用时间,执行时间等。原来的产品是使用axis开发的,接到这个功能的时候便想着采用Spring AOP结合CXF的方式来实现,于是开始准备一个Demo。

@WebService
@SOAPBinding(style = Style.DOCUMENT)
public interface HelloWorld {
    public String sayHello(@WebParam(name = "name") String name);
}

public class HelloWorldImpl implements HelloWorld {
    @Override
    public String sayHello(String name) {
        return name + " Say:hello world~!!!!!!!!!!!!!";
    }

}

定义接口,定义实现类,然后配置Spring容器

<bean id="helloWorldImpl"
        class="com.smart.service.testcxf.HelloWorldImpl" />

    <jaxws:endpoint id="helloWorldService"
        implementor="#helloWorldImpl" address="/helloWorld">
        <jaxws:properties>
            <entry key="mtom-enabled" value="true" />
        </jaxws:properties>
    </jaxws:endpoint>

启动服务,客户端采用C#,根据WSDL生成对应的服务代理类,调用服务,直接报错,application/xop+xml等等。
这里写图片描述
好吧,辛辛苦苦查资料,终于解决,消息编码问题,只需修改配置的编码方式为“Mtom”就能解决问题。
<configuration>
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding messageEncoding="Mtom">
</binding>
</basicHttpBinding>
</bindings>
</system.serviceModel>
</configuration>

百度资料之后,貌似客户端是.NET的就会有这个问题,JAVA的不存在这个问题。
解决之后满心欢喜,基于@AspectJ定义切面,增强类型为环绕增强,代码准备完毕之后,满心欢喜,先利用Junit测试一下,结果如下
这里写图片描述
哈哈,没问题,那就直接跑服务来测试,服务端日志打印也是正常的,但是客户端就很尴尬了
这里写图片描述
没有数据返回!!!想想可能的原因是服务类被代理了,新生成的代理类没有@WebService的注解,所以导致服务数据返回失败。
最终百度了下,说重写AbstractJaxWsServiceExporter和SimpleHttpServerJaxWsServiceExporter这两个类,在加载的时候自己处理获取原型类和对象,该层的切面交给Authenticator处理。这样能实现功能。
但是本人能力有限,折腾了一阵还是没能成功,希望哪位大佬给予指点,助小弟实现该功能,感激不尽噢。
没办法,最终转而使用CXF拦截器

  <!-- 单个拦截器 -->
    <bean id="inMessageInterceptor" class="org.apache.cxf.interceptor.LoggingInInterceptor" />
    <bean id="outMessageInterceptor" class="org.apache.cxf.interceptor.LoggingOutInterceptor"/>
    <bean id="myInInterceptor" class="com.smart.interceptor.MyInInterceptor"/>
  <!-- 输入日志拦截器 -->  
       <jaxws:inInterceptors>  
          <ref bean="inMessageInterceptor"/>  
          <ref bean="myInInterceptor"/>  
       </jaxws:inInterceptors>  
       <!-- 输出日志拦截器 -->  
       <jaxws:outInterceptors>  
          <ref bean="outMessageInterceptor"/>  
       </jaxws:outInterceptors>

此处myInInterceptor为自定义的In拦截器,
这里写图片描述
其中Phase.PRE_INVOKE在构造函数中声明,表示拦截器在哪个阶段起作用。重写handleMessage方法,这里做我们需要做的处理。
另外,因为调取webservice服务是异步的,所以实际拦截过程中,我们并不知道哪次OUT拦截对应IN拦截,这里我们需要做点处理。
在服务端IN拦截器中,添加如下代码

message.getExchange().put("CXF", "test");

在服务端OUT拦截器中,添加如下代码:

message.getExchange().get("CXF");

这里“CXF”作为key值,“test”作为value值,经过测试,同一次服务的IN message.getExchange()与OUT message.getExchange()相同的key得到的value值相同。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值