契约式开发webservice实践之spring-ws+Xmlbeans
1、开发环境
JDK1.4.2.*
Tomcat6.0.*
Spring-2.5.5
Spring-ws-1.5.4
XmlBeans-2.3
2、确定需要请求和应答的xml实例
Request.xml
<?xml version="1.0" encoding="UTF-8"?>
<wl_request xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://footmarktech.com/samples">
<flights>
<flight><segment>PEK-CAN<segment><ticketNo>7841234656</ticketNo></flight>
<flight><segment>PEK-CAN<segment><ticketNo>7841234656</ticketNo></flight>
</flights>
</wl_request>
Response.xml
<?xml version="1.0" encoding="UTF-8"?>
<wl_response xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://footmarktech.com/samples">
<flights>
<flight><segment>PEK-CAN<segment><ticketNo>7841234656</ticketNo></flight>
<flight><segment>PEK-CAN<segment><ticketNo>7841234656</ticketNo></flight>
</flights>
</wl_response>
3、设置XmlBeans环境
设置XMLBEANS_HOME
并将 %XMLBEANS_HOME%/bin增加到path路径中
4、使用xmlbeans tool准备数据契约xsd
根据上一步骤请求和应答的实例xml执行如下命令
inst2xsd -enumerations never Request.xml Response.xml
将生成的schema0.xsd文件命名为 Airline.xsd
将 Airline.xsd放在 ${web-context}/WEB-INF目录下
5、使用xmlbeans tool生成OXM数据映射对象
需要说明的是这些对象是跟Xmlbeans耦合比较紧的,不是POJO
执行如下命令
scomp -out Airline.jar Airline.xsd
6、准备运行时和编译时jar包
<classpathentry kind="lib" path="web/src/context/WEB-INF/lib/acegi-security-1.0.7.jar"/>
<classpathentry kind="lib" path="web/src/context/WEB-INF/lib/activation-1.1.jar"/>
<classpathentry kind="lib" path="web/src/context/WEB-INF/lib/antlr-2.7.7.jar"/>
<classpathentry kind="lib" path="web/src/context/WEB-INF/lib/aopalliance-1.0.jar"/>
<classpathentry kind="lib" path="web/src/context/WEB-INF/lib/axiom-api-1.2.6.jar"/>
<classpathentry kind="lib" path="web/src/context/WEB-INF/lib/axiom-dom-1.2.6.jar"/>
<classpathentry kind="lib" path="web/src/context/WEB-INF/lib/axiom-impl-1.2.6.jar"/>
<classpathentry kind="lib" path="web/src/context/WEB-INF/lib/backport-util-concurrent-3.1.jar"/>
<classpathentry kind="lib" path="web/src/context/WEB-INF/lib/bsf-2.3.0.jar"/>
<classpathentry kind="lib" path="web/src/context/WEB-INF/lib/cglib-nodep-2.1_3.jar"/>
<classpathentry kind="lib" path="web/src/context/WEB-INF/lib/commons-beanutils-1.7.0.jar"/>
<classpathentry kind="lib" path="web/src/context/WEB-INF/lib/commons-codec-1.3.jar"/>
<classpathentry kind="lib" path="web/src/context/WEB-INF/lib/commons-collections-3.2.jar"/>
<classpathentry kind="lib" path="web/src/context/WEB-INF/lib/commons-configuration-1.4.jar"/>
<classpathentry kind="lib" path="web/src/context/WEB-INF/lib/commons-digester-1.8.jar"/>
<classpathentry kind="lib" path="web/src/context/WEB-INF/lib/commons-discovery-0.4.jar"/>
<classpathentry kind="lib" path="web/src/context/WEB-INF/lib/commons-el-1.0.jar"/>
<classpathentry kind="lib" path="web/src/context/WEB-INF/lib/commons-fileupload-1.2.jar"/>
<classpathentry kind="lib" path="web/src/context/WEB-INF/lib/commons-httpclient-3.0.1.jar"/>
<classpathentry kind="lib" path="web/src/context/WEB-INF/lib/commons-io-1.4.jar"/>
<classpathentry kind="lib" path="web/src/context/WEB-INF/lib/commons-lang-2.4.jar"/>
<classpathentry kind="lib" path="web/src/context/WEB-INF/lib/commons-logging-1.1.1.jar"/>
<classpathentry kind="lib" path="web/src/context/WEB-INF/lib/commons-net-1.2.2.jar"/>
<classpathentry kind="lib" path="web/src/context/WEB-INF/lib/commons-pool-1.3.jar"/>
<classpathentry kind="lib" path="web/src/context/WEB-INF/lib/commons-validator-1.3.1.jar"/>
<classpathentry kind="lib" path="web/src/context/WEB-INF/lib/concurrent-1.3.4.jar"/>
<classpathentry kind="lib" path="web/src/context/WEB-INF/lib/dom4j-1.6.1.jar"/>
<classpathentry kind="lib" path="web/src/context/WEB-INF/lib/ehcache-1.2.4.jar"/>
<classpathentry kind="lib" path="web/src/context/WEB-INF/lib/ezmorph-1.0.4.jar"/>
<classpathentry kind="lib" path="web/src/context/WEB-INF/lib/groovy-all-1.5.4.jar"/>
<classpathentry kind="lib" path="web/src/context/WEB-INF/lib/hibernate-3.2.6.ga.jar"/>
<classpathentry kind="lib" path="web/src/context/WEB-INF/lib/hsqldb-1.8.0.7.jar"/>
<classpathentry kind="lib" path="web/src/context/WEB-INF/lib/icu4j-3.4.4.jar"/>
<classpathentry kind="lib" path="web/src/context/WEB-INF/lib/jasypt-1.4.1.jar"/>
<classpathentry kind="lib" path="web/src/context/WEB-INF/lib/javassist-3.6.ga.jar"/>
<classpathentry kind="lib" path="web/src/context/WEB-INF/lib/jaxen-1.1.1.jar"/>
<classpathentry kind="lib" path="web/src/context/WEB-INF/lib/jaxrpc-1.1.jar"/>
<classpathentry kind="lib" path="web/src/context/WEB-INF/lib/jcaptcha-all-1.0-RC6.jar"/>
<classpathentry kind="lib" path="web/src/context/WEB-INF/lib/jcr-1.0.jar"/>
<classpathentry kind="lib" path="web/src/context/WEB-INF/lib/jdom-1.0.jar"/>
<classpathentry kind="lib" path="web/src/context/WEB-INF/lib/json-lib-2.2.1-jdk13.jar"/>
<classpathentry kind="lib" path="web/src/context/WEB-INF/lib/jta-spec1_0_1.jar"/>
<classpathentry kind="lib" path="web/src/context/WEB-INF/lib/log4j-1.2.15.jar"/>
<classpathentry kind="lib" path="web/src/context/WEB-INF/lib/lucene-core-2.2.0.jar"/>
<classpathentry kind="lib" path="web/src/context/WEB-INF/lib/mail-1.4.jar"/>
<classpathentry kind="lib" path="web/src/context/WEB-INF/lib/mysql-connector-java-5.1.5-bin.jar"/>
<classpathentry kind="lib" path="web/src/context/WEB-INF/lib/ognl-2.7.2.jar"/>
<classpathentry kind="lib" path="web/src/context/WEB-INF/lib/oro-2.0.8.jar"/>
<classpathentry kind="lib" path="web/src/context/WEB-INF/lib/oscache-2.4.1.jar"/>
<classpathentry kind="lib" path="web/src/context/WEB-INF/lib/pdfbox-0.6.4.jar"/>
<classpathentry kind="lib" path="web/src/context/WEB-INF/lib/poi-3.0.1-FINAL-20070705.jar"/>
<classpathentry kind="lib" path="web/src/context/WEB-INF/lib/poi-contrib-3.0.1-FINAL-20070705.jar"/>
<classpathentry kind="lib" path="web/src/context/WEB-INF/lib/poi-scratchpad-3.0.1-FINAL-20070705.jar"/>
<classpathentry kind="lib" path="web/src/context/WEB-INF/lib/proxool-0.9.0RC3.jar"/>
<classpathentry kind="lib" path="web/src/context/WEB-INF/lib/serializer-2.7.1.jar"/>
<classpathentry kind="lib" path="web/src/context/WEB-INF/lib/slf4j-api-1.4.3.jar"/>
<classpathentry kind="lib" path="web/src/context/WEB-INF/lib/slf4j-log4j12-1.4.3.jar"/>
<classpathentry kind="lib" path="web/src/context/WEB-INF/lib/spring-2.5.5.jar"/>
<classpathentry kind="lib" path="web/src/context/WEB-INF/lib/stax-api-1.0.1.jar"/>
<classpathentry kind="lib" path="web/src/context/WEB-INF/lib/wsdl4j-1.6.2.jar"/>
<classpathentry kind="lib" path="web/src/context/WEB-INF/lib/wstx-asl-3.2.3.jar"/>
<classpathentry kind="lib" path="web/src/context/WEB-INF/lib/xalan-2.7.1.jar"/>
<classpathentry kind="lib" path="web/src/context/WEB-INF/lib/xercesImpl-2.8.1.jar"/>
<classpathentry kind="lib" path="web/src/context/WEB-INF/lib/xfire-all-1.2.6.jar"/>
<classpathentry kind="lib" path="web/src/context/WEB-INF/lib/xml-apis-1.3.04.jar"/>
<classpathentry kind="lib" path="web/src/context/WEB-INF/lib/xom-1.1.jar"/>
<classpathentry kind="lib" path="web/src/context/WEB-INF/lib/xpp3_min-1.1.3.4.0.jar"/>
<classpathentry kind="lib" path="web/src/context/WEB-INF/lib/xstream-1.2.2.jar"/>
<classpathentry kind="lib" path="web/src/context/WEB-INF/lib/axis-saaj-1.4.jar"/>
<classpathentry kind="lib" path="web/src/context/WEB-INF/lib/axis-1.4.jar"/>
<classpathentry kind="lib" path="web/src/context/WEB-INF/lib/spring-oxm-1.5.4.jar" sourcepath="D:/maven-1.0.2/.maven/repository/springframework/srcs/spring-ws-1.5.4-with-dependencies.zip"/>
<classpathentry kind="lib" path="web/src/context/WEB-INF/lib/spring-webmvc-2.5.5.jar"/>
<classpathentry kind="lib" path="web/src/context/WEB-INF/lib/spring-ws-core-1.5.4.jar" sourcepath="D:/maven-1.0.2/.maven/repository/springframework/srcs/spring-ws-1.5.4-with-dependencies.zip"/>
<classpathentry kind="lib" path="web/src/context/WEB-INF/lib/spring-ws-security-1.5.4.jar"/>
<classpathentry kind="lib" path="web/src/context/WEB-INF/lib/spring-ws-support-1.5.4.jar"/>
<classpathentry kind="lib" path="web/src/context/WEB-INF/lib/spring-xml-1.5.4.jar" sourcepath="D:/maven-1.0.2/.maven/repository/springframework/srcs/spring-ws-1.5.4-with-dependencies.zip"/>
<classpathentry kind="lib" path="web/src/context/WEB-INF/lib/jsr173_1.0_api.jar"/>
<classpathentry kind="lib" path="web/src/context/WEB-INF/lib/resolver.jar"/>
<classpathentry kind="lib" path="web/src/context/WEB-INF/lib/xbean_xpath.jar"/>
<classpathentry kind="lib" path="web/src/context/WEB-INF/lib/xbean.jar"/>
<classpathentry kind="lib" path="web/src/context/WEB-INF/lib/xmlbeans-qname.jar"/>
<classpathentry kind="lib" path="web/src/context/WEB-INF/lib/xmlpublic.jar"/>
<classpathentry kind="lib" path="web/src/context/WEB-INF/lib/Airline.jar"/>
<classpathentry kind="output" path="web/src/context/WEB-INF/classes"/>
Spring-ws1.5.4必须使用springframework2.5版本以上
其对org.springframework.core.io.Resource版本要求较高
必须加入spring-webmvc-2.5.5.jar
org.springframework.web.servlet.FrameworkServlet从2.5版本后被分到spring-webmvc.jar包,并不包含于主spring包内
注,可能有些jar包没有用到
7、书写web.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd">
<web-app>
<display-name>Web</display-name>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<servlet>
<servlet-name>ws-spring-ws</servlet-name>
<servlet-class>org.springframework.ws.transport.http.MessageDispatcherServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>ws-spring-ws</servlet-name>
<url-pattern>/spring-ws/*</url-pattern>
</servlet-mapping>
</web-app>
8、书写业务实现
package demo1;
public class Order {
private String id;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
}
package demo1;
public interface OrderService {
Order getOrder(String id);
}
package demo1;
public class OrderServiceImpl implements OrderService{
public Order getOrder(String id) {
Order order = new Order();
order.setId(id);
return order;
}
}
书写spring配置放在classpath下
applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC
"-//SPRING//DTD BEAN//EN"
"http://www.springframework.org/dtd/spring-beans.dtd">
<beans default-autowire="no" default-lazy-init="false" default-dependency-check="none">
<bean id="orderService" class="demo1.OrderServiceImpl"/>
</beans>
9、书写Spring-ws EndPoint
package demo1;
import org.springframework.oxm.Marshaller;
import org.springframework.ws.server.endpoint.AbstractMarshallingPayloadEndpoint;
import com.footmarktech.samples.WlRequestDocument;
import com.footmarktech.samples.WlResponseDocument;
public class SampleMarshallingEndpoint extends
AbstractMarshallingPayloadEndpoint {
private final OrderService orderService;
public SampleMarshallingEndpoint(OrderService orderService,
Marshaller marshaller) {
super(marshaller);
this.orderService = orderService;
}
protected Object invokeInternal(Object request) throws Exception {
com.footmarktech.samples.WlRequestDocument ab = null;
ab = (WlRequestDocument)request;
//TODO invoke orderService
WlResponseDocument rs = (WlResponseDocument) WlResponseDocument.Factory.newInstance();
rs.addNewWlResponse().addNewFlights().addNewFlight().setTicketNo(ab.getWlRequest().getFlights().getFlightArray(0).getTicketNo());
return rs;
}
}
10、书写ws-spring-ws-servlet.xml
放置于${web-context}/WEB-INF目录下
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">
<bean id="messageFactory" class="org.springframework.ws.soap.axiom.AxiomSoapMessageFactory">
<property name="payloadCaching" value="true"/>
</bean>
<bean id="xmlBeansMarshaller" class="org.springframework.oxm.xmlbeans.XmlBeansMarshaller" />
<bean id="orderEndPoint" class="demo1.SampleMarshallingEndpoint">
<constructor-arg><ref bean="orderService"/></constructor-arg>
<constructor-arg><ref bean="xmlBeansMarshaller"/></constructor-arg>
</bean>
<bean id="payloadMapping" class="org.springframework.ws.server.endpoint.mapping.PayloadRootQNameEndpointMapping">
<property name="defaultEndpoint" ref="orderEndPoint"/>
</bean>
<bean id="echo" class="org.springframework.ws.wsdl.wsdl11.DefaultWsdl11Definition">
<property name="schema">
<bean class="org.springframework.xml.xsd.SimpleXsdSchema">
<property name="xsd" value="/WEB-INF/Airline.xsd"/>
</bean>
</property>
<property name="portTypeName" value="Echo"/>
<property name="locationUri" value="http://localhost:8080/ss1/spring-ws/echo/services"/>
</bean>
</beans>
11、开发客户端
配置applicationContext1.xml放置于 classpath demo1.client包内
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">
<bean id="xmlBeansMarshaller" class="org.springframework.oxm.xmlbeans.XmlBeansMarshaller" />
<bean id="messageFactory" class="org.springframework.ws.soap.axiom.AxiomSoapMessageFactory">
<property name="payloadCaching" value="true"/>
</bean>
<bean id="webServiceTemplate1" class="org.springframework.ws.client.core.WebServiceTemplate">
<constructor-arg ref="messageFactory" />
<property name="marshaller" ref="xmlBeansMarshaller" />
<property name="unmarshaller" ref="xmlBeansMarshaller" />
<property name="messageSender">
<bean class="org.springframework.ws.transport.http.CommonsHttpMessageSender">
<property name="readTimeout" value="0" />
</bean>
</property>
<property name="defaultUri" value="http://localhost:8080/ss1/spring-ws/echo/services" />
</bean>
</beans>
package demo1.client;
import java.io.File;
import java.io.IOException;
import javax.xml.transform.Source;
import org.apache.xmlbeans.XmlException;
import org.apache.xmlbeans.XmlObject;
import org.jdom.JDOMException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.core.io.Resource;
import org.springframework.ws.client.core.WebServiceTemplate;
import org.springframework.ws.client.core.support.WebServiceGatewaySupport;
import org.springframework.xml.transform.ResourceSource;
import org.springframework.xml.transform.StringResult;
import com.footmarktech.smscenter.webservice.SendSMDocument;
import com.footmarktech.smscenter.webservice.SendSMResponseDocument;
import com.footmarktech.samples.WlRequestDocument;
import com.footmarktech.samples.WlResponseDocument;
public class EchoClient {
public static void RequestSpring() {
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext1.xml", EchoClient.class);
WebServiceTemplate webServiceTemplate = (WebServiceTemplate) applicationContext
.getBean("webServiceTemplate1");
WlRequestDocument request = WlRequestDocument.Factory.newInstance();
request.addNewWlRequest().addNewFlights().addNewFlight().setTicketNo(new Long(1231235555).longValue());
WlResponseDocument response = (WlResponseDocument)webServiceTemplate.marshalSendAndReceive(request);
System.out.println(response.getWlResponse().getFlights().getFlightArray(0).getTicketNo());
}
public static void main(String[] args) throws IOException, JDOMException {
RequestSpring();
}
}
12、参考资料
http://xmlbeans.apache.org/
http://static.springframework.org/spring-ws/sites/1.5/reference/html/index.html
http://mdasgin.blogspot.com/2008/06/web-servisleri-bir-makinede-sunulan.html
http://www.infoq.com/cn/articles/arjen-poutsma-spring-ws
http://www.infoq.com/cn/articles/sosnoski-code-first
下载pdf版文档