用MTOM在WCF和CXF之间传数据

[size=x-large]用MTOM在WCF和CXF之间传数据[/size]

MTOM是一种机制,用来以原始字节形式传输包含SOAP消息的较大二进制附件,从而使所传输的消息较小。

如果不用MTOM我们也可以通过WebService传递二进制的文件, 我们先来看看不用MTOM的时候是什么样子的。

[b]服务端[/b]是一个简单的WebService方法, 接受一个byte数组,计算其中的字符数并返回。

@WebService
public interface CounterService {
int count(byte[] data);
}


@Service
@WebService(endpointInterface = "com.cccis.ws.CounterService")
public class CounterServiceImpl implements CounterService {

@Override
public int count(byte[] data) {
try {
String text = GZipUtils.decompressText(data, "utf-8");
return text.length();
} catch (IOException e) {
e.printStackTrace();
return -1;
}
}
}


<bean id="countServiceImpl" class="com.cccis.ws.CounterServiceImpl" />

<jaxws:endpoint
id="countService"
implementor="#countServiceImpl"
serviceName="countService"
address="/countService" />


[b]客户端[/b]是一个简单的WCF的客户端,读取一个文件把字节传递给count方法

try
{
var service = new ServiceReference1.CounterServiceClient();
var text = File.ReadAllText("c:\\words");

var memoryStream = new MemoryStream();
var gzipStream = new GZipStream(memoryStream, CompressionMode.Compress);
var rawData = Encoding.UTF8.GetBytes(text);
gzipStream.Write(rawData, 0 , rawData.Length);
gzipStream.Close();
var len = service.count(memoryStream.ToArray());
Console.WriteLine("lenght = {0}", len);

}
catch (Exception e)
{
Console.WriteLine(e.Message);
Console.WriteLine(e.StackTrace);
}
Console.Read();
}


app.config配置如下:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="countServiceSoapBinding" />
</basicHttpBinding>
</bindings>
<client>
<endpoint address="http://192.168.2.3:8080/binder/services/countService"
binding="basicHttpBinding" bindingConfiguration="countServiceSoapBinding"
contract="ServiceReference1.CounterService" name="CounterServiceImplPort" />
</client>
</system.serviceModel>
</configuration>


运行一些客户端,就可以让服务器计算字符数了, 我们来看看HTTP请求是什么样子的。

[img]http://dl2.iteye.com/upload/attachment/0086/0791/afb80858-dca7-3004-a4bb-3755c5377acc.png[/img]

Content-Length: 1140036, 传输的内容都是base64编码的。也就是说传给count参数的byte数组被编码成Base64传输的。所以比实际的byte数组要大很多,我们的数组实际是854866, 大了近30%。

HTTP请求的内容

[img]http://dl2.iteye.com/upload/attachment/0086/0793/6daa649f-7d4a-3b42-b104-11b4006ff31d.png[/img]

[size=large]使用MTOM的情况[/size]

服务端

@WebService
public interface CounterService {
int count(@XmlMimeType("application/octet-stream") DataHandler value);
}


@Service
@WebService(endpointInterface = "com.cccis.ws.CounterService")
public class CounterServiceImpl implements CounterService {

@Override
public int count(DataHandler data) {
try {
String text = GZipUtils.decompressText(data.getInputStream(), "utf-8");
return text.length();
} catch (IOException e) {
e.printStackTrace();
return -1;
}
}
}


Java接口的参数类型由原来的b[b]yte[][/b]变成[b]DataHanlder[/b], 最重要的是要在前面加一个 @XmlMimeType("application/octet-stream")

配置文件:
    <jaxws:endpoint id="countService" implementor="#countServiceImpl"
serviceName="countService" address="/countService">
<jaxws:properties>
<entry key="mtom-enabled" value="true" />
</jaxws:properties>
</jaxws:endpoint>


添加了一个属性[b]mtom-enabled=true[/b]

加了上面的变化就OK了。

再来看看WCF[b]客户端[/b]的变化

只需要配置文件app.config发生变化就行了

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.serviceModel>
<bindings>
<customBinding>
<binding name="countServiceSoapBinding">
<mtomMessageEncoding messageVersion="Soap11"></mtomMessageEncoding>
<httpTransport/>
</binding>
</customBinding>
</bindings>
<client>
<endpoint address="http://192.168.2.3:8080/binder/services/countService"
binding="customBinding" bindingConfiguration="countServiceSoapBinding"
contract="ServiceReference1.CounterService" name="CounterServiceImplPort" />
</client>
</system.serviceModel>
</configuration>


由原来的basicHttpBinding变成customBinding,然后使用[b]mtomMessageEncoding[/b]即可。 这里需要注意一点的是如果不设置messageVersion="Soap11" 默认使用的是Soap1.2 但是在我的环境里CXF对Soap1.2+MTOM的方式支持的好像不是很好。 所有退而求其次用Soap1.1。

最后我们看一下MTOM的方式的HTTP请求到底是什么样子的

[img]http://dl2.iteye.com/upload/attachment/0086/0795/d7eaf4ff-bc24-3599-8a86-4f86790b6ade.png[/img]

我们可以看到Content-Length: 855855 比原来不用MTOM的1140036小了不少。 SOAP消息的样子也和原来的有很大的不同。

[img]http://dl2.iteye.com/upload/attachment/0086/0797/6820167d-da7b-3c66-aebf-17d6ea335e94.png[/img]

本文的源代码在附件中
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值