zoukankan      html  css  js  c++  java
  • JAVA6开发WebService (二)——JAX-WS例子

    转载自http://wuhongyu.iteye.com/blog/807836

    上一篇写了个最简单的小例子,只是为了说明JAVA6开发Web Service很方便,这一篇稍微深入一点,写个稍微有点代表性的小例子。

        依然使用 JAX-WS(jdk自带的实现)方式,这次要在服务中使用一个复杂类型Customer,并实现附件传输的功能,这里使用MTOM的附件传输方式。MTOM(SOAP Message Transmission Optimization Mechanism)是SOAP 消息传输优化机制,MTOM可以在SOAP 消息中发送二进制数据。

    先来看Customer类:

    package com.why.server;
    
    import java.util.Date;
    
    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 = "Customer")
    @XmlAccessorType(XmlAccessType.FIELD)
    public class Customer {
        private long id;
        private String name;
        private Date birthday;
        @XmlMimeType("application/octet-stream")
        private DataHandler imageData;
        
            //getter and setter
            ......
    }

         MTOM 方式中要传输的附件必须使用javax.activation.DataHandler 类,还要注意必须在类上使用@XmlAccessorType(FIELD)注解,标注JAXB 在进行JAVA 对象与XML 之间进行转换时只关注字段,而不关注属性(getXXX()方法),否则发布Web 服务时会报出现了两个imageData 属性的错误,原因未知,可能是BUG。

        然后使用@XmlMimeType 注解标注这是一个附件类型的数据,这里我们标注imageData 是一个二进制文件,当然你也可以使用具体的MIME类型,譬如:image/jpg、image/gif 等,但要考虑到客户端是否支持。

    接口类:

    package com.why.server;
    
    import javax.jws.WebParam;
    import javax.jws.WebService;
    import javax.xml.ws.soap.MTOM;
    
    @WebService(name="Hello")
    @SOAPBinding(style = SOAPBinding.Style.RPC)
    @MTOM
    public interface Hello {
        public void printContext();
        public Customer selectCustomerByName(@WebParam(name = "customer")Customer customer);
        public Customer selectMaxAgeCustomer(Customer c1, Customer c2);
    }

        @MTOM注解用于开启MTOM功能。

        @WebService注解中的name属性标注在接口类上,可以指定wsdl中接口名称,也就是生成的客户端代码中接口类的名字。

        @SOAPBinding(style = SOAPBinding.Style.RPC)指定SOAP消息样式,有两个枚举值:SOAPBinding.Style.DOCUMENT(默认)和SOAPBinding.Style.RPC,可以对比这两种方式生成的wsdl会有所不同,而且生成的客户端代码也会有所不同。

    实现类:

    package com.why.server;
    
    import java.io.File;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.OutputStream;
    import java.text.ParseException;
    import java.text.SimpleDateFormat;
    import java.util.Date;
    import java.util.Set;
    import javax.activation.DataHandler;
    import javax.activation.FileDataSource;
    import javax.annotation.Resource;
    import javax.jws.WebService;
    import javax.xml.ws.WebServiceContext;
    import javax.xml.ws.handler.MessageContext;
    
    @WebService(serviceName="HelloService",portName="HelloServicePort",targetNamespace="http://service.why.com/",endpointInterface="com.why.server.Hello")
    public class HelloImpl implements Hello {
        
        @Resource
        private WebServiceContext context;
        
        @Override
        public void printContext(){
            MessageContext ctx = context.getMessageContext();
            Set<String> set = ctx.keySet();
            for (String key : set) {
                System.out.println("{" + key + "," + ctx.get(key) +"}");
                try {
                    System.out.println("key.scope=" + ctx.getScope(key));
                } catch (Exception e) {
                    System.out.println(key + " is not exits");
                }
            }
        }
        
        @Override
        public Customer selectCustomerByName(Customer customer) {
            if("why".equals(customer.getName())){
                customer.setId(1);
                try {
                    customer.setBirthday(new SimpleDateFormat("yyyy-MM-dd").parse("1985-10-07"));
                } catch (ParseException e) {
                    e.printStackTrace();
                }
                customer.setImageData(new DataHandler(new FileDataSource(new File("c:"+ File.separator + "why.jpg"))));
            }else{
                customer.setId(2);
                customer.setBirthday(new Date());
                customer.setImageData(new DataHandler(new FileDataSource(new File("c:"+ File.separator + "origin.jpg"))));
            }
            return customer;
        }
        
        @Override
        public Customer selectMaxAgeCustomer(Customer c1, Customer c2) {
            try {
                // 输出接收到的附件
                System.out.println("c1.getImageData().getContentType()=" + c1.getImageData().getContentType());
                InputStream is = c2.getImageData().getInputStream();
                OutputStream os = new FileOutputStream("c:\temp1.jpg");
                byte[] bytes = new byte[1024];
                int c;
                while ((c = is.read(bytes)) != -1) {
                    os.write(bytes, 0, c);
                }
                os.close();
                
                System.out.println("c2.getImageData().getContentType()=" + c2.getImageData().getContentType());
                is = c2.getImageData().getInputStream();
                os = new FileOutputStream("c:\temp2.jpg");
                bytes = new byte[1024];
                while ((c = is.read(bytes)) != -1) {
                    os.write(bytes, 0, c);
                }
                os.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            
            if (c1.getBirthday().getTime() > c2.getBirthday().getTime()){
                return c2;
            }
            else{
                return c1;
            }
        }
    }

        @WebService注解的serviceName属性指定wsdl中service节点的name属性值。portName属性指定wsdl中service节点下port节点name属性值。targetNamespace属性指定wsdl根节点definitions的targetNamespace属性值。endpointInterface属性指定要发布的WebService接口的全路径名,当实现类实现了多个接口时,需要通过此属性标注哪个类是WebService的服务端点接口(SEI)。

        在这个类中,通过@Resource注解注入了一个WebServiceContext对象,这个对象即是WebService的上下文环境。

    发布这个服务:

    package com.why.server;
    
    import javax.xml.ws.Endpoint;
    
    public class SoapServer {
        public static void main(String[] args) {
            Endpoint.publish("http://localhost:8080/helloService",new HelloImpl());
        }
    }

        在命令行键入“wsimport -p com.why.client -keep http://localhost:8080/helloService?wsdl”生成客户端代码,拷贝到工程相应文件夹里,这时,就可以调用这个服务了:

    package com.why.client;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.OutputStream;
    import java.net.MalformedURLException;
    import java.net.URL;
    import java.text.ParseException;
    import java.text.SimpleDateFormat;
    import java.util.GregorianCalendar;
    import javax.activation.DataHandler;
    import javax.activation.DataSource;
    import javax.activation.FileDataSource;
    import javax.xml.datatype.DatatypeConfigurationException;
    import javax.xml.datatype.DatatypeFactory;
    import javax.xml.namespace.QName;
    
    public class SoapClient {
        public static void main(String[] args) throws ParseException, MalformedURLException {
            QName qName = new QName("http://service.why.com/","HelloService");
            HelloService helloService = new HelloService(new URL("http://127.0.0.1:8080/helloService?wsdl"),qName);
            Hello hello = (Hello) helloService.getPort(Hello.class);
            
            hello.printContext();
            
            System.out.println("---------------------------------------------------");
            
            Customer customer = new Customer();
            customer.setName("why");
            DataSource ds = hello.selectCustomerByName(customer).getImageData().getDataSource();
            String attachmentMimeType = ds.getContentType();
            System.out.println(attachmentMimeType);
            try {
                InputStream is = ds.getInputStream();
                OutputStream os = new FileOutputStream("c:\why_temp.jpg");
                byte[] bytes = new byte[1024];
                int c;
                while ((c = is.read(bytes)) != -1) {
                    os.write(bytes, 0, c);
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
            
            System.out.println("########################################");
            
            Customer c1 = new Customer();
            c1.setId(1);
            c1.setName("why");
            GregorianCalendar calendar = (GregorianCalendar)GregorianCalendar.getInstance();
            calendar.setTime(new SimpleDateFormat("yyyy-MM-dd").parse("1985-10-07"));
            try {
                c1.setBirthday(DatatypeFactory.newInstance().newXMLGregorianCalendar(calendar));
            } catch (DatatypeConfigurationException e) {
                e.printStackTrace();
            }
            c1.setImageData(new DataHandler(new FileDataSource("c:\c1.jpg")));
            
            Customer c2 = new Customer();
            c2.setId(2);
            c2.setName("abc");
            calendar.setTime(new SimpleDateFormat("yyyy-MM-dd").parse("1986-10-07"));
            try {
                c2.setBirthday(DatatypeFactory.newInstance().newXMLGregorianCalendar(calendar));
            } catch (DatatypeConfigurationException e) {
                e.printStackTrace();
            }
            c2.setImageData(new DataHandler(new FileDataSource("c:\c2.jpg")));
            
            Customer c = hello.selectMaxAgeCustomer(c1,c2);
            System.out.println(c.getName());
            
        }
    }

    附件是我的工程,当然运行这个程序,需先在C盘建立几个文件c1.jpg、c2.jpg、origin.jpg和why.jpg。

  • 相关阅读:
    Kafka常用操作备忘
    Spark执行流程(转)
    Spark性能优化总结
    Kafka学习笔记
    vue-简单例子初始化
    解析字符串模板函数
    js的apply 和 call区别
    水平垂直居中
    IE8 div旋转 Matrix,模拟轮播前后翻页按钮
    jsp 自定义标签-SimpleTagSupport 使用笔记
  • 原文地址:https://www.cnblogs.com/dhl-2013/p/3680394.html
Copyright © 2011-2022 走看看