简体   繁体   English

具有MTOM附件的Spring-WS Web服务 - Hello world测试

[英]Spring-WS webservice with MTOM attachment - Hello world test

I am trying to create a simple Spring webservice which when called returns a file attachment as part of the SOAP response. 我正在尝试创建一个简单的Spring Web服务,在调用时返回文件附件作为SOAP响应的一部分。 The Enpoint class is shown below: Enpoint类如下所示:

And finally the endpoint 最后是终点

@PayloadRoot(namespace="http://ws.mypackage.com", localPart="downloadMessageRequest")
    @ResponsePayload
    public JAXBElement<DownloadResponseType> invoke(@RequestPayload DownloadMessageRequest req) throws Exception  {

        DownloadResponseType response = new DownloadResponseType();
        DownloadResponseType.PayLoad payload = new DownloadResponseType.PayLoad();          

        javax.activation.DataHandler dataHandler = new javax.activation.DataHandler(new FileDataSource("c:\\temp\\maven-feather.png"));
        payload.setMessagePayLoad(dataHandler);
        response.setPayLoad(payload);

        return objectFactory.createDownloadMessageResponse(response);

    }

I would like the response to include the file as an attachement similar to the following response: 我希望响应将文件包含为类似于以下响应的附件:

Content-Type: multipart/related; boundary=MIMEBoundary4A7AE55984E7438034;
                         type="application/xop+xml"; start="<0.09BC7F4BE2E4D3EF1B@apache.org>";
                         start-info="text/xml; charset=utf-8"

--MIMEBoundary4A7AE55984E7438034
content-type: application/xop+xml; charset=utf-8; type="application/soap+xml;"
content-transfer-encoding: binary
content-id: <0.09BC7F4BE2E4D3EF1B@apache.org>

<?xml version='1.0' encoding='utf-8'?>
<soapenv:Envelope xmlns:soapenv="...."....>
  ........
         <xop:Include href="cid:1.A91D6D2E3D7AC4D580@apache.org" 
                        xmlns:xop="http://www.w3.org/2004/08/xop/include">
         </xop:Include>
  ........

</soapenv:Envelope>
--MIMEBoundary4A7AE55984E7438034
content-type: application/octet-stream
content-transfer-encoding: binary
content-id: <1.A91D6D2E3D7AC4D580@apache.org>

Binary Data.....
--MIMEBoundary4A7AE55984E7438034--

I have tried to follow the documentation and the sample code in the spring-ws samples and for some reason the output i am getting is always this (ie the base64 data is not an attachement. 我试图遵循spring-ws示例中的文档和示例代码,由于某种原因,我得到的输出总是这样(即base64数据不是附件。

HTTP/1.1 200 OK
Server: Apache-Coyote/1.1
Accept: text/xml, text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2
SOAPAction: ""
Content-Type: text/xml;charset=utf-8
Content-Length: 4750
Date: Tue, 03 Jul 2012 17:05:21 GMT

<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"><SOAP-ENV:Header/><SOAP-ENV:Body><ns2:downloadMessageResponse xmlns:ns2="http://ws.mypackage.com"><ns2:payLoad><ns2:messagePayLoad>....iVBORw0KGgoAAAANSUhEUgAAAFoAAAAeCyAAAAAElFTkSuQmCC....</ns2:messagePayLoad></ns2:payLoad></ns2:downloadMessageResponse></SOAP-ENV:Body></SOAP-ENV:Envelope>

As you can see, the payload is not an attachment. 如您所见,有效负载不是附件。 Here is how i have configured my application: 以下是我配置应用程序的方法:

web.xml web.xml中

<context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>
        /WEB-INF/app-config.xml
        </param-value>
    </context-param>

    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>

    <servlet>
        <servlet-name>webservice</servlet-name>
        <servlet-class>org.springframework.ws.transport.http.MessageDispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>/WEB-INF/ws-config.xml</param-value>
        </init-param>
    </servlet>

ws-config.xml WS-config.xml中

<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:ws="http://www.springframework.org/schema/web-services"
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/web-services 
    http://www.springframework.org/schema/web-services/web-services-2.0.xsd
        http://www.springframework.org/schema/beans 
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context 
        http://www.springframework.org/schema/context/spring-context-3.0.xsd">

    <context:component-scan base-package="com.mypackage"/>

    <ws:annotation-driven/>


    <ws:dynamic-wsdl id="serviceDefinition" portTypeName="myService"
                     locationUri="http://localhost:8080/springWsTest/webservice">
        <ws:xsd location="/WEB-INF/schemas/downloadMessageRequest.xsd"/>
    </ws:dynamic-wsdl>

    <bean id="marshaller" class="org.springframework.oxm.jaxb.Jaxb2Marshaller">
        <property name="contextPath" value="com.mypackage.ws"/>
        <property name="mtomEnabled" value="true"/>
    </bean> 
</beans>

downloadMessageRequest.xsd schema file downloadMessageRequest.xsd架构文件

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" 
xmlns:m="http://ws.mypackage.com" 
xmlns:xmime="http://www.w3.org/2005/05/xmlmime" elementFormDefault="qualified"
targetNamespace="http://ws.mypackage.com" 
attributeFormDefault="unqualified"> 

    <xs:element name="downloadMessageRequest">
        <xs:complexType/>
    </xs:element>

    <xs:element name="downloadMessageResponse" type="m:downloadResponseType" />

    <xs:complexType name="downloadResponseType">
            <xs:sequence>
                <xs:element name="requestName" type="xs:string"/>
                <xs:element name="payLoad">
                    <xs:complexType>
                        <xs:sequence>
                            <xs:element name="messagePayLoad" type="xs:base64Binary" xmime:expectedContentTypes="application/octet-stream"/>
                        </xs:sequence>
                    </xs:complexType>
                </xs:element>
            </xs:sequence>
     </xs:complexType>


     <xs:element name="localDTMRequest">
        <xs:complexType/>
    </xs:element>

    <xs:element name="localDTMResponse">
        <xs:complexType>        
            <xs:sequence>
                <xs:element name="localDTM" type="xs:dateTime"/>
            </xs:sequence>          
        </xs:complexType>
    </xs:element>


</xs:schema>

The file does get converted to base64binary. 该文件确实转换为base64binary。 The JAXB clases are generated correctly. JAXB clases是正确生成的。 The Endpoint works but it is not including the file as an attachement. 端点可以工作,但不包括文件作为附件。 It is including it as part of the XML tag even though i have set mtomEnabled=true. 它包含它作为XML标记的一部分,即使我已设置mtomEnabled = true。

What am i missing? 我错过了什么?

Finally managed to get it to work. 终于设法让它发挥作用。 The configuration is more or less the same as what i had in my original post. 配置或多或少与我在原帖中的配置相同。 I had to update the configuration file. 我不得不更新配置文件。 Here is how my configuration file looks like now. 这是我的配置文件现在的样子。

<?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:ws="http://www.springframework.org/schema/web-services"
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/web-services http://www.springframework.org/schema/web-services/web-services-2.0.xsd
        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd">

    <context:component-scan base-package="com.mypackage.ws" />

    <ws:annotation-driven />

    <ws:dynamic-wsdl id="serviceDefinition"
        portTypeName="Msm" locationUri="http://localhost:8080/MyWebService/webservice">
        <ws:xsd location="/WEB-INF/schemas/schema.xsd" />
    </ws:dynamic-wsdl>

    <bean id="messageReceiver"
        class="org.springframework.ws.soap.server.SoapMessageDispatcher">
        <property name="endpointAdapters">
            <list>
                <ref bean="defaultMethodEndpointAdapter" />
            </list>
        </property>
    </bean>

    <bean id="defaultMethodEndpointAdapter"
        class="org.springframework.ws.server.endpoint.adapter.DefaultMethodEndpointAdapter">
        <property name="methodArgumentResolvers">
            <list>
                <!-- Be careful here! You might need to add more processors if you do 
                    more than webservices! -->
                <ref bean="marshallingPayloadMethodProcessor" />
            </list>
        </property>
        <property name="methodReturnValueHandlers">
            <list>
                <ref bean="marshallingPayloadMethodProcessor" />
            </list>
        </property>
    </bean>

    <bean id="marshaller" class="org.springframework.oxm.jaxb.Jaxb2Marshaller">
        <property name="contextPath" value="com.mypackage.ws" />
        <property name="mtomEnabled" value="true" />
    </bean>

    <bean id="marshallingPayloadMethodProcessor"
        class="org.springframework.ws.server.endpoint.adapter.method.MarshallingPayloadMethodProcessor">
        <constructor-arg ref="marshaller" />
        <constructor-arg ref="marshaller" />
    </bean>
</beans>

The changes i added were based on what i read on this article - blog.hpxn.net/2012/06/ 我添加的更改基于我在本文中阅读的内容 - blog.hpxn.net/2012/06/

Edit - An example 编辑 - 一个例子

Here is an example (based on the spring samples) that returns the attachment in MTOM format. 以下是以MTOM格式返回附件的示例(基于弹簧样本)。 I just tried it and the response is shown below: 我刚试了一下,响应如下:

   HTTP/1.1 200 OK
Server: Apache-Coyote/1.1
Accept: text/xml, text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2
SOAPAction: ""
Content-Type: Multipart/Related; start-info="text/xml"; type="application/xop+xml"; boundary="----=_Part_0_17910623.1342789122256"
Transfer-Encoding: chunked
Date: Fri, 20 Jul 2012 12:58:42 GMT

------=_Part_0_17910623.1342789122256
Content-Type: application/xop+xml; charset=utf-8; type="text/xml"

<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"><SOAP-ENV:Header/><SOAP-ENV:Body><ns2:LoadImageResponse xmlns:ns2="http://www.springframework.org/spring-ws/samples/mtom"><ns2:name>?</ns2:name><ns2:image><xop:Include xmlns:xop="http://www.w3.org/2004/08/xop/include" href="cid:f1c3ef65-a519-4bba-9b92-9acffc0c14f7%40www.springframework.org"/></ns2:image></ns2:LoadImageResponse></SOAP-ENV:Body></SOAP-ENV:Envelope>
------=_Part_0_17910623.1342789122256
Content-Type: image/png
Content-ID: <f1c3ef65-a519-4bba-9b92-9acffc0c14f7@www.springframework.org>
Content-Transfer-Encoding: binary

‰PNG

Note that i have not configured any Axiom factories. 请注意,我还没有配置任何Axiom工厂。 The necessary files are listed below: 必要的文件如下:

schema.xsd schema.xsd

<?xml version="1.0" encoding="UTF-8"?>
<schema xmlns="http://www.w3.org/2001/XMLSchema" targetNamespace="http://www.springframework.org/spring-ws/samples/mtom"
        xmlns:tns="http://www.springframework.org/spring-ws/samples/mtom"
        xmlns:xmime="http://www.w3.org/2005/05/xmlmime" elementFormDefault="qualified">

    <element name="StoreImageRequest" type="tns:Image"/>

    <element name="LoadImageRequest" type="string"/>

    <element name="LoadImageResponse" type="tns:Image"/>

    <complexType name="Image">
        <sequence>
            <element name="name" type="string"/>
            <element name="image" type="base64Binary" xmime:expectedContentTypes="image/png"/>
        </sequence>
    </complexType>

</schema>

spring-ws-servlet.xml 弹簧-WS-servlet.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"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">

    <bean id="imageRepository" class="org.springframework.ws.samples.mtom.service.StubImageRepository"/>

    <bean class="org.springframework.ws.samples.mtom.ws.ImageRepositoryEndpoint">
        <constructor-arg ref="imageRepository"/>
    </bean>

    <bean class="org.springframework.ws.server.endpoint.mapping.PayloadRootAnnotationMethodEndpointMapping"/>

    <bean class="org.springframework.ws.server.endpoint.adapter.GenericMarshallingMethodEndpointAdapter">
        <constructor-arg ref="marshaller"/>
    </bean>

    <bean id="marshaller" class="org.springframework.oxm.jaxb.Jaxb2Marshaller">
        <property name="contextPath" value="org.springframework.ws.samples.mtom.schema"/>
        <property name="mtomEnabled" value="true"/>
    </bean>

    <bean id="mtom" class="org.springframework.ws.wsdl.wsdl11.DefaultWsdl11Definition">
        <property name="schema" ref="schema"/>
        <property name="portTypeName" value="ImageRepository"/>
        <property name="locationUri" value="http://localhost:8080/mtom-server/"/>
    </bean>

    <bean id="schema" class="org.springframework.xml.xsd.SimpleXsdSchema">
        <property name="xsd" value="/WEB-INF/schema.xsd"/>
    </bean>

</beans>

web.xml web.xml中

<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/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>

    <servlet>
        <servlet-name>spring-ws</servlet-name>
        <servlet-class>org.springframework.ws.transport.http.MessageDispatcherServlet</servlet-class>
    </servlet>

    <servlet-mapping>
        <servlet-name>spring-ws</servlet-name>
        <url-pattern>/*</url-pattern>
    </servlet-mapping>

</web-app>

To get the response returned as a SAAJ attachment rather than an MTOM attachment, i have to manually configure the SAAj factories as described in this thread How do I add an attachment to a response payload in Spring-WS? 要将响应作为SAAJ附件而不是MTOM附件返回,我必须按照此线程中的描述手动配置SAAj工厂如何在Spring-WS中向响应有效负载添加附件?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM