CXF实现MTOM协议
MTOM(SOAP Message Transmission Optimization Mechanism)SOAP 消息传输优化机制,可以在SOAP 消息中发送二进制数据,与SAAJ 传输附件不同,MTOM需要XOP(XML-binary Optimized Packing)来传输二进制数据。MTOM 允许将消息中包含的大型数据元素外部化,并将其作为无任何特殊编码的二进制数据随消息一起传送。MTOM 消息会打包为多部分相关 MIME 序列,放在SOAP 消息中一起传送。因此你可以看出MTOM 并不是将附件转为Base64 编码,这样可以大大的提高性能,因为二进制文件转Base64 编码会非常庞大。
MTOM 方式中要传输的附件必须使用javax.activation.DataHandler 类,然后对象类型还要使用@javax.xml.binding.annotation.XmlMimeType 进行注解,标注这是一个附件类型的数据。
1、POJO对象类的处理
- @XmlRootElement(name="User")
- @XmlAccessorType(XmlAccessType.FIELD)
- @XmlType(name="User")
- public class User {
- @XmlElement(nillable=true)
- private Long id;
- @XmlElement(nillable=true)
- private String name;
- @XmlElement(nillable=true)
- private int age;
- @XmlMimeType("application/octet-stream")
- private DataHandler imageData; //人员的图像
- public User() {}
- public User(Long id, String name, int age) {
- super();
- this.id = id;
- this.name = name;
- this.age = age;
- }
注意:图像的类型必须为DataHandle类型。这里标注imageData 是一个二进制文件(application/octet-stream),当然你也可以使用具体的MIME类型,譬如:image/jpg、image/gif 等,但你要考虑客户端是否有对应的类型(因为JAVA语言之外的客户端的特性未必是你完全了解的),而且javax.activation.*中的MIME 的相关API 可以完成MIME 类型的自动识别。这里你要注意的是必须在类上使用@XmlAccessorType(FIELD)注解,标注JAXB 在进行JAVA 对象与XML 之间进行转换时只关注字段,而不关注属性(getXXX()方法),否则发布Web 服务时会报出现了两个imageData 属性的错误
2、让你要在服务端和客户端分别启用MTOM 支持。可以与spring整合后,可以修改CXF的spring配置文件,来启用MTOM
- <jaxws:properties>
- <entry key="mtom-enabled" value="true" />
- </jaxws:properties>
这段内容加到<jaxws:server … 、<jaxws:endpoint … 、<jaxws:client … 之间即可
3、具体实现
(1)HelloWorld.java接口添加如下两个方法
- @WebMethod
- public User getUser();
- @WebMethod
- public void updateUser(@WebParam(name="user")User user);
2)HellWorld.java实现接口添加的两个方法
- /**
- * <修改用户信息,包括上传用户的图像
- * 创 建 人: XX
- * 创建时间: 2012-9-26 下午04:50:23
- * @param user
- * @see [类、类#方法、类#成员]
- */
- public void updateUser(User user){
- System.out.println("姓名:"+user.getName()+",年龄:"+user.getAge());
- DataHandler handler = user.getImageData();
- try {
- InputStream is = handler.getInputStream();
- OutputStream os = new FileOutputStream(new File("c:\\test11.jpg"));
- byte[] b = new byte[100000];
- int bytesRead = 0;
- while ((bytesRead = is.read(b)) != -1) {
- os.write(b, 0, bytesRead);
- }
- os.flush();
- os.close();
- is.close();
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- /**
- * 查询用户信息,包括以附件的形式返回用户的图像
- * 创 建 人: XX
- * 创建时间: 2012-9-26 下午04:49:43
- * @return
- * @see [类、类#方法、类#成员]
- */
- public User getUser(){
- User user =new User(11L,"李四",21);
- user.setImageData(new DataHandler(new FileDataSource(new File("d:"+File.separator)+"test.jpg")));
- return user;
- }
4、测试
- User user =client.getUser();
- //修改用户信息,包括上传图像
- user =new User(12L,"王五",23);
- DataSource source = new FileDataSource(new File("d:"+File.separator+"test.jpg"));
- user.setImageData(new DataHandler(source));
- client.updateUser(user);
- //查询用户信息
- InputStream is = user.getImageData().getDataSource().getInputStream();
- OutputStream os = new FileOutputStream(new File("d:"+File.separator+"test11.jpg"));
- byte[] b = new byte[100000];
- int bytesRead = 0;
- while ((bytesRead = is.read(b)) != -1) {
- os.write(b, 0, bytesRead);
- }
- os.close();
- is.close();

浙公网安备 33010602011771号