基于CXF的webservice拦截器

最近项目需要与外部项目进行数据交换,需要开发webservice接口,项目的webservice基于CXF开发的,返回报文格式不符合接口调用方的规范:

例如:

CXF自动返回的报文格式如下:

<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
    <soap:Body>
        <ns2:doRequestResponse xmlns:ns2="http://aaa.bbb.ccc.ddd/">
            <return>返回的数据。。。。</return>
        </ns2:doRequestResponse >
    </soap:Body>
</soap:Envelope>

然而,接口调用方要求格式如下:

<?xml version="1.0" ?>
<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
    <S:Body>
        <ns2:doRequestResponse xmlns:ns2="http://aaa.bbb.ccc.ddd/">
            <return>返回的数据。。。。</return>
        </ns2:doRequestResponse>
    </S:Body>
</S:Envelope>

怎么办?开发一个基于CXF的拦截器,数据返回前进行拦截,改写报文,再返回。

具体步骤如下:

1. 准备好CXF的有关的jar包,可以到官网下载。

 

2. 新建java工程,构建路径中引入上面的jar包。

 

3. 新建一个类MyInterceptor,继承AbstractPhaseInterceptor<SoapMessage>

public class MyInterceptor extends AbstractPhaseInterceptor<SoapMessage> {
	
	public MyInterceptor () {
		super(Phase.PRE_STREAM);
		// TODO Auto-generated constructor stub
	}

	@Override
	public void handleMessage(SoapMessage message) throws Fault {
		// TODO Auto-generated method stub
				
			String ms = "";
			try {
	            // 从输出流中获取内容
	            OutputStream os = (OutputStream)message.getContent(OutputStream.class);
	            CachedOutputStream cs = new CachedOutputStream();
	            message.setContent(OutputStream.class, cs);
	            message.getInterceptorChain().doIntercept(message);
	
	            CachedOutputStream csnew = (CachedOutputStream)message.getContent(OutputStream.class);
	            InputStream in = csnew.getInputStream();
	            // 将流转换为字符串
	            ms = IOUtils.toString(in, "UTF-8");
	            ms = ms.replace("soap:", "S:");
	            ms = ms.replace(":soap", ":S");
	            ms = "<?xml version=\"1.0\" ?>" + ms;
	            IOUtils.copy(new ByteArrayInputStream(ms.getBytes("UTF-8")), os);
	            cs.close();
	            os.flush();
	            message.setContent(OutputStream.class, os);
	        } catch (IOException var7) {
	            System.out.println(var7.getMessage() + var7);
	        }
	}

}

4. 在CXF的的配置文件cxf-servlet.xml中配置:

<cxf:bus>
        <cxf:outInterceptors>
            <bean class="你的包名.MyZInterceptor"></bean>
        </cxf:outInterceptors>
    </cxf:bus>

5. 重启CXF服务,大功告成:

6. 如果要对指定的服务做拦截,其它服务不拦截,加入下列代码:

boolean isMyService = false;
		Exchange ec = message.getExchange();
		if (ec != null)
			for (String key : ec.keySet()) {
//				System.out.println(key + ":" + ec.get(key));
				if ("javax.xml.ws.wsdl.description".equals(key)) {
					Object o = ec.get(key);
					if (o != null && "/你的service的完整路径?wsdl".equals(o.toString())) {
						isGonganService = true;
						break;
					}
				}
			}

 在第三步的拦截代码上加判断:

if (MyService) {
    //是我的服务,进行拦截

}

原创不易,转载请注明出处。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值