JAVA开发WebService (二)——JAX-WS例子

 

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

 

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

 

先来看Customer类:

 

Java代码   收藏代码
  1. package com.why.server;  
  2.   
  3. import java.util.Date;  
  4.   
  5. import javax.activation.DataHandler;  
  6. import javax.xml.bind.annotation.XmlAccessType;  
  7. import javax.xml.bind.annotation.XmlAccessorType;  
  8. import javax.xml.bind.annotation.XmlMimeType;  
  9. import javax.xml.bind.annotation.XmlRootElement;  
  10.   
  11. @XmlRootElement(name = "Customer")  
  12. @XmlAccessorType(XmlAccessType.FIELD)  
  13. public class Customer {  
  14.     private long id;  
  15.     private String name;  
  16.     private Date birthday;  
  17.     @XmlMimeType("application/octet-stream")  
  18.     private DataHandler imageData;  
  19.       
  20.         //getter and setter  
  21.         ......  
  22. }  

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

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

 

接口类:

Java代码   收藏代码
  1. package com.why.server;  
  2.   
  3. import javax.jws.WebParam;  
  4. import javax.jws.WebService;  
  5. import javax.xml.ws.soap.MTOM;  
  6.   
  7. /** 
  8.  *  
  9.  * @author why 
  10.  * 
  11.  */  
  12. @WebService(name="Hello")  
  13. @SOAPBinding(style = SOAPBinding.Style.RPC)  
  14. @MTOM  
  15. public interface Hello {  
  16.     public void printContext();  
  17.     public Customer selectCustomerByName(@WebParam(name = "customer")Customer customer);  
  18.     public Customer selectMaxAgeCustomer(Customer c1, Customer c2);  
  19. }  

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

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

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

 

实现类:

Java代码   收藏代码
  1. package com.why.server;  
  2.   
  3. import java.io.File;  
  4. import java.io.FileOutputStream;  
  5. import java.io.IOException;  
  6. import java.io.InputStream;  
  7. import java.io.OutputStream;  
  8. import java.text.ParseException;  
  9. import java.text.SimpleDateFormat;  
  10. import java.util.Date;  
  11. import java.util.Set;  
  12. import javax.activation.DataHandler;  
  13. import javax.activation.FileDataSource;  
  14. import javax.annotation.Resource;  
  15. import javax.jws.WebService;  
  16. import javax.xml.ws.WebServiceContext;  
  17. import javax.xml.ws.handler.MessageContext;  
  18.   
  19. /** 
  20.  *  
  21.  * @author why 
  22.  * 
  23.  */  
  24. @WebService(serviceName="HelloService",portName="HelloServicePort",targetNamespace="http://service.why.com/",endpointInterface="com.why.server.Hello")  
  25. public class HelloImpl implements Hello {  
  26.       
  27.     @Resource  
  28.     private WebServiceContext context;  
  29.       
  30.     @Override  
  31.     public void printContext(){  
  32.         MessageContext ctx = context.getMessageContext();  
  33.         Set<String> set = ctx.keySet();  
  34.         for (String key : set) {  
  35.             System.out.println("{" + key + "," + ctx.get(key) +"}");  
  36.             try {  
  37.                 System.out.println("key.scope=" + ctx.getScope(key));  
  38.             } catch (Exception e) {  
  39.                 System.out.println(key + " is not exits");  
  40.             }  
  41.         }  
  42.     }  
  43.       
  44.     @Override  
  45.     public Customer selectCustomerByName(Customer customer) {  
  46.         if("why".equals(customer.getName())){  
  47.             customer.setId(1);  
  48.             try {  
  49.                 customer.setBirthday(new SimpleDateFormat("yyyy-MM-dd").parse("1985-10-07"));  
  50.             } catch (ParseException e) {  
  51.                 e.printStackTrace();  
  52.             }  
  53.             customer.setImageData(new DataHandler(new FileDataSource(new File("c:"+ File.separator + "why.jpg"))));  
  54.         }else{  
  55.             customer.setId(2);  
  56.             customer.setBirthday(new Date());  
  57.             customer.setImageData(new DataHandler(new FileDataSource(new File("c:"+ File.separator + "origin.jpg"))));  
  58.         }  
  59.         return customer;  
  60.     }  
  61.       
  62.     @Override  
  63.     public Customer selectMaxAgeCustomer(Customer c1, Customer c2) {  
  64.         try {  
  65.             // 输出接收到的附件  
  66.             System.out.println("c1.getImageData().getContentType()=" + c1.getImageData().getContentType());  
  67.             InputStream is = c2.getImageData().getInputStream();  
  68.             OutputStream os = new FileOutputStream("c:\\temp1.jpg");  
  69.             byte[] bytes = new byte[1024];  
  70.             int c;  
  71.             while ((c = is.read(bytes)) != -1) {  
  72.                 os.write(bytes, 0, c);  
  73.             }  
  74.             os.close();  
  75.               
  76.             System.out.println("c2.getImageData().getContentType()=" + c2.getImageData().getContentType());  
  77.             is = c2.getImageData().getInputStream();  
  78.             os = new FileOutputStream("c:\\temp2.jpg");  
  79.             bytes = new byte[1024];  
  80.             while ((c = is.read(bytes)) != -1) {  
  81.                 os.write(bytes, 0, c);  
  82.             }  
  83.             os.close();  
  84.         } catch (IOException e) {  
  85.             e.printStackTrace();  
  86.         }  
  87.           
  88.         if (c1.getBirthday().getTime() > c2.getBirthday().getTime()){  
  89.             return c2;  
  90.         }  
  91.         else{  
  92.             return c1;  
  93.         }  
  94.     }  
  95. }  

 

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

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

 

发布这个服务:

Java代码   收藏代码
  1. package com.why.server;  
  2.   
  3. import javax.xml.ws.Endpoint;  
  4.   
  5. /** 
  6.  *  
  7.  * @author why 
  8.  * 
  9.  */  
  10. public class SoapServer {  
  11.     public static void main(String[] args) {  
  12.         Endpoint.publish("http://localhost:8080/helloService",new HelloImpl());  
  13.     }  
  14. }  

 

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

Java代码   收藏代码
  1. package com.why.client;  
  2. import java.io.FileOutputStream;  
  3. import java.io.IOException;  
  4. import java.io.InputStream;  
  5. import java.io.OutputStream;  
  6. import java.net.MalformedURLException;  
  7. import java.net.URL;  
  8. import java.text.ParseException;  
  9. import java.text.SimpleDateFormat;  
  10. import java.util.GregorianCalendar;  
  11. import javax.activation.DataHandler;  
  12. import javax.activation.DataSource;  
  13. import javax.activation.FileDataSource;  
  14. import javax.xml.datatype.DatatypeConfigurationException;  
  15. import javax.xml.datatype.DatatypeFactory;  
  16. import javax.xml.namespace.QName;  
  17.   
  18. /** 
  19.  *  
  20.  * @author why 
  21.  * 
  22.  */  
  23. public class SoapClient {  
  24.     public static void main(String[] args) throws ParseException, MalformedURLException {  
  25.         QName qName = new QName("http://service.why.com/","HelloService");  
  26.         HelloService helloService = new HelloService(new URL("http://127.0.0.1:8080/helloService?wsdl"),qName);  
  27.         Hello hello = (Hello) helloService.getPort(Hello.class);  
  28.           
  29.         hello.printContext();  
  30.           
  31.         System.out.println("---------------------------------------------------");  
  32.           
  33.         Customer customer = new Customer();  
  34.         customer.setName("why");  
  35.         DataSource ds = hello.selectCustomerByName(customer).getImageData().getDataSource();  
  36.         String attachmentMimeType = ds.getContentType();  
  37.         System.out.println(attachmentMimeType);  
  38.         try {  
  39.             InputStream is = ds.getInputStream();  
  40.             OutputStream os = new FileOutputStream("c:\\why_temp.jpg");  
  41.             byte[] bytes = new byte[1024];  
  42.             int c;  
  43.             while ((c = is.read(bytes)) != -1) {  
  44.                 os.write(bytes, 0, c);  
  45.             }  
  46.         } catch (IOException e) {  
  47.             e.printStackTrace();  
  48.         }  
  49.           
  50.         System.out.println("########################################");  
  51.           
  52.         Customer c1 = new Customer();  
  53.         c1.setId(1);  
  54.         c1.setName("why");  
  55.         GregorianCalendar calendar = (GregorianCalendar)GregorianCalendar.getInstance();  
  56.         calendar.setTime(new SimpleDateFormat("yyyy-MM-dd").parse("1985-10-07"));  
  57.         try {  
  58.             c1.setBirthday(DatatypeFactory.newInstance().newXMLGregorianCalendar(calendar));  
  59.         } catch (DatatypeConfigurationException e) {  
  60.             e.printStackTrace();  
  61.         }  
  62.         c1.setImageData(new DataHandler(new FileDataSource("c:\\c1.jpg")));  
  63.           
  64.         Customer c2 = new Customer();  
  65.         c2.setId(2);  
  66.         c2.setName("abc");  
  67.         calendar.setTime(new SimpleDateFormat("yyyy-MM-dd").parse("1986-10-07"));  
  68.         try {  
  69.             c2.setBirthday(DatatypeFactory.newInstance().newXMLGregorianCalendar(calendar));  
  70.         } catch (DatatypeConfigurationException e) {  
  71.             e.printStackTrace();  
  72.         }  
  73.         c2.setImageData(new DataHandler(new FileDataSource("c:\\c2.jpg")));  
  74.           
  75.         Customer c = hello.selectMaxAgeCustomer(c1,c2);  
  76.         System.out.println(c.getName());  
  77.           
  78.     }  
  79. }  

 

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

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值