天天看點

基于JAX-WS的Web Service服務端/用戶端

JAX-WS簡介:

JAX_RPC(Java API for XML-Based RPC)允許Java應用程式可以通過已知的描述資訊調用一個基于Java的Web服務,描述資訊與Web服務的WSDL描述相一緻

JAX-RPC2.0更名為JAX-WS2.0(Java API for XML-Based Web Services)

JAX-WS中,一個遠端調用可以轉換為一個基于XML的協定,如SOAP。開發者在使用JAX-WS的過程中,不需要編寫任何生成、處理SOAP消息的代碼,JAX-WS在運作時自動将API的調用轉換為相應的SOAP消息

在伺服器端,使用者隻需要通過Java語言定義遠端調用所需實作的接口,并提供相應實作,通過調用JAX-WS的服務釋出接口即可将其釋出為WebService接口

在用戶端,使用者可以通過JAX-WS的API建立一個代理來實作對于遠端伺服器端的調用

JAX-WS服務端:

JAX-WS服務端采用注釋描述WebService,不再依賴WebService描述檔案

使用JDK1.6_45(JDK1.5中不包含所需類)

package com.sean.server;

import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebService;

@WebService
public interface Plus {
	
	@WebMethod
	public int plus(@WebParam(name="x") int x,@WebParam(name="y") int y);
}
           
package com.sean.server;

import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebService;

@WebService
public class PlusImpl implements Plus {
	
	@WebMethod
	public int plus(@WebParam(name="x") int x, @WebParam(name="y") int y) {
		return x + y;
	}
}
           
package com.sean.server;

import javax.xml.ws.Endpoint;

public class Server {
	public static void main(String[] args) {
		PlusImpl plus = new PlusImpl();
		String addr = "http://127.0.0.1:8888/Plus";
		Endpoint.publish(addr, plus);
	}
}
           

程式啟動後,通路http://127.0.0.1:8888/Plus?wsdl即可檢視自動生成的WSDL檔案

<?xml version="1.0" encoding="UTF-8"?>
<!-- Published by JAX-WS RI at http://jax-ws.dev.java.net. RI's version is 
	JAX-WS RI 2.1.6 in JDK 6. -->
<!-- Generated by JAX-WS RI at http://jax-ws.dev.java.net. RI's version is 
	JAX-WS RI 2.1.6 in JDK 6. -->
<definitions name="PlusImplService" targetNamespace="http://server.sean.com/"
	xmlns="http://schemas.xmlsoap.org/wsdl/" xmlns:xsd="http://www.w3.org/2001/XMLSchema"
	xmlns:tns="http://server.sean.com/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/">
	<types>
		<xsd:schema>
			<xsd:import schemaLocation="http://127.0.0.1:8888/Plus?xsd=1"
				namespace="http://server.sean.com/" />
		</xsd:schema>
	</types>
	<message name="plus">
		<part name="parameters" element="tns:plus" />
	</message>
	<message name="plusResponse">
		<part name="parameters" element="tns:plusResponse" />
	</message>
	<portType name="PlusImpl">
		<operation name="plus">
			<input message="tns:plus" />
			<output message="tns:plusResponse" />
		</operation>
	</portType>
	<binding name="PlusImplPortBinding" type="tns:PlusImpl">
		<soap:binding style="document"
			transport="http://schemas.xmlsoap.org/soap/http" />
		<operation name="plus">
			<soap:operation soapAction="" />
			<input>
				<soap:body use="literal" />
			</input>
			<output>
				<soap:body use="literal" />
			</output>
		</operation>
	</binding>
	<service name="PlusImplService">
		<port name="PlusImplPort" binding="tns:PlusImplPortBinding">
			<soap:address location="http://127.0.0.1:8888/Plus" />
		</port>
	</service>
</definitions>
           

使用 SoapUI5.0.0嘗試用上面的WSDL建立WebService服務端報錯(org.apache.xmlbeans.XmlException:error:does not close tag.)

使用SoapUI4.5.2則一切正常,隻能歸咎于不同版本的SoapUI對檔案格式校驗不同

JAX-WS用戶端:

package com.sean.client;

import java.net.URL;

import javax.xml.namespace.QName;
import javax.xml.ws.Service;

import com.sean.server.Plus;

public class Client {
	public static void main(String[] args) throws Exception {
		QName serviceName = new QName("http://server.sean.com/", "PlusImplService");
		QName portName = new QName("http://server.sean.com/", "PlusImplPort");
		
		String addr = "http://127.0.0.1:8888/Plus?wsdl";
		URL url = new URL(addr);
		
		Service service = Service.create(url, serviceName);
		Plus plus = service.getPort(portName,Plus.class);
		//Plus plus = service.getPort(Plus.class);
		
		int result = plus.plus(1, 2);
		System.out.println("result:" + result);
	}
}
           

使用Plus plus = service.getPort(Plus.class)方法時,用戶端調用時報錯:

Exception in thread "main" javax.xml.ws.WebServiceException: Undefined port type: {http://server.sean.com/}Plus
           

解決方式一:

如用戶端示例,将Plus plus = service.getPort(Plus.class)修改為Plus plus = service.getPort(portName,Plus.class)

解決方式二:

修改PlusImpl類的@WebService标記修改為@WebService(endpointInter)

參考:http://stackoverflow.com/questions/13417454/javax-xml-ws-webserviceexception-undefined-port-type-java-struts-soap-wsdl 

繼續閱讀