JAVA6開發WebService (二)——JAX-WS例子

上一篇寫了個最簡單的小例子,只是爲了說明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;

/**
 * 
 * @author why
 *
 */
@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;

/**
 * 
 * @author why
 *
 */
@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;

/**
 * 
 * @author why
 *
 */
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;

/**
 * 
 * @author why
 *
 */
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。


轉載自:http://wuhongyu.iteye.com/blog/807836

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章