将二进制数据放到Attachment中进行传递,而不是放到SOAPBODY进行传递
xsd文件中定义二进制数据类型
<xsd:element type="tns:upload" name="upload"/> <xsd:element type="tns:uploadResponse" name="uploadResponse"/> <xsd:complexType name="upload"> <xsd:sequence> <xsd:element type="xsd:base64Binary" name="file" minOccurs="0"/> </xsd:sequence> </xsd:complexType> <xsd:complexType name="uploadResponse"> <xsd:sequence/> </xsd:complexType>
第一种方式:
服务端 @MOTM
客户端 new MTOMFeature(true)
接口参数:byte[] file
1.使用附件的形式传递二进制数据
接口
package com.hqh.service;
import java.util.List;
import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebResult;
import javax.jws.WebService;
import javax.xml.bind.annotation.XmlSeeAlso;
import javax.xml.ws.RequestWrapper;
import javax.xml.ws.ResponseWrapper;
import com.hqh.model.User;
/**
* This class was generated by the JAX-WS RI.
* JAX-WS RI 2.1.6 in JDK 6
* Generated source version: 2.1
*
*/
@WebService(name = "IUserService", targetNamespace = "http://service.hqh.com")
public interface IUserService {
/**
* 文件上传服务
* @param file
*/
@WebMethod
@RequestWrapper(localName = "upload", targetNamespace = "http://service.hqh.com", className = "com.hqh.service.Upload")
@ResponseWrapper(localName = "uploadResponse", targetNamespace = "http://service.hqh.com", className = "com.hqh.service.UploadResponse")
public void upload(
@WebParam(name = "file", targetNamespace = "http://service.hqh.com")
byte[] file);
}
服务器端实现类上增加MTOM注解
@WebService(endpointInterface="com.hqh.service.IUserService",
wsdlLocation="WEB-INF/wsdl/user.wsdl",
serviceName="UserService",
portName="userServicePort",
targetNamespace="http://service.hqh.com")
@MTOM
public class UserServiceImpl implements IUserService {
@Override
public void upload(byte[] data) {
FileOutputStream os = null;
try {
os = new FileOutputStream("E:/technology-hqh/proj/webservice/a.tmp");
os.write(data);
os.flush();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if(os!=null) {
try {
os.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
客户端
import java.io.File;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import javax.xml.namespace.QName;
import javax.xml.ws.soap.MTOMFeature;
import org.apache.commons.io.FileUtils;
import org.junit.Before;
import com.hqh.service.IUserService;
import com.hqh.service.UserService;
public class Test {
private UserService service ;
private IUserService iservice ;
@Before
public void init() {
try {
URL url = new URL("http://localhost:8888/Demo/service");
QName name = new QName("http://service.hqh.com", "UserService");
service = new UserService(url,name);
//开启MTOM功能,二进制文件将以附件形式传递
iservice = service.getUserServicePort(new MTOMFeature(true));
} catch (MalformedURLException e) {
e.printStackTrace();
}
}
@org.junit.Test
public void testUpload() {
try {
String path1="E:/technology-hqh/proj/webservice/35_二进制的处理(使用MTOM).avi";
String path2="D:/scott.dmp";
byte[] data = FileUtils.readFileToByteArray(
new File(path2));
iservice.upload(data);
} catch (IOException e) {
e.printStackTrace();
}
}
}
使用Eclipse的TCPM监控可观察到数据传输过程:
Host: localhost:8888 Connection: keep-alive Content-Length: 21291 --uuid:7a022a6f-e4f9-49de-9683-805e4f9ce0e7 Content-Id: <rootpart*7a022a6f-e4f9-49de-9683-805e4f9ce0e7@example.jaxws.sun.com> Content-Type: application/xop+xml;charset=utf-8;type="text/xml" Content-Transfer-Encoding: binary <?xml version="1.0" ?> <S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/"> <S:Body> <ns2:upload xmlns:ns2="http://service.hqh.com"> <file> <xop:Include xmlns:xop="http://www.w3.org/2004/08/xop/include" href="cid:19d34ad8-d956-4b9d-95bc-9f9f5ccc3760@example.jaxws.sun.com"></xop:Include> </file> </ns2:upload> </S:Body> </S:Envelope> --uuid:7a022a6f-e4f9-49de-9683-805e4f9ce0e7Content-Id: <19d34ad8-d956-4b9d-95bc-9f9f5ccc3760@example.jaxws.sun.com> Content-Type: application/octet-stream Content-Transfer-Encoding: binary TEXPORT:V10.02.01 USCOTT RUSERS 2048 0 20 0 TT� ...
第二种方式:
服务端 @BindingType(SOAPBinding.SOAP11HTTP_MTOM_BINDING)
客户端 DataHandler
接口参数:DataHandler handler
1.xsd
<!-- 文件上传 -->
<xsd:element type="tns:upload" name="upload"/>
<xsd:element type="tns:uploadResponse" name="uploadResponse"/>
<xsd:complexType name="upload">
<xsd:sequence>
<!-- <xsd:element type="xsd:base64Binary" name="file" minOccurs="0"/> -->
<!-- 第二种方式 -->
<xsd:element xmlns:xmime="http://www.w3.org/2005/05/xmlmime"
xmime:expectedContentTypes="application/octet-stream"
type="xsd:base64Binary" name="file" minOccurs="0" form="qualified" />
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="uploadResponse">
<xsd:sequence/>
</xsd:complexType>
接口
package com.hqh.service;
import java.util.List;
import javax.activation.DataHandler;
import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebResult;
import javax.jws.WebService;
import javax.xml.bind.annotation.XmlMimeType;
import javax.xml.bind.annotation.XmlSeeAlso;
import javax.xml.ws.RequestWrapper;
import javax.xml.ws.ResponseWrapper;
import com.hqh.model.User;
/**
* This class was generated by the JAX-WS RI.
* JAX-WS RI 2.1.6 in JDK 6
* Generated source version: 2.1
*
*/
@WebService(name = "IUserService", targetNamespace = "http://service.hqh.com")
public interface IUserService {
/**
* 文件上传服务
* @param file
*/
@WebMethod
@RequestWrapper(localName = "upload", targetNamespace = "http://service.hqh.com", className = "com.hqh.service.Upload")
@ResponseWrapper(localName = "uploadResponse", targetNamespace = "http://service.hqh.com", className = "com.hqh.service.UploadResponse")
public void upload(
@WebParam(name = "file", targetNamespace = "http://service.hqh.com")
@XmlMimeType("application/octet-stream")DataHandler handler);
}
实现类
package com.hqh.service;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import javax.activation.DataHandler;
import javax.annotation.Resource;
import javax.jws.WebService;
import javax.xml.namespace.QName;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;
import javax.xml.stream.events.XMLEvent;
import javax.xml.ws.BindingType;
import javax.xml.ws.WebServiceContext;
import javax.xml.ws.soap.MTOM;
import javax.xml.ws.soap.SOAPBinding;
import org.apache.commons.io.FileUtils;
import com.hqh.model.User;
import com.sun.xml.ws.api.message.Header;
import com.sun.xml.ws.api.message.HeaderList;
import com.sun.xml.ws.developer.JAXWSProperties;
@WebService(endpointInterface="com.hqh.service.IUserService",
wsdlLocation="WEB-INF/wsdl/user.wsdl",
serviceName="UserService",
portName="userServicePort",
targetNamespace="http://service.hqh.com")
//@MTOM
@BindingType(SOAPBinding.SOAP11HTTP_MTOM_BINDING)
public class UserServiceImpl implements IUserService {
@Override
public void upload(DataHandler handler) {
FileOutputStream os = null;
InputStream is = null;
try {
System.out.println(handler.getContentType());
is = handler.getInputStream();
int len = 0;
byte[] buf = new byte[1024];
os = new FileOutputStream("E:/technology-hqh/proj/webservice/b.tmp");
while((len=is.read(buf))!=-1) {
os.write(buf, 0, len);
}
os.flush();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if(os!=null)
os.close();
if(is!=null)
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
客户端
import java.io.File;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import javax.activation.DataHandler;
import javax.activation.FileDataSource;
import javax.xml.namespace.QName;
import javax.xml.ws.Binding;
import javax.xml.ws.BindingProvider;
import javax.xml.ws.soap.MTOMFeature;
import javax.xml.ws.soap.SOAPBinding;
import org.apache.commons.io.FileUtils;
import org.junit.Before;
import com.hqh.service.IUserService;
import com.hqh.service.UserService;
public class Test {
private UserService service ;
private IUserService iservice ;
@Before
public void init() {
try {
URL url = new URL("http://localhost:8888/Demo/service");
QName name = new QName("http://service.hqh.com", "UserService");
service = new UserService(url,name);
//开启MTOM功能,二进制文件将以附件形式传递
//第一种方式
// iservice = service.getUserServicePort(new MTOMFeature(true));
//第二种方式
iservice = service.getUserServicePort();
BindingProvider provider = (BindingProvider) iservice;
SOAPBinding binding = (SOAPBinding) provider.getBinding();
binding.setMTOMEnabled(true);
} catch (MalformedURLException e) {
e.printStackTrace();
}
}
@org.junit.Test
public void testUpload() {
String path1="E:/technology-hqh/proj/webservice/35_二进制的处理(使用MTOM).avi";
String path2="D:/scott.dmp";
DataHandler handler = new DataHandler(new FileDataSource(new File(path2)));
iservice.upload(handler);
}
}
通过eclipse的TCPM观察文件的传输:
GET /Demo/service?wsdl HTTP/1.1
User-Agent: Java/1.6.0_18
Host: localhost:8888
Accept: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2
Connection: keep-alive
POST /Demo/service HTTP/1.1
Content-type: multipart/related;start="<rootpart*dded5b46-a30b-4376-8f73-d0ab8d716898@example.jaxws.sun.com>";type="application/xop+xml";boundary="uuid:dded5b46-a30b-4376-8f73-d0ab8d716898";start-info="text/xml"
Soapaction: ""
Accept: text/xml, multipart/related, text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2
User-Agent: JAX-WS RI 2.1.6 in JDK 6
Host: localhost:8888
Connection: keep-alive
Content-Length: 21299
--uuid:dded5b46-a30b-4376-8f73-d0ab8d716898
Content-Id: <rootpart*dded5b46-a30b-4376-8f73-d0ab8d716898@example.jaxws.sun.com>
Content-Type: application/xop+xml;charset=utf-8;type="text/xml"
Content-Transfer-Encoding: binary
<?xml version="1.0" ?>
<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
<S:Body>
<ns2:upload xmlns:ns2="http://service.hqh.com">
<ns2:file>
<xop:Include xmlns:xop="http://www.w3.org/2004/08/xop/include"
href="cid:50f22c0a-386d-4db6-9c80-0c01fb2ceb6d@example.jaxws.sun.com"></xop:Include>
</ns2:file>
</ns2:upload>
</S:Body>
</S:Envelope>
--uuid:dded5b46-a30b-4376-8f73-d0ab8d716898
Content-Id: <50f22c0a-386d-4db6-9c80-0c01fb2ceb6d@example.jaxws.sun.com>
Content-Type: application/octet-stream
Content-Transfer-Encoding: binary
TEXPORT:V10.02.01
USCOTT
RUSERS
2048
0
20
0
TT�