分類  >  Web前端 >

(4)CXF基於契約優先實現webservice

tags:    時間:2013-12-10 00:33:30
(四)CXF基於契約優先實現webservice

基於契約優先編寫CXF的webservice

wsdl中增加HEADER,傳遞一個User對象

使用註解添加Interceptor

 

第一步:編寫xsd

<?xml version="1.0" encoding="UTF-8"?> <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"  	    targetNamespace="http://www.example.org/cal"  	    xmlns:tns="http://www.example.org/cal"  	    elementFormDefault="unqualified"> 	     	 <xsd:element name="add" type="tns:add"/> 	 <xsd:element name="addResponse" type="tns:addResponse"/> 	 <!-- 頭信息 --> 	 <xsd:element name="license" type="tns:user"></xsd:element> 	  	 <xsd:complexType name="add"> 	 	<xsd:sequence> 	 		<xsd:element name="num1" type="xsd:int"/> 	 		<xsd:element name="num2" type="xsd:int"/> 	 	</xsd:sequence> 	 </xsd:complexType> 	  	 <xsd:complexType name="addResponse"> 	 	<xsd:sequence> 	 		<xsd:element name="result" type="xsd:long"/> 	 	</xsd:sequence> 	 </xsd:complexType> 	  	 <xsd:complexType name="user"> 	 	<xsd:sequence> 	 		<xsd:element name="name" type="xsd:string"/> 	 		<xsd:element name="pwd" type="xsd:string"/> 	 	</xsd:sequence> 	 </xsd:complexType> 	  </xsd:schema>

 

 

 

第二步,編寫wsdl

<?xml version="1.0" encoding="UTF-8" standalone="no"?> <wsdl:definitions xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"  				  xmlns:tns="http://www.example.org/cal"  				  xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"  				  xmlns:xsd="http://www.w3.org/2001/XMLSchema"  				  name="CalWsService" targetNamespace="http://www.example.org/cal">   <wsdl:types>     <xsd:schema targetNamespace="http://www.example.org/cal">      	<xsd:include schemaLocation="cal.xsd"></xsd:include>     </xsd:schema>   </wsdl:types>      <!-- 頭信息 -->   <wsdl:message name="license">   	<wsdl:part name="license" element="tns:license"></wsdl:part>   </wsdl:message>      <wsdl:message name="add">     <wsdl:part element="tns:add" name="parameters"/>   </wsdl:message>   <wsdl:message name="addResponse">     <wsdl:part element="tns:addResponse" name="parameters"/>   </wsdl:message>      <wsdl:portType name="ICalService">     <wsdl:operation name="add">       <wsdl:input message="tns:add"/>       <wsdl:output message="tns:addResponse"/>     </wsdl:operation>   </wsdl:portType>      <wsdl:binding name="calSOAP" type="tns:ICalService">     <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>     <wsdl:operation name="add">       <wsdl:input>         <soap:body use="literal"/>         <!-- header -->         <soap:header use="literal" part="license" message="tns:license"></soap:header>       </wsdl:input>       <wsdl:output>         <soap:body use="literal"/>       </wsdl:output>     </wsdl:operation>   </wsdl:binding>      <wsdl:service name="CalWsService">     <wsdl:port binding="tns:calSOAP" name="calSOAPPart">       <soap:address location="http://localhost:8888/cxf/ws"/>     </wsdl:port>   </wsdl:service> </wsdl:definitions> 

 

 

 

第三步:將wsdl通過CXF的wsdl2java命令轉換為本地java文件(只要介面即可)

POM.xml中增加wsdl2java的插件命令

<build> 		<plugins> 			<plugin> 				<groupId>org.apache.cxf</groupId> 				<artifactId>cxf-codegen-plugin</artifactId> 				<version>${cxf.version}</version> 				<executions> 					<execution> 						<id>generate-sources</id> 						<phase>compile</phase> 						<configuration> 							<sourceRoot>${project.build.directory}/generated/cxf</sourceRoot> 							<wsdlOptions> 								<wsdlOption>                                                                         <!-- 本地wsdl文件地址 --> 									<wsdl>src/main/resources/META-INF/wsdl/cal.wsdl</wsdl> 								</wsdlOption> 							</wsdlOptions> 						</configuration> 						<goals> 							<goal>wsdl2java</goal> 						</goals> 					</execution> 				</executions> 			</plugin> 		</plugins> 	</build>

 

模型

package com.hqh.ws.cxf.model;  public class User { 	private String name; 	private String pwd; 	 	 	public User() { 		super(); 	} 	public User(String name, String pwd) { 		super(); 		this.name = name; 		this.pwd = pwd; 	} 	public String getName() { 		return name; 	} 	public void setName(String name) { 		this.name = name; 	} 	public String getPwd() { 		return pwd; 	} 	public void setPwd(String pwd) { 		this.pwd = pwd; 	} 	@Override 	public String toString() { 		return "User [name=" + name + ", pwd=" + pwd + "]"; 	} 	 } 

 

 

 

刪除介面中的@XmlSeeAlso({ObjectFactory.class})和註解中定義的class屬性

在add()上手動加入頭信息 @WebParam(name="license", header=true) User user

 

package org.example.cal;  import javax.jws.WebMethod; import javax.jws.WebParam; import javax.jws.WebResult; import javax.jws.WebService; import javax.xml.ws.RequestWrapper; import javax.xml.ws.ResponseWrapper;  import com.hqh.ws.cxf.model.User;  /**  * This class was generated by Apache CXF 2.6.0  * 2013-08-17T11:29:27.810+08:00  * Generated source version: 2.6.0  *   */ @WebService(targetNamespace = "http://www.example.org/cal", name = "ICalService") public interface ICalService {      @WebResult(name = "result", targetNamespace = "")     @RequestWrapper(localName = "add", targetNamespace = "http://www.example.org/cal")     @WebMethod     @ResponseWrapper(localName = "addResponse", targetNamespace = "http://www.example.org/cal")     public long add(         @WebParam(name = "num1", targetNamespace = "")         int num1,         @WebParam(name = "num2", targetNamespace = "")         int num2,         //手動增加頭信息         @WebParam(name="license", header=true)         User user     ); } 

 

 

 

編寫實現類

package org.example.cal;  import javax.jws.WebService;  import com.hqh.ws.cxf.model.User;  @WebService(endpointInterface="org.example.cal.ICalService", 			serviceName="CalWsService", 			portName="calSOAPPart", 			targetNamespace="http://www.example.org/cal") public class CalServiceImpl implements ICalService {  	@Override 	public long add(int num1, int num2, User license) { 		//列印licenseInfo 		System.out.println(license); 		 		long result = num1 + num2; 		System.out.println(num1+"+"+num2+"="+result); 		return result; 	}  } 

 

 

 

使用CXF發布服務

package org.example.cal;  import javax.xml.namespace.QName;  import org.apache.cxf.jaxws.JaxWsServerFactoryBean;  public class MyCXFServer { 	public static void main(String[] args) { 		JaxWsServerFactoryBean svrFactory = new JaxWsServerFactoryBean(); 		 		svrFactory.setAddress("http://localhost:8888/cxf/ws"); 		svrFactory.setServiceClass(ICalService.class); 		svrFactory.setServiceBean(new CalServiceImpl()); 		 		//必須顯示定義WsdlLocation和ServiceName才能基於契約優先來發布webservice 		svrFactory.setWsdlLocation("src/main/resources/META-INF/wsdl/cal.wsdl"); 		svrFactory.setServiceName(new QName("http://www.example.org/cal","CalWsService")); 		 		//開啟服務 		svrFactory.create(); 	} } 

 

客戶端通過公布的wsdl的URL,使用wsdl2java轉換為本地java文件

pom.xml中增加wsdl2java插件

<build> 		<plugins> 			<plugin> 				<groupId>org.apache.cxf</groupId> 				<artifactId>cxf-codegen-plugin</artifactId> 				<version>${cxf.version}</version> 				<executions> 					<execution> 						<id>generate-sources</id> 						<phase>compile</phase> 						<configuration> 							<sourceRoot>${project.build.directory}/generated/cxf</sourceRoot> 							<wsdlOptions> 								<wsdlOption>                                                                 <!-- 網路wsdl文件地址 --> 									<wsdl>http://localhost:8888/cxf/ws?wsdl</wsdl> 								</wsdlOption> 							</wsdlOptions> 						</configuration> 						<goals> 							<goal>wsdl2java</goal> 						</goals> 					</execution> 				</executions> 			</plugin> 		</plugins> 	</build>

編寫攔截器

package com.hqh.ws.cxf.interceptor;  import java.util.List;  import javax.xml.bind.JAXBException; import javax.xml.namespace.QName;  import org.apache.cxf.binding.soap.SoapMessage; import org.apache.cxf.binding.soap.interceptor.AbstractSoapInterceptor; import org.apache.cxf.databinding.DataBinding; import org.apache.cxf.headers.Header; import org.apache.cxf.interceptor.Fault; import org.apache.cxf.jaxb.JAXBDataBinding; import org.apache.cxf.phase.Phase;  import com.hqh.ws.cxf.model.User;  public class LicenseOutInterceptorNew extends AbstractSoapInterceptor{ 	/** 	 * 指定加入攔截器到某個階段 	 * @param p 	 */ 	public LicenseOutInterceptorNew() { 		super(Phase.WRITE); 	}  	@Override 	public void handleMessage(SoapMessage message) throws Fault { 		List<Header> headers = message.getHeaders(); 		System.out.println("headers.size:"+headers.size()); 		try { 			//創建QName 			String namespaceURI = "http://www.example.org/cal"; 			String localPart = "license"; 			String prefix = "ns"; 			QName qname = new QName(namespaceURI, localPart, prefix);  			//頭信息為一個對象 			User user = new User("root","root123"); 			 			//創建DataBinding 			DataBinding dataBinding = new JAXBDataBinding(User.class); 			 			//創建Header 			Header header = new Header(qname, user, dataBinding); 			 			//將header加入到SOAP頭集合中 			headers.add(header); 		} catch (JAXBException e) { 			e.printStackTrace(); 			throw new Fault(e); 		} 		 	}  } 

 

在客戶端的服務介面上使用註解加入攔截器

package org.example.cal;  import javax.jws.WebMethod; import javax.jws.WebParam; import javax.jws.WebResult; import javax.jws.WebService; import javax.xml.bind.annotation.XmlSeeAlso; import javax.xml.ws.RequestWrapper; import javax.xml.ws.ResponseWrapper;  import org.apache.cxf.interceptor.InInterceptors; import org.apache.cxf.interceptor.OutInterceptors;  /**  * This class was generated by Apache CXF 2.6.0  * 2013-08-17T12:22:32.760+08:00  * Generated source version: 2.6.0  *   */ @WebService(targetNamespace = "http://www.example.org/cal", name = "ICalService") @XmlSeeAlso({ObjectFactory.class}) //將LicenseOutInterceptorNew加入到out攔截器鏈中 @OutInterceptors (interceptors = {"com.hqh.ws.cxf.interceptor.LicenseOutInterceptorNew" }) public interface ICalService {      @WebResult(name = "result", targetNamespace = "")     @RequestWrapper(localName = "add", targetNamespace = "http://www.example.org/cal", className = "org.example.cal.Add")     @WebMethod     @ResponseWrapper(localName = "addResponse", targetNamespace = "http://www.example.org/cal", className = "org.example.cal.AddResponse")     public long add(         @WebParam(name = "num1", targetNamespace = "")         int num1,         @WebParam(name = "num2", targetNamespace = "")         int num2     ); } 

 

調用服務端提供的服務

	/** 	 * 基於契約優先的CXF webservice調用 	 */ 	@Test 	public void test04() { //		ICalService service = new CalWsService().getCalSOAPPart(); //		long ret = service.add(1, 11); //		System.out.println(ret); 		 		JaxWsProxyFactoryBean factory = new JaxWsProxyFactoryBean(); 		factory.setAddress("http://localhost:8888/cxf/ws?wsdl"); 		factory.setServiceClass(ICalService.class); 		ICalService service = (ICalService)factory.create(); 		long ret = service.add(11, 1); 		System.out.println(ret); 	}

 

客戶端發出的消息與接收到的返回值:

<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"> 	<soap:Header> 		<ns:license xmlns:ns="http://www.example.org/cal"> 			<name>root</name> 			<pwd>root123</pwd> 		</ns:license> 	</soap:Header> 	<soap:Body> 		<ns2:add xmlns:ns2="http://www.example.org/cal"> 			<num1>11</num1> 			<num2>1</num2> 		</ns2:add> 	</soap:Body> </soap:Envelope>

 

-------------------------------------- 12

 

 

 

服務端處理結果:

User [name=root, pwd=root123] 11+1=12

 

 

 

 

 

推薦閱讀文章

Bookmark the permalink ,來源:互聯網