加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

WebService CXF --- 传输文件MTOM

发布时间:2020-12-16 23:02:16 所属栏目:安全 来源:网络整理
导读:博客分类: WebService ? 一、几个相关的概念 ? 1、MTOM基础概念????? ????? MTOM(Message Transmission Optimization Mechanism)消息优化传输机制。 ??它提出的模型适用于大量数据的交互情况。针对Base64编码情况带来的开销提出的解决方案。当数据量小的

    博客分类:
  • WebService
?

一、几个相关的概念

? 1、MTOM基础概念?????

????? MTOM(Message Transmission Optimization Mechanism)消息优化传输机制。

??它提出的模型适用于大量数据的交互情况。针对Base64编码情况带来的开销提出的解决方案。当数据量小的时候,SOAP依然使用XML进行消息的传递。

?? ?消息传输优化机制 (MTOM) 标准允许将消息中包含的大型数据元素外部化,并将其作为无任何特殊编码的二进制数据随消息一起传送。MTOM 消息会打包为多部分/相关 MIME 序列,放在SOAP 消息中一起传送。

??? 但是在大量数据情况下,如果数据依然进行Base64编码,会带来33%的额外开销,这样的情况对于大量数据交换的情况是无法容忍的。MTOM 就是针对SOAP 消息传输的基础上提出的改进办法。对于大量数据的传递,不会进行进行Base64编码,而是直接以附件的二进制原始数据的形式封装在SOAP消息的 MIME 部分,进行传输。SOAP 消息通过指向随其发送的 MIME 部分来引用二进制内容,另外包括SOAP基本的XML 数据,这些还是Base64编码。因为此模型与简单邮件协议SMTP 模型基本一致。

?????MTOM通过简化大量数据的编码过程,从而提高数据的处理效率。因为SOAP消息等必要的信息,MTOM 也有一些必要的开销。MTOM仅在二进制数据元素的大小超过大约 1 KB 时,才能体现出其优势。

?????什么是BASE64编码、MTOM消息优化传输机制、MIME。这些对于我们理解MTOM消息优化传输机制问题非常的必要。

?

? 2、BASE64编码?

??? BASE64编码 的原理很简单,其方法是,将输入数据流每次取6 bit(每bit代表1位二进制),不足6bit的补0,这样,每3个8位字节将编码为4个6位字节(3×8 → 4×6);不满4个字节的以“=”填充。其实这4个六位字节 仍然是8位,只不过高两位被设置为0。当一个字节只有6位有效时,它的取值空间为0 到 2的6次方减1 即63,也就是说被转换的Base64编码的每一个编码的取值空间为(0~63)。

?

  这样就可以将3个8位字节,转换为4个字节,这4个转换的字节都可以映射到字符中。也即数据都可以使用字符编码代替。 因为转换后的字符串要比原来的多一个字节,长1/3。因此编码后的数据长度增加到4/3倍。这里也是为什么使用SOAP消息效率比MTOM低的原因。因为 SOAP使用XML语言进行消息传递,XML是基于BASE64编码的语言。

?

3、MIME

?? MIME表示多用途Internet邮件扩允协议。MIME扩允了基本的面向文本的Internet邮件系统,以便可以在消息中包含二进制附件。MIME(Multipurpose Internet Mail Extentions),一般译作"多用途的网络邮件扩充协议"。顾名思义,它可以传送多媒体文件。 MIME (Multipurpose Internet Mail Extensions,多目的Internet邮件扩展)是创建用于电子邮件交换,网络文档,及企业网和Internet上的其他应用程序中的文件格式的规范。

?

?

二、MTOM之旅

?? 1、POJO

?????

Java代码 ?

收藏代码

  1. package?org.wy.pojo;??
  2. ??
  3. import?javax.activation.DataHandler;??
  4. import?javax.xml.bind.annotation.XmlAccessType;??
  5. import?javax.xml.bind.annotation.XmlAccessorType;??
  6. import?javax.xml.bind.annotation.XmlMimeType;??
  7. import?javax.xml.bind.annotation.XmlRootElement;??
  8. import?javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;??
  9. ??
  10. @XmlRootElement??
  11. @XmlAccessorType(XmlAccessType.FIELD)??
  12. public?class?User?{??
  13. ????private?String?name?=?"wy";??
  14. ????private?String?sex?=?"man";??
  15. ????public?int?age?=?20;??
  16. ??????
  17. ????//private?Address?address;??
  18. ??????
  19. ????//注这是一个附件类型的数据??
  20. ????@XmlMimeType("application/octet-stream")??
  21. ????private?DataHandler?dataHandler;??
  22. ??????
  23. ????public?String?getName()?{??
  24. ????????return?name;??
  25. ????}??
  26. ??
  27. ????public?void?setName(String?name)?{??
  28. ????????this.name?=?name;??
  29. ????}??
  30. ??
  31. ????//处理复杂的对象??
  32. ????/*@XmlJavaTypeAdapter(AddressAdapter.class)?
  33. ????public?Address?getAddress()?{?
  34. ????????return?address;?
  35. ????}?
  36. ?
  37. ????public?void?setAddress(Address?address)?{?
  38. ????????this.address?=?address;?
  39. ????}*/??
  40. ??
  41. ????public?DataHandler?getDataHandler()?{??
  42. ????????return?dataHandler;??
  43. ????}??
  44. ??
  45. ????public?void?setDataHandler(DataHandler?dataHandler)?{??
  46. ????????this.dataHandler?=?dataHandler;??
  47. ????}??
  48. ??????
  49. }?????

?

??? MTOM 方式中要传输的附件必须使用javax.activation.DataHandler 类,还要注意必须在类上使用@XmlAccessorType(XmlAccessType.FIELD)注解,标注JAXB 在进行JAVA 对象与XML 之间进行转换时只关注字段,而不关注属性(getXXX()方法)。

??? 然后使用@XmlMimeType 注解标注这是一个附件类型的数据,这里我们标注imageData 是一个二进制文件,当然你也可以使用具体的MIME类型,譬如:image/jpg、image/gif 等,但要考虑到客户端是否支持。

?

?2、接口类

????

Java代码 ?

收藏代码

  1. package?org.wy.service;??
  2. ??
  3. import?javax.jws.WebService;??
  4. import?javax.jws.soap.SOAPBinding;??
  5. import?javax.xml.ws.soap.MTOM;??
  6. ??
  7. import?org.wy.pojo.User;??
  8. @WebService(name="userService")?//name属性标注在接口类上,可以指定wsdl中接口名称,也就是生成的客户端代码中接口类的名字。??
  9. @SOAPBinding(style?=?SOAPBinding.Style.RPC)?//指定SOAP消息样式??
  10. @MTOM??//开启MTOM功能??
  11. public?interface?IUserService?{??
  12. ????public?User?getUser();??
  13. }??

?

??? @MTOM注解用于开启MTOM功能。

??? @WebService注解中的name属性标注在接口类上,可以指定wsdl中接口名称,也就是生成的客户端代码中接口类的名字。

??? @SOAPBinding(style = SOAPBinding.Style.RPC)指定SOAP消息样式,有两个枚举值:SOAPBinding.Style.DOCUMENT(默认)和 SOAPBinding.Style.RPC,可以对比这两种方式生成的wsdl会有所不同,而且生成的客户端代码也会有所不同。

?

?实现类:

??????

Java代码 ?

收藏代码

  1. package?org.wy.service.impl;??
  2. ??
  3. import?java.io.File;??
  4. ??
  5. import?javax.activation.DataHandler;??
  6. import?javax.activation.FileDataSource;??
  7. import?javax.jws.WebService;??
  8. ??
  9. import?org.wy.pojo.User;??
  10. import?org.wy.service.IUserService;??
  11. /**?
  12. ?*??
  13. ?*?@author?wy?
  14. ?*?
  15. ?*/??
  16. @WebService??
  17. public?class?UserServiceImpl?implements?IUserService{??
  18. ????public?User?getUser()??
  19. ????{??
  20. ????????User?user?=?new?User();??
  21. ????????user.setName("wy");??
  22. ????????user.setDataHandler(new?DataHandler(new?FileDataSource(new?File("D:resumelogo.gif"))));??
  23. ????????return?user;??
  24. ????}??
  25. }??

?

3、服务端配置

?? applicationContext-cxf.xml

??

Xml代码 ?

收藏代码

  1. <?xml?version="1.0"?encoding="UTF-8"??>??
  2. <beans?xmlns="http://www.springframework.org/schema/beans"??
  3. ????xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"??
  4. ????xmlns:jaxws="http://cxf.apache.org/jaxws"??
  5. ????xsi:schemaLocation="??
  6. ????http://www.springframework.org/schema/beans???
  7. ????http://www.springframework.org/schema/beans/spring-beans-3.0.xsd??
  8. ????http://cxf.apache.org/jaxws???
  9. ????http://cxf.apache.org/schemas/jaxws.xsd">??
  10. ??
  11. ????<!--?导入资源?-->??
  12. ????<import?resource="classpath:META-INF/cxf/cxf.xml"?/>??
  13. ????<import?resource="classpath:META-INF/cxf/cxf-extension-soap.xml"?/>??
  14. ????<import?resource="classpath:META-INF/cxf/cxf-servlet.xml"?/>??
  15. ??
  16. ????<!--?<jaxws:endpoint?implementor="org.wy.service.impl.UserServiceImpl"?address="/UserService"/>?-->??
  17. ??
  18. ????<!--?使用bean?-->??
  19. ??????
  20. ????<jaxws:endpoint?implementor="#userService"?address="/UserService"?/>??
  21. ??
  22. </beans>??

??

在命令行键入“wsimport -p org.wy.client -keep ?http://localhost:8080/WebServiceCXF/services/UserService?wsdl”生成客户端代码,拷贝到工程相应文件夹

当然也可以使用CXF中的wsdl2java命令生成客户端。

?

这时,就可以调用这个服务了:

?? 测试类:

??

Java代码 ?

收藏代码

  1. package?org.wy.jdkclienttest;??
  2. ??
  3. import?java.io.FileOutputStream;??
  4. import?java.io.IOException;??
  5. import?java.io.InputStream;??
  6. ??
  7. import?javax.activation.DataHandler;??
  8. ??
  9. import?org.wy.jdkclient.User;??
  10. import?org.wy.jdkclient.UserServiceImplService;??
  11. ??
  12. /**?
  13. ?*??
  14. ?*?@author?wy?
  15. ?*?
  16. ?*/??
  17. public?class?Test?{??
  18. ??
  19. ????public?static?void?main(String[]?args)?throws?IOException?{??
  20. ????????UserServiceImplService?userService?=?new?UserServiceImplService();??
  21. ????????User?user?=?userService.getUserServiceImplPort().getUser();??
  22. ??????????
  23. ????????String?name?=?user.getName();??
  24. ????????int?age?=?user.getAge();??
  25. ????????String?sex?=?user.getSex();??
  26. ????????System.out.println(name+"rn"+age+"rn"+sex);??
  27. ??????????
  28. ????????//输出传递过来的文件??
  29. ????????DataHandler?dataHandler?=?user.getDataHandler();??
  30. ????????String?fileName?=?dataHandler.getName();??
  31. ????????String?fileType?=?dataHandler.getContentType();??
  32. ????????Object?content?=?dataHandler.getContent();??
  33. ????????System.out.println(fileName+"rn"+fileType+"rn"+content.toString());??
  34. ????????//Streaming?Mode???
  35. ????????InputStream?is?=?dataHandler.getInputStream();??
  36. ????????FileOutputStream?fos?=?new?FileOutputStream("D:logo.gif");??
  37. ????????byte[]?bytes?=?new?byte[2048];??
  38. ????????int?len?=?0;??
  39. ????????while((len?=?is.read(bytes))!=-1){??
  40. ????????????fos.write(bytes,?0,?len);??
  41. ????????}??
  42. ????????fos.flush();??
  43. ????????fos.close();??
  44. ????????is.close();??
  45. ????}??
  46. ??
  47. }??

??

?

?来看下结果:

?

Java代码 ?

收藏代码

  1. 2011-12-25?14:03:49?org.apache.cxf.service.factory.ReflectionServiceFactoryBean?buildServiceFromWSDL??
  2. 信息:?Creating?Service?{http://impl.service.wy.org/}UserServiceImplService?from?WSDL:?http://localhost:8080/WebServiceCXF/services/UserService?wsdl??
  3. name=?wy??
  4. age=?20??
  5. sex=?man??
  6. fileName=?null??
  7. fileType=?image/gif??
  8. fileContent=?org.apache.cxf.attachment.DelegatingInputStream@11e1bbf??

?

?

附件中是上一篇和本篇的代码。

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读