通常情况下,在JAX-WS2.0中是利用JAXB将传入的SOAP XML消息转换成JAVA的object,然后调用对应porttype的JAVA类的相应的方法,在完成调用后,再通过JAXB将返回参数转成SOAP XML.
JAX-WS还提供了另一种方法,让我们可以直接操作SOAP XML,通过让对应porttype的JAVA类实现 Provider<Source> 接口,当服务器端收到SOAP消息后,会调用 Source invoke(Source payload) 方法,如果需要直接对XML进行操作,不想利用JAXB来做对象和XML的转换,可以用这种机制.
例子:(用CXF发布web service)参照http://blog.csdn.net/kkdelta/archive/2009/03/12/3984312.aspx了解CXF发布的步骤.
1,JAVA 类
package com.cxfwsp.test;
import java.io.StringReader;
import javax.xml.transform.Result;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;
import javax.xml.ws.Provider;
import javax.xml.ws.Service;
import javax.xml.ws.ServiceMode;
import javax.xml.ws.WebServiceProvider;
@WebServiceProvider(serviceName = "TestWSProviderService", portName = "TestWSProviderPort", targetNamespace = "http://test.cxfwsp.com/", wsdlLocation = "wsdl/prjCXFWSP.wsdl")
@ServiceMode(Service.Mode.PAYLOAD)
public class TestWSProvider implements Provider<Source> {
public Source invoke(Source payload) {
//System.out.println(payload);
//DOMSource domsrc = (DOMSource)payload;
try{
Transformer tFormer = TransformerFactory.newInstance().newTransformer();
Result result = new StreamResult(System.out);
tFormer.transform(payload, result);
}catch(Exception e){
e.printStackTrace();
}
return new StreamSource(new StringReader("<testWSResponse><return><retIntVal>12</retIntVal><retStrVAL>teststr</retStrVAL> </return></testWSResponse>"));
}
}
2,wsdl 文件:
<?xml version="1.0" encoding="UTF-8"?>
<wsdl:definitions name="TestWSProviderService" targetNamespace="http://test.cxfwsp.com/" xmlns:tns="http://test.cxfwsp.com/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/">
<wsdl:types>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:tns="http://test.cxfwsp.com/" attributeFormDefault="unqualified" elementFormDefault="unqualified" targetNamespace="http://test.cxfwsp.com/">
<xs:element name="testWS" type="tns:testWS"/>
<xs:element name="testWSResponse" type="tns:testWSResponse"/>
<xs:complexType name="testWS">
<xs:sequence>
<xs:element minOccurs="0" name="arg0" type="tns:reqParameter"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="reqParameter">
<xs:sequence>
<xs:element name="intVal" type="xs:int"/>
<xs:element minOccurs="0" name="strVAL" type="xs:string"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="testWSResponse">
<xs:sequence>
<xs:element minOccurs="0" name="return" type="tns:respParameter"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="respParameter">
<xs:sequence>
<xs:element name="retIntVal" type="xs:int"/>
<xs:element minOccurs="0" name="retStrVAL" type="xs:string"/>
</xs:sequence>
</xs:complexType>
</xs:schema>
</wsdl:types>
<wsdl:message name="testWSResponse">
<wsdl:part name="parameters" element="tns:testWSResponse">
</wsdl:part>
</wsdl:message>
<wsdl:message name="testWS">
<wsdl:part name="parameters" element="tns:testWS">
</wsdl:part>
</wsdl:message>
<wsdl:portType name="TestWSProvider">
<wsdl:operation name="testWS">
<wsdl:input name="testWS" message="tns:testWS">
</wsdl:input>
<wsdl:output name="testWSResponse" message="tns:testWSResponse">
</wsdl:output>
</wsdl:operation>
</wsdl:portType>
<wsdl:binding name="TestWSProviderServiceSoapBinding" type="tns:TestWSProvider">
<soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
<wsdl:operation name="testWS">
<soap:operation soapAction="" style="document"/>
<wsdl:input name="testWS">
<soap:body use="literal"/>
</wsdl:input>
<wsdl:output name="testWSResponse">
<soap:body use="literal"/>
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<wsdl:service name="TestWSProviderService">
<wsdl:port name="TestWSProviderPort" binding="tns:TestWSProviderServiceSoapBinding">
<soap:address location="http://localhost:8080/prjCXFWSP/services/TestWSProviderPort"/>
</wsdl:port>
</wsdl:service>
</wsdl:definitions>
3 web.xml配置(集成Spring发布):
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>WEB-INF/beans.xml</param-value>
</context-param>
<listener>
<listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>
<servlet>
<servlet-name>CXFServlet</servlet-name>
<servlet-class>
org.apache.cxf.transport.servlet.CXFServlet
</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>CXFServlet</servlet-name>
<url-pattern>/services/*</url-pattern>
</servlet-mapping>
4,Spring 配置文件(beans.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:jaxws="http://cxf.apache.org/jaxws"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd">
<import resource="classpath:META-INF/cxf/cxf.xml" />
<import resource="classpath:META-INF/cxf/cxf-extension-soap.xml" />
<import resource="classpath:META-INF/cxf/cxf-servlet.xml" />
<bean name="testService" class="com.cxfwsp.test.TestWSProvider" />
<jaxws:endpoint id="testEndpoint" implementor="#testService"
wsdlLocation="classpath:wsdl/prjCXFWSP.wsdl"
address="/TestWSProviderPort">
<jaxws:features>
<bean class="org.apache.cxf.feature.LoggingFeature" />
</jaxws:features>
</jaxws:endpoint>
</beans>