php 打印soap日志,CXF打印SOAP报文,记录WebService日志

CXF是Apache发布的一个用于快速构建Services的框架,用于构建WebService客户端及服务端。

使用cxf构建的java程序,在java层面看到的是很多层的java类对象,但是在实际的接口调用和数据传输过程中则使用的soap报文(网络传输过程中不可能真的把java对象传过去)。

第一种方法使用cxf自带拦截器直接在控制台打印输入输出报文,适合使用main()方法测试时使用。

第二种方法自己实现拦截器进行报文输出,报文可用日志工具进行存储,或者写入数据库,适合web项目使用。

第一种方法代码如下:

package com.action;

import org.apache.cxf.endpoint.Client;

import org.apache.cxf.frontend.ClientProxy;

import org.apache.cxf.transport.http.HTTPConduit;

import org.apache.cxf.transports.http.configuration.HTTPClientPolicy;

public class CoreAction {

public static void test(BaseDto b, QueryDto b1) {

// 设置URL

String url = "http://localhost:8080/core/services/query";

// 实例化service

QueryPolicy service = CxfUtil.getService(QueryPolicy.class, url);

// 超时

Client proxy = ClientProxy.getClient(service);

HTTPConduit conduit = (HTTPConduit) proxy.getConduit();

HTTPClientPolicy policy = new HTTPClientPolicy();

policy.setConnectionTimeout(6000); // 6000毫秒

policy.setReceiveTimeout(6000); // 6000毫秒

conduit.setClient(policy);

// 调用

response response = service.query(b, b1);

}

public static void main(String[] args) {

BaseDto b = new BaseDto();

QueryDto b1 = new QueryDto();

test(b, b1);

}

}

两行拦截器代码:

package com.util;

import java.util.HashMap;

import java.util.Map;

import org.apache.cxf.interceptor.LoggingInInterceptor;

import org.apache.cxf.interceptor.LoggingOutInterceptor;

import org.apache.cxf.jaxws.JaxWsProxyFactoryBean;

public class CxfUtil {

private static MapserviceMap = new HashMap();

public static T getService(Class extends T> type, String serviceUrl) {

Object client = serviceMap.get(serviceUrl);

if (client == null) {

synchronized (serviceMap) {

JaxWsProxyFactoryBean factory = new JaxWsProxyFactoryBean();

factory.setServiceClass(type);

factory.setAddress(serviceUrl);

// 输入报文拦截器

factory.getInInterceptors().add(new LoggingInInterceptor());

// 输出报文拦截器

factory.getOutInterceptors().add(new LoggingOutInterceptor());

client = factory.create();

serviceMap.put(serviceUrl, client);

}

}

if (client == null) {

throw new IllegalArgumentException(String.format("The url:%s is not a service url", serviceUrl));

}

if (!type.isAssignableFrom(client.getClass())) {

throw new IllegalArgumentException(String.format("The service's type should be %s", client.getClass()));

}

return (T) client;

}

}

第二种方法代码如下:

1.实现输入报文拦截器InInterceptor

package com.util;

import java.io.IOException;

import java.io.InputStream;

import org.apache.cxf.helpers.IOUtils;

import org.apache.cxf.interceptor.Fault;

import org.apache.cxf.interceptor.LoggingMessage;

import org.apache.cxf.io.CachedOutputStream;

import org.apache.cxf.message.Message;

import org.apache.cxf.phase.AbstractPhaseInterceptor;

import org.apache.cxf.phase.Phase;

public class InInterceptor extends AbstractPhaseInterceptor{

private int limit = 102400;

public int getLimit() {

return limit;

}

public void setLimit(int limit) {

this.limit = limit;

}

public InInterceptor() {

// 拦截器在调用方法之前拦截SOAP消息

super(Phase.RECEIVE);

}

public void handleMessage(Message message) throws Fault {

logging(message);

}

private void logging(Message message) throws Fault {

if (message.containsKey(LoggingMessage.ID_KEY)) {

return;

}

String id = (String) message.getExchange().get(LoggingMessage.ID_KEY);

if (id == null) {

id = LoggingMessage.nextId();

message.getExchange().put(LoggingMessage.ID_KEY, id);

}

message.put(LoggingMessage.ID_KEY, id);

LoggingMessage buffer = new LoggingMessage("Inbound Message\n----------------------------", id);

String encoding = (String) message.get(Message.ENCODING);

if (encoding != null) {

buffer.getEncoding().append(encoding);

}

String ct = (String) message.get("Content-Type");

if (ct != null) {

buffer.getContentType().append(ct);

}

Object headers = message.get(Message.PROTOCOL_HEADERS);

if (headers != null) {

buffer.getHeader().append(headers);

}

String uri = (String) message.get(Message.REQUEST_URI);

if (uri != null) {

buffer.getAddress().append(uri);

}

InputStream is = (InputStream) message.getContent(InputStream.class);

if (is != null) {

CachedOutputStream bos = new CachedOutputStream();

try {

IOUtils.copy(is, bos);

bos.flush();

is.close();

message.setContent(InputStream.class, bos.getInputStream());

if (bos.getTempFile() != null) {

buffer.getMessage().append("\nMessage (saved to tmp file):\n");

buffer.getMessage().append("Filename: " + bos.getTempFile().getAbsolutePath() + "\n");

}

if (bos.size() > this.limit) {

buffer.getMessage().append("(message truncated to " + this.limit + " bytes)\n");

}

bos.writeCacheTo(buffer.getPayload(), this.limit);

bos.close();

} catch (IOException e) {

throw new Fault(e);

}

}

// 打印日志,保存日志保存这里就可以,可写库或log4j记录日志

System.out.println(buffer.toString());

}

// 出现错误输出错误信息和栈信息

public void handleFault(Message message) {

Exception exeption = message.getContent(Exception.class);

System.out.println(exeption.getMessage());

}

}

2.实现输出报文拦截器OutInterceptor

package com.util;

import java.io.OutputStream;

import org.apache.cxf.interceptor.Fault;

import org.apache.cxf.interceptor.LoggingMessage;

import org.apache.cxf.io.CacheAndWriteOutputStream;

import org.apache.cxf.io.CachedOutputStream;

import org.apache.cxf.io.CachedOutputStreamCallback;

import org.apache.cxf.message.Message;

import org.apache.cxf.phase.AbstractPhaseInterceptor;

import org.apache.cxf.phase.Phase;

public class OutInterceptor extends AbstractPhaseInterceptor{

private int limit = 102400;

public int getLimit() {

return limit;

}

public void setLimit(int limit) {

this.limit = limit;

}

public OutInterceptor() {

// 拦截器在调用方法之前拦截SOAP消息

super(Phase.PRE_STREAM);

}

public void handleMessage(Message message) throws Fault {

OutputStream os = (OutputStream) message.getContent(OutputStream.class);

if (os == null) {

return;

}

CacheAndWriteOutputStream newOut = new CacheAndWriteOutputStream(os);

message.setContent(OutputStream.class, newOut);

newOut.registerCallback(new LoggingCallback(message, os));

}

// 出现错误输出错误信息和栈信息

public void handleFault(Message message) {

Exception exeption = message.getContent(Exception.class);

System.out.println(exeption.getMessage());

}

class LoggingCallback implements CachedOutputStreamCallback {

private final Message message;

private final OutputStream origStream;

public LoggingCallback(Message msg, OutputStream os) {

this.message = msg;

this.origStream = os;

}

public void onFlush(CachedOutputStream cos) {

}

public void onClose(CachedOutputStream cos) {

String id = (String) this.message.getExchange().get(LoggingMessage.ID_KEY);

if (id == null) {

id = LoggingMessage.nextId();

this.message.getExchange().put(LoggingMessage.ID_KEY, id);

}

LoggingMessage buffer = new LoggingMessage("Outbound Message\n---------------------------", id);

String encoding = (String) this.message.get(Message.ENCODING);

if (encoding != null) {

buffer.getEncoding().append(encoding);

}

String address = (String) this.message.get(Message.ENDPOINT_ADDRESS);

if (address != null) {

buffer.getAddress().append(address);

}

String ct = (String) this.message.get("Content-Type");

if (ct != null) {

buffer.getContentType().append(ct);

}

Object headers = this.message.get(Message.PROTOCOL_HEADERS);

if (headers != null) {

buffer.getHeader().append(headers);

}

if (cos.getTempFile() == null) {

if (cos.size() > OutInterceptor.this.limit)

buffer.getMessage().append("(message truncated to " + OutInterceptor.this.limit + " bytes)\n");

} else {

buffer.getMessage().append("Outbound Message (saved to tmp file):\n");

buffer.getMessage().append("Filename: " + cos.getTempFile().getAbsolutePath() + "\n");

if (cos.size() > OutInterceptor.this.limit)

buffer.getMessage().append("(message truncated to " + OutInterceptor.this.limit + " bytes)\n");

}

try {

cos.writeCacheTo(buffer.getPayload(), OutInterceptor.this.limit);

} catch (Exception ex) {

}

// 打印日志,保存日志保存这里就可以,可写库或log4j记录日志

System.out.println(buffer.toString());

try {

cos.lockOutputStream();

cos.resetOut(null, false);

} catch (Exception ex) {

}

this.message.setContent(OutputStream.class, this.origStream);

}

}

}

3.在Spring配置文件中引用拦截器

报文输出结果:

信息: Outbound Message

---------------------------

ID: 1

Address: http://192.168.6.166:8080/SP/queryIndex

Encoding: UTF-8

Content-Type: text/xml

Headers: {SOAPAction=[""], Accept=[*/*]}

Payload: CompService123456123123123

--------------------------------------

信息: Inbound Message

----------------------------

ID: 1

Encoding: UTF-8

Content-Type: text/xml; charset=UTF-8

Headers: {content-type=[text/xml; charset=UTF-8], Date=[Tue, 14 Nov 2017 01:58:36 GMT], transfer-encoding=[chunked], X-Powered-By=[Servlet/2.5 JSP/2.1]}

Payload: 23Index

--------------------------------------

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值