Spring-ws提供SOAP服务的注意事项
2015-11-29 00:18
369 查看
本文在官方例子的基础上,使用JAXB marshall 和 unmarshall 处理 xml数据
依照官方的例子,我们需要处理一个假期的请求,以下是Holiday的xml格式:<Holiday xmlns="http://mycompany.com/hr/schemas"> <StartDate>2006-07-03</StartDate> <EndDate>2006-07-07</EndDate> </Holiday>
以下是Employee的xml格式:
<Employee xmlns="http://mycompany.com/hr/schemas"> <Number>42</Number> <FirstName>Arjen</FirstName> <LastName>Poutsma</LastName> </Employee>
那么一个请求就是下面的xml格式:
<HolidayRequest xmlns="http://mycompany.com/hr/schemas"> <Holiday> <StartDate>2006-07-03</StartDate> <EndDate>2006-07-07</EndDate> </Holiday> <Employee> <Number>42</Number> <FirstName>Arjen</FirstName> <LastName>Poutsma</LastName> </Employee> </HolidayRequest>
我们需要为这个请求定义一个schema文件hr.xsd:
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:hr="http://mycompany.com/hr/schemas" elementFormDefault="qualified" targetNamespace="http://mycompany.com/hr/schemas"> <xs:element name="HolidayRequest"> <xs:complexType> <xs:all> <xs:element name="Holiday" type="hr:HolidayType"/> <xs:element name="Employee" type="hr:EmployeeType"/> </xs:all> </xs:complexType> </xs:element> <xs:complexType name="HolidayType"> <xs:sequence> <xs:element name="StartDate" type="xs:date"/> <xs:element name="EndDate" type="xs:date"/> </xs:sequence> </xs:complexType> <xs:complexType name="EmployeeType"> <xs:sequence> <xs:element name="Number" type="xs:integer"/> <xs:element name="FirstName" type="xs:string"/> <xs:element name="LastName" type="xs:string"/> </xs:sequence> </xs:complexType> </xs:schema>
在web.xml文件中添加处理soap的servlet:
<web-app xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml 4000 /ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd" version="2.4"> <display-name>MyCompany HR Holiday Service</display-name> <!-- take especial notice of the name of this servlet --> <servlet> <servlet-name>spring-ws</servlet-name> <servlet-class>org.springframework.ws.transport.http.MessageDispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:config/spring-ws.xml</param-value> </init-param> <init-param> <param-name>transformWsdlLocations</param-name> <param-value>true</param-value> </init-param> </servlet> <servlet-mapping> <servlet-name>spring-ws</servlet-name> <url-pattern>/ws/*</url-pattern> </servlet-mapping> </web-app>
像SpringMVC有一个配置文件一样,spring-ws.xml是spring-ws的配置文件。这里解释一下MessageDispatcherServlet,Spring-ws的服务端是围绕着这个servlet设计的,这个servlet将收到的xml报文转发到endpoint,这一点跟SpringMVC的DispacherServlet很相似。MessageDispatcherServlet处理请求的转发过程如下图所示。
spring-ws.xml的内容如下。
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:sws="http://www.springframework.org/schema/web-services" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/web-services http://www.springframework.org/schema/web-services/web-services-2.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd"> <context:component-scan base-package="com.chinamobile.cmss.eshub.ssb.wssimulator" /> <sws:annotation-driven /> <sws:dynamic-wsdl id="holiday" portTypeName="HumanResource" locationUri="/ws/holidayService/" targetNamespace="http://mycompany.com/hr/definitions"> <sws:xsd location="classpath:schema/hr.xsd" /> </sws:dynamic-wsdl> </beans>
我们开启自动扫描@Endpoint注解的类。接着定义暴露接口的wsdl路径。
下面开始写Endpoint。
package com.chinamobile.cmss.eshub.ssb.wssimulator.endpoint; import org.springframework.ws.server.endpoint.annotation.Endpoint; import org.springframework.ws.server.endpoint.annotation.PayloadRoot; import org.springframework.ws.server.endpoint.annotation.RequestPayload; import com.chinamobile.cmss.eshub.ssb.wssimulator.entity.HolidayRequest; @Endpoint public class HolidayEndpoint { private static final String NAMESPACE_URI = "http://mycompany.com/hr/schemas"; @PayloadRoot(namespace = NAMESPACE_URI, localPart = "HolidayRequest") public void handleHolidayRequest(@RequestPayload HolidayRequest holidayRequest) throws Exception { System.out.println(holidayRequest.toString()); } }
这里使用了eclipselink的JAXB,项目的pom.xml需要特殊加入的配置如下。
<dependency> <groupId>org.springframework.ws</groupId> <artifactId>spring-ws-core</artifactId> <version>2.2.3.RELEASE</version> </dependency> <dependency> <groupId>wsdl4j</groupId> <artifactId>wsdl4j</artifactId> <version>1.6.3</version> </dependency> <dependency> <groupId>org.eclipse.persistence</groupId> <artifactId>eclipselink</artifactId> <version>2.5.0</version> </dependency>
编写Holiday.java实体类如下,注意与xml
date对应的java类型不是
Date,而是
XMLGregorianCalendar,xml与java数据类型的对应关系参考这里。
package com.chinamobile.cmss.eshub.ssb.wssimulator.entity; import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlElement; import javax.xml.datatype.XMLGregorianCalendar; @XmlAccessorType(XmlAccessType.FIELD) public class Holiday { @XmlElement(namespace="http://mycompany.com/hr/schemas") private XMLGregorianCalendar StartDate; @XmlElement(namespace="http://mycompany.com/hr/schemas") private XMLGregorianCalendar EndDate; public XMLGregorianCalendar getStartDate() { return StartDate; } public void setStartDate(XMLGregorianCalendar startDate) { StartDate = startDate; } public XMLGregorianCalendar getEndDate() { return EndDate; } public void setEndDate(XMLGregorianCalendar endDate) { EndDate = endDate; } @Override public String toString() { return "Holiday [StartDate=" + StartDate + ", EndDate=" + EndDate + "]"; } }
编写Employee.java如下。
package com.chinamobile.cmss.eshub.ssb.wssimulator.entity; import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlElement; @XmlAccessorType(XmlAccessType.FIELD) public class Employee { @XmlElement(namespace="http://mycompany.com/hr/schemas") private int Number; @XmlElement(namespace="http://mycompany.com/hr/schemas") private String FirstName; @XmlElement(namespace="http://mycompany.com/hr/schemas") private String LastName; public int getNumber() { return Number; } public void setNumber(int number) { Number = number; } public String getFirstName() { return FirstName; } public void setFirstName(String firstName) { FirstName = firstName; } public String getLastName() { return LastName; } public void setLastName(String lastName) { LastName = lastName; } @Override public String toString() { return "Employee [Number=" + Number + ", FirstName=" + FirstName + ", LastName=" + LastName + "]"; } }
在Spring-ws中使用JAXB的时候要注意,每个类要注明namespace,否则会报
A descriptor with default root element的错误。类中的每个属性也要加
@XmlElement(namespace="")的标记,否则在接收的时候为空,namespace与你制定的相同。
HolidayRequest.java代码如下。
package com.chinamobile.cmss.eshub.ssb.wssimulator.entity; import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.XmlRootElement; @XmlRootElement(name = "HolidayRequest", namespace="http://mycompany.com/hr/schemas") @XmlAccessorType(XmlAccessType.FIELD) public class HolidayRequest { @XmlElement(namespace="http://mycompany.com/hr/schemas") private Holiday Holiday; @XmlElement(namespace="http://mycompany.com/hr/schemas") private Employee Employee; public Holiday getHoliday() { return Holiday; } public void setHoliday(Holiday holiday) { Holiday = holiday; } public Employee getEmployee() { return Employee; } public void setEmployee(Employee employee) { Employee = employee; } @Override public String toString() { return "HolidayRequest [Holiday=" + Holiday + ", Employee=" + Employee + "]"; } }
在实体类相同的包下面创建
jaxb.properties文件,内容为
javax.xml.bind.context.factory=org.eclipse.persistence.jaxb.JAXBContextFactory,表示我们不使用默认的JAXB,而是使用eclipselink提供的实现,使用默认的JAXB要写更多的代码配置ObjectFactory,否则会报
doesnt contain ObjectFactory.class or jaxb.index的错误。
到此我们在官方实例的基础上完成了一个更好用的样例。
相关文章推荐
- XML 与 JSON 优劣对比
- As3.0 xml + Loader应用代码
- 网马生成器 MS Internet Explorer XML Parsing Buffer Overflow Exploit (vista) 0day
- ext读取两种结构的xml的代码
- C#针对xml基本操作及保存配置文件应用实例
- Ruby程序中创建和解析XML文件的方法
- asp下查询xml的实现代码
- sqlserver FOR XML PATH 语句的应用
- 使用sp_xml_preparedocument处理XML文档的方法
- EBS xml publisher中文乱码问题及解决办法
- C#中的Linq to Xml详解
- C#操作XML文件实例汇总
- SQL Server中的XML数据进行insert、update、delete
- SQL Server中的XML数据进行insert、update、delete操作实现代码
- 关于SQLServer2005的学习笔记 XML的处理
- C#通过DataSet读写xml文件的方法
- C#实现基于XML配置MenuStrip菜单的方法
- php xml 入门学习资料
- Zend 输出产生XML解析错误