今天就跟大家聊聊有關(guān)怎么理解WebService CXF中傳輸文件MTOM,可能很多人都不太了解,為了讓大家更加了解,小編給大家總結(jié)了以下內(nèi)容,希望大家根據(jù)這篇文章可以有所收獲。
成都創(chuàng)新互聯(lián)公司作為成都網(wǎng)站建設(shè)公司,專注網(wǎng)站建設(shè)、網(wǎng)站設(shè)計(jì),有關(guān)企業(yè)網(wǎng)站設(shè)計(jì)方案、改版、費(fèi)用等問題,行業(yè)涉及報(bào)廢汽車回收等多個(gè)領(lǐng)域,已為上千家企業(yè)服務(wù),得到了客戶的尊重與認(rèn)可。
一、幾個(gè)相關(guān)的概念
1、MTOM基礎(chǔ)概念
官方介紹:http://cxf.apache.org/docs/mtom-attachments-with-jaxb.html
MTOM(Message Transmission Optimization Mechanism)消息優(yōu)化傳輸機(jī)制。
它提出的模型適用于大量數(shù)據(jù)的交互情況。針對Base64編碼情況帶來的開銷提出的解決方案。當(dāng)數(shù)據(jù)量小的時(shí)候,SOAP依然使用XML進(jìn)行消息的傳遞。
消息傳輸優(yōu)化機(jī)制 (MTOM) 標(biāo)準(zhǔn)允許將消息中包含的大型數(shù)據(jù)元素外部化,并將其作為無任何特殊編碼的二進(jìn)制數(shù)據(jù)隨消息一起傳送。MTOM 消息會(huì)打包為多部分/相關(guān) MIME 序列,放在SOAP 消息中一起傳送。
但是在大量數(shù)據(jù)情況下,如果數(shù)據(jù)依然進(jìn)行Base64編碼,會(huì)帶來33%的額外開銷,這樣的情況對于大量數(shù)據(jù)交換的情況是無法容忍的。MTOM 就是針對SOAP 消息傳輸?shù)幕A(chǔ)上提出的改進(jìn)辦法。對于大量數(shù)據(jù)的傳遞,不會(huì)進(jìn)行進(jìn)行Base64編碼,而是直接以附件的二進(jìn)制原始數(shù)據(jù)的形式封裝在SOAP消息的 MIME 部分,進(jìn)行傳輸。SOAP 消息通過指向隨其發(fā)送的 MIME 部分來引用二進(jìn)制內(nèi)容,另外包括SOAP基本的XML 數(shù)據(jù),這些還是Base64編碼。因?yàn)榇四P团c簡單郵件協(xié)議SMTP 模型基本一致。
MTOM通過簡化大量數(shù)據(jù)的編碼過程,從而提高數(shù)據(jù)的處理效率。因?yàn)镾OAP消息等必要的信息,MTOM 也有一些必要的開銷。MTOM僅在二進(jìn)制數(shù)據(jù)元素的大小超過大約 1 KB 時(shí),才能體現(xiàn)出其優(yōu)勢。
什么是BASE64編碼、MTOM消息優(yōu)化傳輸機(jī)制、MIME。這些對于我們理解MTOM消息優(yōu)化傳輸機(jī)制問題非常的必要。
2、BASE64編碼
BASE64編碼 的原理很簡單,其方法是,將輸入數(shù)據(jù)流每次取6 bit(每bit代表1位二進(jìn)制),不足6bit的補(bǔ)0,這樣,每3個(gè)8位字節(jié)將編碼為4個(gè)6位字節(jié)(3×8 → 4×6);不滿4個(gè)字節(jié)的以“=”填充。其實(shí)這4個(gè)六位字節(jié) 仍然是8位,只不過高兩位被設(shè)置為0。當(dāng)一個(gè)字節(jié)只有6位有效時(shí),它的取值空間為0 到 2的6次方減1 即63,也就是說被轉(zhuǎn)換的Base64編碼的每一個(gè)編碼的取值空間為(0~63)。
這樣就可以將3個(gè)8位字節(jié),轉(zhuǎn)換為4個(gè)字節(jié),這4個(gè)轉(zhuǎn)換的字節(jié)都可以映射到字符中。也即數(shù)據(jù)都可以使用字符編碼代替。 因?yàn)檗D(zhuǎn)換后的字符串要比原來的多一個(gè)字節(jié),長1/3。因此編碼后的數(shù)據(jù)長度增加到4/3倍。這里也是為什么使用SOAP消息效率比MTOM低的原因。因?yàn)?SOAP使用XML語言進(jìn)行消息傳遞,XML是基于BASE64編碼的語言。
3、MIME
MIME表示多用途Internet郵件擴(kuò)允協(xié)議。MIME擴(kuò)允了基本的面向文本的Internet郵件系統(tǒng),以便可以在消息中包含二進(jìn)制附件。MIME(Multipurpose Internet Mail Extentions),一般譯作"多用途的網(wǎng)絡(luò)郵件擴(kuò)充協(xié)議"。顧名思義,它可以傳送多媒體文件。 MIME (Multipurpose Internet Mail Extensions,多目的Internet郵件擴(kuò)展)是創(chuàng)建用于電子郵件交換,網(wǎng)絡(luò)文檔,及企業(yè)網(wǎng)和Internet上的其他應(yīng)用程序中的文件格式的規(guī)范。
二、MTOM之旅
1、POJO
Java代碼
package org.wy.pojo;
import javax.activation.DataHandler;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlMimeType;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class User {
private String name = "wy";
private String sex = "man";
public int age = 20;
//private Address address;
//注這是一個(gè)附件類型的數(shù)據(jù)
@XmlMimeType("application/octet-stream")
private DataHandler dataHandler;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
//處理復(fù)雜的對象
/*@XmlJavaTypeAdapter(AddressAdapter.class)
public Address getAddress() {
return address;
}
public void setAddress(Address address) {
this.address = address;
}*/
public DataHandler getDataHandler() {
return dataHandler;
}
public void setDataHandler(DataHandler dataHandler) {
this.dataHandler = dataHandler;
}
}
MTOM 方式中要傳輸?shù)母郊仨毷褂胘avax.activation.DataHandler 類,還要注意必須在類上使用@XmlAccessorType(XmlAccessType.FIELD)注解,標(biāo)注JAXB 在進(jìn)行JAVA 對象與XML 之間進(jìn)行轉(zhuǎn)換時(shí)只關(guān)注字段,而不關(guān)注屬性(getXXX()方法)。
然后使用@XmlMimeType 注解標(biāo)注這是一個(gè)附件類型的數(shù)據(jù),這里我們標(biāo)注imageData 是一個(gè)二進(jìn)制文件,當(dāng)然你也可以使用具體的MIME類型,譬如:image/jpg、image/gif 等,但要考慮到客戶端是否支持。
2、接口類
Java代碼
package org.wy.service;
import javax.jws.WebService;
import javax.jws.soap.SOAPBinding;
import javax.xml.ws.soap.MTOM;
import org.wy.pojo.User;
@WebService(name="userService") //name屬性標(biāo)注在接口類上,可以指定wsdl中接口名稱,也就是生成的客戶端代碼中接口類的名字。
@SOAPBinding(style = SOAPBinding.Style.RPC) //指定SOAP消息樣式
@MTOM //開啟MTOM功能
public interface IUserService {
public User getUser();
}
@MTOM注解用于開啟MTOM功能。
@WebService注解中的name屬性標(biāo)注在接口類上,可以指定wsdl中接口名稱,也就是生成的客戶端代碼中接口類的名字。
@SOAPBinding(style = SOAPBinding.Style.RPC)指定SOAP消息樣式,有兩個(gè)枚舉值:SOAPBinding.Style.DOCUMENT(默認(rèn))和 SOAPBinding.Style.RPC,可以對比這兩種方式生成的wsdl會(huì)有所不同,而且生成的客戶端代碼也會(huì)有所不同。
實(shí)現(xiàn)類:
Java代碼
package org.wy.service.impl;
import java.io.File;
import javax.activation.DataHandler;
import javax.activation.FileDataSource;
import javax.jws.WebService;
import org.wy.pojo.User;
import org.wy.service.IUserService;
/**
*
* @author wy
*
*/
@WebService
public class UserServiceImpl implements IUserService{
public User getUser()
{
User user = new User();
user.setName("wy");
user.setDataHandler(new DataHandler(new FileDataSource(new File("D:\\resume\\logo.gif"))));
return user;
}
}
3、服務(wù)端配置
applicationContext-cxf.xml
Xml代碼
<?xml version="1.0" encoding="UTF-8" ?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:jaxws="http://cxf.apache.org/jaxws"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://cxf.apache.org/jaxws
http://cxf.apache.org/schemas/jaxws.xsd">
<!-- 導(dǎo)入資源 -->
<import resource="classpath:META-INF/cxf/cxf.xml" />
<import resource="classpath:META-INF/cxf/cxf-extension-soap.xml" />
<import resource="classpath:META-INF/cxf/cxf-servlet.xml" />
<!-- <jaxws:endpoint implementor="org.wy.service.impl.UserServiceImpl" address="/UserService"/> -->
<!-- 使用bean -->
<jaxws:endpoint implementor="#userService" address="/UserService" />
</beans>
在命令行鍵入“wsimport -p org.wy.client -keep http://localhost:8080/WebServiceCXF/services/UserService?wsdl”生成客戶端代碼,拷貝到工程相應(yīng)文件夾
當(dāng)然也可以使用CXF中的wsdl2java命令生成客戶端。
這時(shí),就可以調(diào)用這個(gè)服務(wù)了:
測試類:
Java代碼
package org.wy.jdkclienttest;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import javax.activation.DataHandler;
import org.wy.jdkclient.User;
import org.wy.jdkclient.UserServiceImplService;
/**
*
* @author wy
*
*/
public class Test {
public static void main(String[] args) throws IOException {
UserServiceImplService userService = new UserServiceImplService();
User user = userService.getUserServiceImplPort().getUser();
String name = user.getName();
int age = user.getAge();
String sex = user.getSex();
System.out.println(name+"\r\n"+age+"\r\n"+sex);
//輸出傳遞過來的文件
DataHandler dataHandler = user.getDataHandler();
String fileName = dataHandler.getName();
String fileType = dataHandler.getContentType();
Object content = dataHandler.getContent();
System.out.println(fileName+"\r\n"+fileType+"\r\n"+content.toString());
//Streaming Mode
InputStream is = dataHandler.getInputStream();
FileOutputStream fos = new FileOutputStream("D:\\logo.gif");
byte[] bytes = new byte[2048];
int len = 0;
while((len = is.read(bytes))!=-1){
fos.write(bytes, 0, len);
}
fos.flush();
fos.close();
is.close();
}
}
來看下結(jié)果:
Java代碼
2011-12-25 14:03:49 org.apache.cxf.service.factory.ReflectionServiceFactoryBean buildServiceFromWSDL
信息: Creating Service {http://impl.service.wy.org/}UserServiceImplService from WSDL: http://localhost:8080/WebServiceCXF/services/UserService?wsdl
name= wy
age= 20
sex= man
fileName= null
fileType= image/gif
fileContent= org.apache.cxf.attachment.DelegatingInputStream@11e1bbf
看完上述內(nèi)容,你們對怎么理解WebService CXF中傳輸文件MTOM有進(jìn)一步的了解嗎?如果還想了解更多知識(shí)或者相關(guān)內(nèi)容,請關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道,感謝大家的支持。
當(dāng)前題目:怎么理解WebServiceCXF中傳輸文件MTOM
當(dāng)前網(wǎng)址:http://bm7419.com/article28/iehhjp.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站營銷、動(dòng)態(tài)網(wǎng)站、自適應(yīng)網(wǎng)站、營銷型網(wǎng)站建設(shè)、企業(yè)建站、面包屑導(dǎo)航
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)