spring -ws是基于契約先行(contract first)的原則實現(xiàn)的web service。
自從JDK1.5的annotation出現(xiàn)以后,我偏向于寫注解而不寫xml,所以我在項目中盡量寫注解來替代xml
閑話少說。動手做。
必備包:spring.jar ; spring-ws-1.5.8-all.jar ; wsdl4j-1.6.1.jar ; spring-mvc-2.5.6.jar;
XmlSchema-1.4.3.jar ; commons-logging-1.1.1.jar
spring-ws是契約先行,先寫wsdl文件的內容,然后生成所需要的java類。
而wsdl是由包含請求和返回以及數(shù)據(jù)xsd文件,使用spring-ws生成的。
這里演示一個簡單的spring-ws
一個人客戶端輸入自己的卡號,返回這個人的所有信息。
xsd文件(workerInfo.xsd)
<?xml version="1.0" encoding="UTF-8"?>
< xs:schema xmlns:xs="http://www./2001/XMLSchema"
xmlns:tns="http:///schemas/workerinfo"
elementFormDefault="qualified"
targetNamespace="http:///schemas/workerinfo">
<!--查詢請求,輸入的是一個字符串的證件號碼CardNo-->
<xs:element name="WorkerRequest">
<xs:complexType>
<xs:all>
<xs:element name="CardNo" type="xs:string" />
</xs:all>
</xs:complexType>
</xs:element>
<!--數(shù)據(jù)返回,返回的是一個WorkerInfo數(shù)據(jù)類型-->
<xs:element name="WorkerResponse">
<xs:complexType>
<xs:all>
<xs:element name="WorkerResponse" type="tns:WorkerInfo" />
</xs:all>
</xs:complexType>
</xs:element>
<!--WorkerInfo數(shù)據(jù)類型其實就是一個Java類,由下面幾個屬性組成-->
<xs:complexType name="WorkerInfo">
<xs:sequence>
<xs:element name="id" type="xs:long"></xs:element>
<xs:element name="cardNo" type="xs:string"></xs:element>
<xs:element name="workerName" type="xs:string"></xs:element>
<xs:element name="workerSex" type="xs:string"></xs:element>
</xs:sequence>
</xs:complexType>
< /xs:schema>
對于spring-ws要配置的地方有
web.xml:
<?xml version="1.0" encoding="UTF-8"?>
< web-app xmlns:xsi="http://www./2001/XMLSchema-instance" xmlns="http://java./xml/ns/javaee" xmlns:web="http://java./xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java./xml/ns/javaee http://java./xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5">
<display-name>ajjws</display-name>
< servlet>
<servlet-name>ajjws</servlet-name>
<servlet-class>org.springframework.ws.transport.http.MessageDispatcherServlet</servlet-class>
<init-param>
<param-name>transformWsdlLocations</param-name>
<param-value>true</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>ajjws</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
</web-app>
ajjws-servlet.xml:(名稱和web.xml的servlet-name相同)
<?xml version="1.0" encoding="UTF-8"?>
< beans xmlns="http://www./schema/beans"
xmlns:xsi="http://www./2001/XMLSchema-instance"
xmlns:context="http://www./schema/context"
xsi:schemaLocation="http://www./schema/beans
http://www./schema/beans/spring-beans-2.5.xsd
http://www./schema/context http://www./schema/context/spring-context-2.5.xsd">
<!--對com.ajjws下的包里的類自動掃描,從而不用定義文件中bean,在類中使用@Service@component等-調用時候使用@Resource或者@AutoWired->
<context:annotation-config/>
<context:component-scan base-package="com.ajjws"/>
<!--指定xsd文件的地址-->
<bean id="schemaCollection" class="org.springframework.xml.xsd.commons.CommonsXsdSchemaCollection">
<property name="xsds">
<list>
<value>/WEB-INF/xsds/workerInfo.xsd</value>
</list>
</property>
<property name="inline" value="true"/>
</bean>
<bean class="org.springframework.ws.server.endpoint.adapter.GenericMarshallingMethodEndpointAdapter">
<constructor-arg ref="marshaller" />
</bean>
<!--利用Jaxb2實現(xiàn)xml到Java的轉換-->
<bean id="marshaller" class="org.springframework.oxm.jaxb.Jaxb2Marshaller">
<property name="contextPath" value="com.ajjws.beans" />
</bean>
<!--申明我們用注解來實現(xiàn)請求和Endpoint的映射對應-->
<bean class="org.springframework.ws.server.endpoint.mapping.PayloadRootAnnotationMethodEndpointMapping"/>
<!--通過xsd文件定義wsdl-->
<bean id="ajjws" class="org.springframework.ws.wsdl.wsdl11.DefaultWsdl11Definition">
<property name="schemaCollection" ref="schemaCollection" />
<property name="portTypeName" value="Ajj" />
<property name="locationUri" value="http://localhost:8080/ajjws/services" />
<property name="targetNamespace" value="http:///definitions" />
</bean>
< /beans>
安裝jaxb eclipse插件,在xsd文件上點右鍵,選擇jaxb2.1->run xjc

運行后會在com.ajjws.bean包下通過xsd文件生成的java類
如下所示:

Endpoint:(AjjwsEndpoint.java 響應web service的請求的文件)
package com.ajjws.ws;
import javax.annotation.Resource;
import org.springframework.ws.server.endpoint.annotation.Endpoint;
import org.springframework.ws.server.endpoint.annotation.PayloadRoot;
import com.ajjws.beans.ObjectFactory;
import com.ajjws.beans.WorkerInfo;
import com.ajjws.beans.WorkerRequest;
import com.ajjws.beans.WorkerResponse;
import com.ajjws.service.AjjService;
/**
* @author wyf
*
*/
@Endpoint
public class AjjwsEndpoint {
@Resource
private AjjService ajjService;//需配置自動掃描bean
@Resource
private ObjectFactory objectFactory;
@PayloadRoot(localPart="WorkerRequest",namespace="http:///schemas/workerinfo")
public WorkerResponse getWorkInfo(WorkerRequest request) {
WorkerResponse response=objectFactory.createWorkerResponse();
WorkerInfo workerInfo=ajjService.getWorkInfo(request.getCardNo());
response.setWorkerResponse(workerInfo);
return response;
}
}
AjjService.java:
package com.ajjws.service;
import com.ajjws.beans.WorkerInfo;
public interface AjjService {
/**
* 獲取證件信息
*/
public WorkerInfo getWorkInfo(String cardNo);
}
AjjServiceImpl.java
package com.ajjws.service;
import org.springframework.stereotype.Service;
import com.ajjws.beans.WorkerInfo;
/**
* @author wyf
*
*/
@Service("ajjService")
public class AjjServiceImpl implements AjjService {
public WorkerInfo getWorkInfo(String cardNo) {
//此處僅為演示,為加入數(shù)據(jù)庫
System.out.println(cardNo);
WorkerInfo worker=new WorkerInfo();
worker.setCardNo("1234");
worker.setId(1);
worker.setWorkerName("wyf");
worker.setWorkerSex("男");
return worker;
}
}
客戶端使用eclipse本身自帶的生成web service client


點擊finish,通過wsdl生成客戶端所需要的Java類
結構如下

客戶端調用代碼:
package com.ajjSearch.web;
import java.rmi.RemoteException;
import org.springframework.ws.client.core.support.WebServiceGatewaySupport;
import com.ajjws.definitions.AjjProxy;
import com.ajjws.schemas.workerinfo.WorkerInfo;
import com.ajjws.schemas.workerinfo.WorkerRequest;
import com.ajjws.schemas.workerinfo.WorkerResponse;
public class WsClient extends WebServiceGatewaySupport{
public static void main(String[] args) throws RemoteException {
doSomething();
}
public static void doSomething() throws RemoteException{
WorkerRequest wreq=new WorkerRequest("1111");
WorkerResponse wres=new AjjProxy().getAjj().worker(wreq);
System.out.println(wres.getWorkerResponse());
WorkerInfo wi=wres.getWorkerResponse();
System.out.println(wi.getCardNo()+" "+wi.getId()+" "+wi.getWorkerName()+" "+wi.getWorkerSex());
}
}