zoukankan      html  css  js  c++  java
  • 传输参数【JAXWS入门系列】第06章_使用MTOM处理二进制文件

    最近应用开发的过程中出现了一个小问题,顺便记录一下原因和方法--传输参数

        首先示例服务端代码

        

        

        上面这个SEI,是以byte[]为参数的服务端接口类BinaryService.java

    package com.jadyer.service;
    
    import javax.jws.WebParam;
    import javax.jws.WebService;
    
    @WebService(targetNamespace="http://blog.csdn.net/jadyer")
    public interface BinaryService {
    	public void upload(@WebParam(name="uploadFile")byte[] file);
    }

        上面这个SEI,是以DataHandler为参数的服务端接口类BinaryHandlerService.java

    package com.jadyer.service;
    
    import javax.activation.DataHandler;
    import javax.jws.WebParam;
    import javax.jws.WebService;
    import javax.xml.bind.annotation.XmlMimeType;
    
    @WebService(targetNamespace="http://blog.csdn.net/jadyerHandler")
    public interface BinaryHandlerService {
    	public void uploadUseHandler(@WebParam(name="uploadFile")
    								 @XmlMimeType("application/octet-stream")
    								 DataHandler file);
    }

        接下来分别是两个SEI对应的SIB

    package com.jadyer.service;
    
    import java.io.File;
    import java.io.IOException;
    
    import javax.jws.WebService;
    import javax.xml.ws.soap.MTOM;
    
    import org.apache.commons.io.FileUtils;
    
    @WebService(endpointInterface="com.jadyer.service.BinaryService", targetNamespace="http://blog.csdn.net/jadyer")
    @MTOM
    public class BinaryServiceImpl implements BinaryService {
    	@Override
    	public void upload(byte[] file) {
    		try {
    			//FileUtils类引用自commons-io-2.4.jar
    			FileUtils.writeByteArrayToFile(new File("D:/test.jpg"), file);
    		} catch (IOException e) {
    			e.printStackTrace();
    		}
    	}
    }
    package com.jadyer.service;
    
    import java.io.File;
    import java.io.IOException;
    
    import javax.activation.DataHandler;
    import javax.jws.WebService;
    import javax.xml.ws.BindingType;
    import javax.xml.ws.soap.SOAPBinding;
    
    import org.apache.commons.io.FileUtils;
    
    @WebService(endpointInterface="com.jadyer.service.BinaryHandlerService",
    			targetNamespace="http://blog.csdn.net/jadyerHandler")
    @BindingType(SOAPBinding.SOAP11HTTP_MTOM_BINDING)
    public class BinaryHandlerServiceImpl implements BinaryHandlerService {
    	@Override
    	public void uploadUseHandler(DataHandler file) {
    		try {
    			//FileUtils类引用自commons-io-2.4.jar
    			FileUtils.copyInputStreamToFile(file.getDataSource().getInputStream(), new File("D:/test2.jpg"));
    		} catch (IOException e) {
    			e.printStackTrace();
    		}
    	}
    }

        最后是发布服务的ServerApp.java

        每日一道理
    成熟是一种明亮而不刺眼的光辉,一种圆润而不腻耳的音响,一种不需要对别人察颜观色的从容,一种终于停止了向周围申诉求告的大气,一种不理会哄闹的微笑,一种洗刷了偏激的淡漠,一种无须声张的厚实,一种并不陡峭的高度。
    package com.jadyer.server;
    
    import javax.xml.ws.Endpoint;
    
    import com.jadyer.service.BinaryHandlerService;
    import com.jadyer.service.BinaryHandlerServiceImpl;
    import com.jadyer.service.BinaryServiceImpl;
    
    /**
     * 应用MTOM处理二进制文件
     * @see ---------------------------------------------------------------------------------------------------
     * @see 比拟传统做法是:服务端颁布的方法参数为byte[],客户端调用时直接传进去一个文件的byte[]便可
     * @see 此时应用TcpMon监听报文会发现,字节数组在传送的过程中,都是在SOAPBody里头传送的,而且是一次性全部传送
     * @see 那么问题就来了:如果传送的文件比拟大,就有可能形成内存溢出
     * @see 对此,有一种解决方案是应用MTOM机制传输文件
     * @see ---------------------------------------------------------------------------------------------------
     * @see MTOM(Message Transmission Optimization Mechanism),翻译过来就是消息优化传输机制
     * @see 应用了MTOM后,我们再应用tcpmon监听报文会发现,文件传输是通过附件(以流的形式)传送的,而不是通过SOAPBody
     * @see 这里有须要提一下:当应用Apache的TcpMon监听MTOM时,由于JAXWS版本问题,可能会呈文上面的异常
     * @see javax.xml.ws.WebServiceException: java.io.IOException: Error writing to server
     * @see 这时,我们可以应用GoogleCode上的tcpmon或者Eclipse提供的TCP/IP Monitor
     * @see 有关三者的描述,可参考我的博客http://blog.csdn.net/jadyer/article/details/8967447
     * @see 好了,回归正题.关于MTOM,有两种实现方式,分别为传输byte[]和传输javax.activation.DataHandler
     * @see ---------------------------------------------------------------------------------------------------
     * @see MTOM实现之传输byte[]
     * @see 1)SEI中定义开放服务的方法参数为byte[]
     * @see 2)应用@MTOM注解SIB,表现打开MTOM传输功能
     * @see 3)客户端调用时,为getServicePort()方法传入new MTOMFeature()参数,表现启用MTOM传输
     * @see   如new BinaryServiceImplService().getBinaryServiceImplPort(new MTOMFeature()).upload(....)
     * @see ---------------------------------------------------------------------------------------------------
     * @see MTOM实现之传输javax.activation.DataHandler
     * @see 1)SEI中定义开放服务的方法参数为DataHandler,并为该参数增长注解@XmlMimeType("application/octet-stream")
     * @see 2)应用@BindingType(SOAPBinding.SOAP11HTTP_MTOM_BINDING)注解SIB
     * @see 3)客户端调用时应用(SOAPBinding)((BindingProvider)service).setMTOMEnabled(true)启用MTOM传输
     * @see   BinaryHandlerService service = new BinaryHandlerServiceImplService().getBinaryHandlerServiceImplPort()
     * @see   BindingProvider bp = (BindingProvider)service
     * @see   SOAPBinding binding = (SOAPBinding)bp.getBinding()
     * @see   binding.setMTOMEnabled(true)
     * @see   service.uploadUseHandler(new DataHandler(new FileDataSource(new File("D:/玄玉.png"))));
     * @see ---------------------------------------------------------------------------------------------------
     * @see MTOM总结
     * @see 其实在应用DataHandler时,第二步和第三步都可以应用<code>MTOM实现之传输byte[]</code>的第二,三步编写方式
     * @see 即应用@MTOM和new MTOMFeature()来打开MTOM传输并启用之,也就是说这两种方式的区分就在于开放服务的方法参数不同
     * @see 一个是upload(byte[] file),一个是upload(@XmlMimeType("application/octet-stream")DataHandler file)
     * @see ---------------------------------------------------------------------------------------------------
     * @create May 26, 2013 12:15:53 AM
     * @author 玄玉<http://blog.csdn.net/jadyer>
     */
    public class ServerApp {
    	public static void main(String[] args) {
    		Endpoint.publish("http://127.0.0.1:8086/upload", new BinaryServiceImpl());
    		Endpoint.publish("http://127.0.0.1:8086/uploadHandler", new BinaryHandlerServiceImpl());
    	}
    }

        OK,服务端代码示例完毕,上面是客户端代码

        

        

        客户端只有一个演示调用服务的类ClientApp.java

        注意:具体客户端代码是由wsimport生成的,详见http://blog.csdn.net/jadyer/article/details/8692108

    package com.jadyer.client;
    
    import java.io.File;
    import java.io.IOException;
    import java.net.URL;
    
    import javax.activation.DataHandler;
    import javax.activation.FileDataSource;
    import javax.xml.namespace.QName;
    import javax.xml.ws.BindingProvider;
    import javax.xml.ws.soap.SOAPBinding;
    
    import net.csdn.blog.jadyerhandler.BinaryHandlerService;
    import net.csdn.blog.jadyerhandler.BinaryHandlerServiceImplService;
    
    /**
     * wsimport -d D:/Download/ -keep -verbose http://127.0.0.1:8086/upload?wsdl
     * @create May 26, 2013 1:47:40 AM
     * @author 玄玉<http://blog.csdn.net/jadyer>
     */
    public class ClientApp {
    	public static void main(String[] args) throws IOException {
    //		URL url = new URL("http://127.0.0.1:8086/upload?wsdl");
    //		QName qname = new QName("http://blog.csdn.net/jadyer", "BinaryServiceImplService");
    //		byte[] uploadFile = FileUtils.readFileToByteArray(new File("D:/玄玉.png"));
    //		//普通的传文件
    //		new BinaryServiceImplService(url, qname).getBinaryServiceImplPort().upload(uploadFile);
    //		//MTOM方式
    //		new BinaryServiceImplService(url, qname).getBinaryServiceImplPort(new MTOMFeature()).upload(uploadFile);
    		
    		
    		URL urlHandler = new URL("http://127.0.0.1:8086/uploadHandler?wsdl");
    		QName qnameHandler = new QName("http://blog.csdn.net/jadyerHandler", "BinaryHandlerServiceImplService");
    		BinaryHandlerService service = new BinaryHandlerServiceImplService(urlHandler, qnameHandler).getBinaryHandlerServiceImplPort();
    		BindingProvider bp = (BindingProvider)service;
    		SOAPBinding binding = (SOAPBinding)bp.getBinding();
    		binding.setMTOMEnabled(true);
    		service.uploadUseHandler(new DataHandler(new FileDataSource(new File("D:/玄玉.png"))));
    	}
    }

    文章结束给大家分享下程序员的一些笑话语录: 看到有人回帖“不顶不是中国人”,他的本意是想让帖子沉了。

    --------------------------------- 原创文章 By
    传输和参数
    ---------------------------------

  • 相关阅读:
    带你封装自己的『权限管理』框架
    一夜搞懂 | JVM 线程安全与锁优化
    一夜搞懂 | Java 内存模型与线程
    一夜搞懂 | JVM 字节码执行引擎
    一夜搞懂 | JVM 类加载机制
    一夜搞懂 | JVM GC&内存分配
    一文洞悉JVM内存管理机制
    Redis 的基本数据类型 和 基础应用场景
    MyISAM 和 InnoDB 索引结构及其实现原理
    一次性搞懂 PHP 中面向对象的所有知识点。
  • 原文地址:https://www.cnblogs.com/jiangu66/p/3112893.html
Copyright © 2011-2022 走看看