首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 软件管理 > 软件架构设计 >

用MTOM在WCF跟CXF之间传数据

2013-07-04 
用MTOM在WCF和CXF之间传数据用MTOM在WCF和CXF之间传数据MTOM是一种机制,用来以原始字节形式传输包含SOAP消

用MTOM在WCF和CXF之间传数据
用MTOM在WCF和CXF之间传数据

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

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

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

@WebServicepublic 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" /><jaxws:endpoint       id="countService"       implementor="#countServiceImpl"       serviceName="countService"      address="/countService" />


客户端是一个简单的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请求是什么样子的。



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

HTTP请求的内容



使用MTOM的情况

服务端

@WebServicepublic 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接口的参数类型由原来的byte[]变成DataHanlder, 最重要的是要在前面加一个 @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>


添加了一个属性mtom-enabled=true

加了上面的变化就OK了。

再来看看WCF客户端的变化

只需要配置文件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,然后使用mtomMessageEncoding即可。 这里需要注意一点的是如果不设置messageVersion="Soap11" 默认使用的是Soap1.2 但是在我的环境里CXF对Soap1.2+MTOM的方式支持的好像不是很好。 所有退而求其次用Soap1.1。

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



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



本文的源代码在附件中

热点排行