关于CXF大文件的传输问题

最近在做一个webservice的项目,本人选用的是Apache CXF来实现,因为需要再项目中进行大文件的传输问题,在网上找了很多这方面的资料,都不甚理想,说的都不够明白,有的文章讲的传输小文件还可以,在传输大文件的时候就会报内存溢出异常,这个是麻烦的事情,本人在综合了各位前辈的经验,终于实现了大文件大的传输问题,采用的是mtom的机制进行附件传输,废话少说,下面就是cxf整合spring进行大文件传输的一个例子,当然了,至于jar包就自己到官网下载了,首先开发客户端代码:

第一步:开发接口

package cn.genomics.signtureServer.cxf;

import javax.jws.WebParam;
import javax.jws.WebService;

import cn.genomics.signtureServer.model.Resume;

@WebService
public interface IFileUpload {
	
	String upload(@WebParam(name="resume") Resume resume);
}

 @WebService和(@WebParam这两个注释是不可以少的哦。

类Resume包含传输文件的参数:文件名,文件类型,数据源(可以是Datahandler或是一个字节数组)我这用的是Datahandler,代码如下:

package cn.genomics.signtureServer.model;

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;

@XmlRootElement(name="resume")
@XmlAccessorType(XmlAccessType.FIELD)
public class Resume {
	
	private String fileName;
	private String fileType;
	@XmlMimeType("application/octet-stream")
	private DataHandler fileData;
	
	public String getFileName() {
		return fileName;
	}
	public void setFileName(String fileName) {
		this.fileName = fileName;
	}
	public String getFileType() {
		return fileType;
	}
	public void setFileType(String fileType) {
		this.fileType = fileType;
	}
	public DataHandler getFileData() {
		return fileData;
	}
	public void setFileData(DataHandler fileData) {
		this.fileData = fileData;
	}
}

 @XmlMimeType("application/octet-stream")记住这个注释是必不可少的,说明这是一个二进制文件。

第二步:开发接口实现类:

package cn.genomics.signtureServer.cxf;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

import javax.jws.WebService;

import cn.genomics.signtureServer.model.Resume;

@WebService(endpointInterface="cn.genomics.signtureServer.cxf.IFileUpload") 
public class IFileUploadImpl implements IFileUpload {

	@Override
	public String upload(Resume resume) {
		File outFilePath = new File("F:\\上传文件");//文件上传的路径,自己想上传到哪就到哪,自己决定
		File outFile = new File(outFilePath.getAbsolutePath() + File.separator + resume.getFileName() + "."
								+ resume.getFileType());
		if(!outFilePath.exists()) {
			outFilePath.mkdir();
		}
		byte[] buf = new byte[1024 * 512];
		int read = 0;
		BufferedInputStream bis = null;
		BufferedOutputStream bos = null;
		try {
			bis = new BufferedInputStream(resume.getFileData().getInputStream());
			bos = new BufferedOutputStream(new FileOutputStream(outFile));
			while((read = bis.read(buf)) != -1) {
				bos.write(buf,0,read);
			}
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}finally {
			try {
				if(bos != null) {
					bos.close();
				}
				if(bis != null) {
					bis.close();
				}
			}catch(IOException e) {
				e.printStackTrace();
			}
		}
		return "文件上传成功";
	}
}

 接下来就是配置文件的配置了,首先是web.xml的配置:

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" 
	xmlns="http://java.sun.com/xml/ns/javaee" 
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
	xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
	http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
  <welcome-file-list>
    <welcome-file>index.jsp</welcome-file>
  </welcome-file-list>
  
  <context-param> 
  	<param-name>contextConfigLocation</param-name>
    <param-value>classpath:applicationContext.xml</param-value>
  </context-param>
  <listener> 
  	<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
  </listener> 
  
 
  <servlet>
  	<servlet-name>CXFServlet</servlet-name>
  	<servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class> 
  	<load-on-startup>1</load-on-startup>
  </servlet>
	<servlet-mapping> 
		<servlet-name>CXFServlet</servlet-name> 
		<url-pattern>/sealService/*</url-pattern> 
	</servlet-mapping> 
	
</web-app>

 下面是applicationContext.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:aop="http://www.springframework.org/schema/aop" 
	   xmlns:xsd="http://www.w3.org/2001/XMLSchema"
	   xmlns:tx="http://www.springframework.org/schema/tx" 
	   xmlns:context="http://www.springframework.org/schema/context"
	   xmlns:http-conf="http://cxf.apache.org/transports/http/configuration" 
	   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://www.springframework.org/schema/aop  
           		           http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
					       http://www.springframework.org/schema/context
					       http://www.springframework.org/schema/context/spring-context-3.0.xsd 
					       http://cxf.apache.org/transports/http/configuration 
					       http://cxf.apache.org/schemas/configuration/http-conf.xsd   
					       http://www.springframework.org/schema/tx   
      					   http://www.springframework.org/schema/tx/spring-tx-3.0.xsd   
					       http://cxf.apache.org/jaxws
					       http://cxf.apache.org/schemas/jaxws.xsd">
	<aop:aspectj-autoproxy/>  
	<context:component-scan base-package="cn.genomics.signtureServer"/>
	<context:annotation-config/>
	  
	<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"/>
	
	
	<http-conf:destination name="*.http-destination">  
        <http-conf:server ReceiveTimeout="90000"/>  
    </http-conf:destination>  
   
	<bean id="upload" class="cn.genomics.signtureServer.cxf.IFileUploadImpl"/>
	<jaxws:endpoint id="fileUpload" implementor="#upload" address="/FileUpload" publish="true">
		<jaxws:features>
			<bean class="org.apache.cxf.feature.LoggingFeature" /> 
		</jaxws:features>  
		<jaxws:properties >
			<entry key="mtom-enabled" value="true"/>
    	</jaxws:properties>
	</jaxws:endpoint>
</beans> 

到这里服务器端就开发完毕,把项目部署到tomcat容器里,访问地址:(我的是80端口)http://localhost/testFileUpload/sealService/FileUpload?wsdl,如果能访问的到,就说明成功了。下面的任务就是要开发客户端了。

首先接口:

扫描二维码关注公众号,回复: 646828 查看本文章
package cn.genomics.signtureserver.cxf;

import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebResult;
import javax.jws.WebService;
import javax.jws.soap.SOAPBinding;

@WebService(name = "IFileUpload", targetNamespace = "http://cxf.signtureServer.genomics.cn/")
@SOAPBinding(use = SOAPBinding.Use.LITERAL, parameterStyle = SOAPBinding.ParameterStyle.WRAPPED)
public interface IFileUpload {
	@WebMethod(operationName = "upload", action = "")
	@WebResult(name = "return", targetNamespace = "")
	String upload(@WebParam(name="resume")Resume resume);

}

 Resume类跟服务器端一样

接下来配置文件applicationContext_client.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:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:http-conf="http://cxf.apache.org/transports/http/configuration"
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://www.springframework.org/schema/context 
					http://www.springframework.org/schema/context/spring-context-3.0.xsd 
					http://cxf.apache.org/transports/http/configuration 
					http://cxf.apache.org/schemas/configuration/http-conf.xsd    
					http://cxf.apache.org/jaxws 
					http://cxf.apache.org/schemas/jaxws.xsd">
	<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"/>
	
	<http-conf:conduit name="*.http-conduit">  
        <http-conf:client ConnectionTimeout="30000" ReceiveTimeout="60000"/>  
    </http-conf:conduit>  
	
	<bean id="client" class="cn.genomics.signtureserver.cxf.IFileUpload" factory-bean="clientFactory" factory-method="create"/>
	<bean id="clientFactory" class="org.apache.cxf.jaxws.JaxWsProxyFactoryBean">
		<property name="serviceClass" value="cn.genomics.signtureserver.cxf.IFileUpload"/>
		<property name="address" value="http://localhost/testFileUpload/sealService/FileUpload?wsdl"/>
		<property name="properties">
			<map><entry key="mtom-enabled" value="true"></entry></map>
		</property>
	</bean>
</beans> 

 <map><entry key="mtom-enabled" value="true"></entry></map>这个绝对不能少。

现在可以测试了:

package cn.genomics.signtureserver.cxf;

import javax.activation.DataHandler;
import javax.activation.FileDataSource;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Test {
	
	public static void main(String[] args) {
		ApplicationContext con = new ClassPathXmlApplicationContext("applicationContext_client.xml");
		IFileUpload iu = con.getBean("client",IFileUpload.class);
		Resume re = new Resume();
		re.setFileName("h1");
		re.setFileType("zip");
		re.setFileData(new DataHandler(new FileDataSource("D:\\华大基因\\testDemo\\t1\\h1.zip")));
		iu.upload(re);
	}

}

猜你喜欢

转载自yanghui-java.iteye.com/blog/1747643