ゞ沉默是金ゞ

鱼离不开水,但是没有说不离开哪滴水.
posts - 98,comments - 104,trackbacks - 0

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

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

先来看Customer类:


package org.duke.jaxws.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;

    
public long getId() {
        
return id;
    }

    
public void setId(long id) {
        
this.id = id;
    }

    
public String getName() {
        
return name;
    }

    
public void setName(String name) {
        
this.name = name;
    }

    
public Date getBirthday() {
        
return birthday;
    }

    
public void setBirthday(Date birthday) {
        
this.birthday = birthday;
    }

    
public DataHandler getImageData() {
        
return imageData;
    }

    
public void setImageData(DataHandler imageData) {
        
this.imageData = imageData;
    }

}

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

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

接口类:


package org.duke.jaxws.server;

import javax.jws.WebParam;
import javax.jws.WebService;
import javax.jws.soap.SOAPBinding;
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 org.duke.jaxws.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 
= "Hello", portName = "HelloPort", targetNamespace = "http://server.jaxws.duke.org/", endpointInterface = "org.duke.jaxws.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 ("duke".equals(customer.getName())) {
            customer.setId(
1);
            
try {
                customer.setBirthday(
new SimpleDateFormat("yyyy-MM-dd")
                        .parse(
"1985-03-14"));
            } 
catch (ParseException e) {
                e.printStackTrace();
            }
            customer.setImageData(
new DataHandler(new FileDataSource(new File(
                    
"c:" + File.separator + "duke.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 org.duke.jaxws.server;

import javax.xml.ws.Endpoint;

public class SoapServer {
    
public static void main(String[] args) {
        Endpoint.publish(
"http://localhost:8080/Service/Hello"new HelloImpl());
    }
}
在命令行键入“wsimport -s src -p org.duke.jaxws.client -keep http://localhost:8080/Service/Hello?wsdl”生成客户端代码,拷贝到工程相应文件夹里,这时,就可以调用这个服务了:

package org.duke.jaxws.test;

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;

import org.duke.jaxws.client.Customer;
import org.duke.jaxws.client.Hello;
import org.duke.jaxws.client.Hello_Service;

public class SoapClient {
    
public static void main(String[] args) throws ParseException,
            MalformedURLException {
        QName qName 
= new QName("http://server.jaxws.duke.org/""Hello");
        Hello_Service helloService 
= new Hello_Service(new URL(
                
"http://localhost:8080/Service/Hello?wsdl"), qName);
        Hello hello 
= (Hello) helloService.getPort(Hello.class);

        hello.printContext();

        System.out.println(
"########################################");

        Customer customer 
= new Customer();
        customer.setName(
"duke");
        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:\\Shawn\\duke-real_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(
"duke");
        GregorianCalendar calendar 
= (GregorianCalendar) GregorianCalendar
                .getInstance();
        calendar.setTime(
new SimpleDateFormat("yyyy-MM-dd").parse("1985-03-14"));
        
try {
            c1.setBirthday(DatatypeFactory.newInstance()
                    .newXMLGregorianCalendar(calendar));
        } 
catch (DatatypeConfigurationException e) {
            e.printStackTrace();
        }
        c1.setImageData(
new DataHandler(new FileDataSource(
                
"c:\\Shawn\\duke1.jpg")));

        Customer c2 
= new Customer();
        c2.setId(
2);
        c2.setName(
"abc");
        calendar.setTime(
new SimpleDateFormat("yyyy-MM-dd").parse("1986-03-14"));
        
try {
            c2.setBirthday(DatatypeFactory.newInstance()
                    .newXMLGregorianCalendar(calendar));
        } 
catch (DatatypeConfigurationException e) {
            e.printStackTrace();
        }
        c2.setImageData(
new DataHandler(new FileDataSource(
                
"c:\\Shawn\\duke-real_temp.jpg")));

        Customer c 
= hello.selectMaxAgeCustomer(c1, c2);
        System.out.println(c.getName());

    }
}




posted on 2012-06-27 14:06 ゞ沉默是金ゞ 阅读(1261) 评论(2)  编辑  收藏 所属分类: webservice

FeedBack:
# re: JAVA6开发WebService (二)——JAX-WS
2012-06-27 15:41 | 路人甲
setBirthday()这边好像有问题哦。  回复  更多评论
  
# re: JAVA6开发WebService (二)——JAX-WS[未登录]
2012-06-27 17:41 | ゞ沉默是金ゞ
@路人甲
什么问题呀  回复  更多评论
  

只有注册用户登录后才能发表评论。


网站导航: