之前想用spring的AOP给webservice添加切面的,但是使用around切面后,居然调用端得不到webservice的返回结果,而且报文的详细情况也不得而知,很是尴尬,所以偷了个懒。但是该做的还是要做,不要以后要求查看调用日志的时候,什么都拿不出,不是一个尴尬能搞定的。

  我使用的是基于cxf的webservice,所以添加调用日志的方法也是基于cxf的,其次是配合sping开发webservice。基本的webservice的实现,这里就不再说明。

 一、使用LoggingInInterceptor实现

  第一种方法,就是使用已经的实现的日志拦截,需要配置好log.properties。

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:jaxws="http://cxf.apache.org/jaxws"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd "> <jaxws:endpoint implementor="com.test.DepartServiceImpl" address="/departService">
<jaxws:inInterceptors>
<bean class="org.apache.cxf.interceptor.LoggingInInterceptor" />
</jaxws:inInterceptors>
<jaxws:outInterceptors>
<bean class="org.apache.cxf.interceptor.LoggingOutInterceptor" />
</jaxws:outInterceptors>
</jaxws:endpoint> </beans>
  <jaxws:inInterceptors>是输入拦截器,在接口被调用的时候会被拦截。下面是接口被调用后的日志输出。
----------------------------
ID: 1
Address: http://localhost:8080/test/ws/departService?wsdl
Encoding: UTF-8
Http-Method: POST
Content-Type: text/xml; charset=UTF-8
Headers: {Accept=[*/*], cache-control=[no-cache], connection=[keep-alive], Content-Length=[221], content-type=[text/xml; charset=UTF-8], host=[localhost:18080], pragma=[no-cache], SOAPAction=[""], user-agent=[Apache CXF 2.7.7]}
Payload: <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:Body><ns2:findEmployees xmlns:ns2="http://cxf.test.com/"><arg0>张三</arg0><arg1></arg1></ns2:findEmployees></soap:Body></soap:Envelope>
--------------------------------------
  <jaxws:outInterceptors>是输出拦截器,在接口调用完毕的时候被拦截。下面是接口调用完成后的日志输出。
---------------------------
ID: 1
Encoding: UTF-8
Content-Type: text/xml
Headers: {}
Payload: <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:Body><ns2:findEmployeesResponse xmlns:ns2="http://cxf.test.com/"><return><user_depart>IT</user_depart><user_name>张三</user_name><user_state>在职</user_state><user_tele></user_tele><user_type>普通员工</user_type></return></ns2:findEmployeesResponse></soap:Body></soap:Envelope>
--------------------------------------

  我们可以看到基本的实现已经非常详细,甚至能看到一些重要基本的信息。如果这个方法还不能满足你的需求,那么请看后面。

 二、实现AbstractPhaseInterceptor

import org.apache.cxf.interceptor.Fault;
import org.apache.cxf.message.Message;
import org.apache.cxf.phase.AbstractPhaseInterceptor;
import org.apache.cxf.phase.Phase; import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException; public class WebserviceLogInterceptor extends AbstractPhaseInterceptor<Message> { public WebserviceLogInterceptor(){
super(Phase.RECEIVE);
} @Override
public void handleMessage(Message message) throws Fault {
StringBuffer sb = new StringBuffer();
//这里可以对流做处理,从流中读取数据,然后修改为自己想要的数据
InputStream is = message.getContent(InputStream.class);
String encoding = (String)message.get(Message.ENCODING);
int len = 0;
byte[] bytes = new byte[1024 * 4];
try {
while((len = is.read(bytes))!=-1){
sb.append(new String(bytes, 0, len, encoding));
}
} catch (IOException e) {
e.printStackTrace();
}
System.out.println(sb.toString());
      //在这里需要注意一点的是,如果修改后的soap消息格式不符合webservice框架格式,比如:框架封装后的格式为
//<soap:Envelope xmlns:soap="http://www.w3.org/2001/12/soap-envelope" <soap:Body>
//<这里是调用服务端方法的命名空间><这是参数名称>
//这里才是真正的消息
//</这里是调用服务端方法的命名空间></这是参数名称>
//</soap:Body>
//</soap:Envelope>
try {
message.setContent(InputStream.class, new ByteArrayInputStream(sb.toString().getBytes(encoding)));
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
}

  配置文件添加对应的拦截器。

<jaxws:endpoint implementor="com.test.cxf.impl.DepartServiceImpl" address="/departService">
<jaxws:inInterceptors>
<bean class="org.apache.cxf.interceptor.LoggingInInterceptor" />
<bean class="com.test.interceptor.WebserviceLogInterceptor" />
</jaxws:inInterceptors>
</jaxws:endpoint>

  需要注意的是,在处理完数据后,需要在写回到流中,不然接口无法的到参数。

import org.apache.cxf.helpers.IOUtils;
import org.apache.cxf.interceptor.Fault;
import org.apache.cxf.io.CachedOutputStream;
import org.apache.cxf.message.Message;
import org.apache.cxf.phase.AbstractPhaseInterceptor;
import org.apache.cxf.phase.Phase; import java.io.*; public class WebserviceLogInterceptor1 extends AbstractPhaseInterceptor<Message> { public WebserviceLogInterceptor1(){
super(Phase.PRE_STREAM);
} @Override
public void handleMessage(Message message) throws Fault {
StringBuffer sb = new StringBuffer();
OutputStream os = message.getContent(OutputStream.class); message.setContent(OutputStream.class, new CachedOutputStream()); message.getInterceptorChain().doIntercept(message); CachedOutputStream csnew = (CachedOutputStream) message.getContent(OutputStream.class);
try {
String encoding = (String)message.get(Message.ENCODING);
InputStream in = csnew.getInputStream(); int len = 0;
byte[] bytes = new byte[1024 * 4];
while((len = in.read(bytes))!=-1) {
sb.append(new String(bytes, 0, len, encoding));
}
System.out.println(sb.toString());
//这里对xml做处理,处理完后同理,写回流中
IOUtils.copy(new ByteArrayInputStream(sb.toString().getBytes(encoding)), os); os.flush(); } catch (IOException e) {
e.printStackTrace();
} message.setContent(OutputStream.class, os);
}
}

  同样的,在读取完数据后,仍需要写回到流中,不然调用端得不到结果。

添加webservice调用日志的更多相关文章

  1. 如何添加WebService调用时的用户认证

    场景: 当把发布好的WebService地址或WSDL提供给调用方时,需要对方先进行身份的认证通过后才允许接口的进步访问.而不是公开的谁都可以调用. 解决: 1.在IIS中设置对应网站的目录访问权限. ...

  2. C#动态webservice调用接口 (JAVA,C#)

    C#动态webservice调用接口 using System; using System.Collections; using System.IO; using System.Net; using ...

  3. 使用自定义签名的https的ssl安全问题解决和metro的webservice调用

    最近一直在忙新的项目,每天加班到8点多,都没来写博客了.新的项目遇到了很多问题,现在趁着突然停电来记录下调用https的问题吧. 我们服务主要是,我们调用数据源数据,并且再提供接口供外部数据调用. 我 ...

  4. WebService 调用

    一.WebService调用 1.webservice支持四种调用方式:SOAP 1.1,SOAP 1.2,GET,POST.           2.如果要webservice支持GET,POST调 ...

  5. WebService调用1(.Net)

    1.创建一个最简单的Web Service (1)  新建-项目-ASP.NET空WEB应用程序 (2)添加新项-WEB服务 默认会添加一个HelloWorld方法: using System; us ...

  6. WebService 调用三种方法

    //来源:http://www.cnblogs.com/eagle1986/archive/2012/09/03/2669699.html 最近做一个项目,由于是在别人框架里开发app,导致了很多限制 ...

  7. webservice调用和生成

    webservice简介: Web Service技术, 能使得运行在不同机器上的不同应用无须借助附加的.专门的第三方软件或硬件, 就可相互交换数据或集成.依据Web Service规范实施的应用之间 ...

  8. WebService调用SSAS教程

    WebService调用SSAS教程 一.创建SSAS项目 使用SQL Server Business Intelligence Development Studio新建Analysis Servic ...

  9. 客户端设置WebService调用超时时间

    刚接触WebService,对如何在客户端设置WebService调用超时时间查阅了一些资料,现总结如下: ============================================== ...

随机推荐

  1. 为什么applicationContext.xml和spring-servlet.xml中都有注解过滤<context:component-scan base-package="myproject"> 和<context:component-scan base-package="myproject.controller" />

    在刚学习SpringMVC框架整合时,你也许会产生疑问为什么Spring.xml和SpringMVC.xml中都有注解过滤. <context:component-scan base-packa ...

  2. Mac 热键大全

    屏幕捕捉快捷键动作............................保存到............-快捷键 全屏捕捉........................桌面(.PDF文件)..... ...

  3. css3+jquery制作3d旋转相册

    首先来看一下今天的炫酷效果: 首先分析一下这张图片: 1.每张图片都有倒影 2.这11张图片呈圆形均匀排列 3.可旋转,上下移动(当然这是效果做出来以后,图片是分析不出来的) 那下面就开始吧. 一.准 ...

  4. 非域客户端的office使用RMS加密服务出现‘介绍“信息权限管理服务”’服务的提示

    环境:office2007,需要使用windows RMS服务,客户机处于工作组模式,如图: 出现这个说明客户机没有发现RMS服务,可以通过导入注册表解决,如下: Windows Registry E ...

  5. SharePoint 2013 入门教程

    以下文章是自己在学习SharePoint的过程中,不断积累和总结的博文,现在总结一个目录,分享给大家.这个博客也是自己从SharePoint入门,到一个SharePoint开发的成长记录,里面记录的都 ...

  6. Android 5.X新特性之为RecyclerView添加下拉刷新和上拉加载及SwipeRefreshLayout实现原理

    RecyclerView已经写过两篇文章了,分别是Android 5.X新特性之RecyclerView基本解析及无限复用 和 Android 5.X新特性之为RecyclerView添加Header ...

  7. UICollectionViewCell--查找cell上的按钮点击后,对应的是哪个cell

    实际写项目会碰到各种各样的问题,废话不多说 按钮添加到cell时,根据是直接添加到self还是self.contentView上,在点击方法里找到btn的父视图 我是直接添加到self上,所以只有一层 ...

  8. css属性兼容主流浏览器

    目前,对于网页中一些浏览器兼容性问题,可以使用css hack(css 招数)和浏览器Bug修复的方式解决. 名词解释: css Hack:针对特定浏览器编写冗余代码,这是一种欺骗浏览器的行为,预示着 ...

  9. 搭建高可用的rabbitmq集群 + Mirror Queue + 使用C#驱动连接

    我们知道rabbitmq是一个专业的MQ产品,而且它也是一个严格遵守AMQP协议的玩意,但是要想骚,一定需要拿出高可用的东西出来,这不本篇就跟大家说 一下cluster的概念,rabbitmq是erl ...

  10. VS2015安装之后加装SQL SERVER2014的步骤

    网上一直说的是先安装SQL Server 2014,再安装VS2015,软件就不会出现问题.我这次在什么都没准备的情况下安装了VS2015,安装之后发觉VS2015自带的SQL2014只有连接服务器和 ...