Webservice中服务器端直接操作SOAP的XML内容

时间:2022-08-26 17:49:44

通常情况下,在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>