Значение @PayloadRoot при использовании объектов, а не схемы XML - PullRequest
5 голосов
/ 31 мая 2011

Я использую Объекты как сообщения от клиента на сервисный сервер.Как настроить конечную точку так, чтобы служба была найдена?@PayloadRoot здесь кажется неподходящим, потому что я не использую XML-схему, но объекты, помеченные @XmlRootElement (то есть улицей)

мой код:

spring-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"
   xmlns:context="http://www.springframework.org/schema/context"
   xmlns:sws="http://www.springframework.org/schema/web-services"
   xmlns:oxm="http://www.springframework.org/schema/oxm"
   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
   http://www.springframework.org/schema/oxm http://www.springframework.org/schema/oxm/spring-oxm-3.0.xsd">

<context:component-scan base-package="com.coral.project.endpoints"/>

<sws:annotation-driven />

<sws:dynamic-wsdl id="test" portTypeName="TestCase" locationUri="/testService/"
                  targetNamespace="http://www.example.org/schemasDef/test/definitions">
    <sws:xsd location="/WEB-INF/schemasDef/test.xsd"/>
</sws:dynamic-wsdl>

<bean id="springWSClient" class="com.coral.project.endpoints.SpringWSClient">
    <property name="defaultUri" value="http://localhost:8080/parking/springServices/testService/"/>
    <property name="marshaller" ref="marshaller" />
    <property name="unmarshaller" ref="marshaller" />
</bean>

<oxm:jaxb2-marshaller id="marshaller">
    <oxm:class-to-be-bound name="com.coral.project.entity.Street"/>
</oxm:jaxb2-marshaller>
</beans>

клиент:

public class SpringWSClient extends WebServiceGatewaySupport {

public void getSum() throws SOAPException, IOException, TransformerException {
    StreetDao streetDao = SpringUtils.getBean(StreetDao.class);
    Street street = streetDao.findById(1);

    getWebServiceTemplate().marshalSendAndReceive(street);

}
}

конечная точка:

@Endpoint
public class SpringWsEndpoint {

@Inject
private SpringWebService springWebService;

@PayloadRoot(localPart = "street", namespace = "http://blahblah")
@ResponsePayload
public Element handleTestRequest(@RequestPayload SAXSource testRequest) throws Exception {

    String fisrt = firstNum.valueOf(testRequest);
    String second = secondNum.valueOf(testRequest);

    String sum = springWebService.sum(Integer.parseInt(fisrt), Integer.parseInt(second)).toString();

    Element responseElement = new Element("TestRequest");
    Element sumElement = new Element("sum");
    sumElement.setText(sum);
    responseElement.setContent(sumElement);

    return responseElement;
}

}

Ответы [ 2 ]

4 голосов
/ 01 июня 2011

Узнал, как это сделать.Пришлось сделать несколько исправлений.Самое главное, @XmlRootElement name и атрибуты пространства имен требуются в моем случае.Итак, рабочий код:

test.xsd

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" 
    xmlns:test="http://www.example.org/schemasDef/test/schemas" 
    elementFormDefault="qualified"
    targetNamespace="http://www.example.org/schemasDef/test/schemas">

    <xs:element name="TestRequest">
        <xs:complexType>
            <xs:all>
                <xs:element name="firstNum" type="xs:integer" />
                <xs:element name="secondNum" type="xs:integer" />
                <xs:element name="sum" type="xs:integer" />
            </xs:all>
        </xs:complexType>
    </xs:element>

</xs:schema>

TestRequest.java

package com.coral.project.entity;

import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement(name="TestRequest",namespace="http://www.example.org/schemasDef/test/schemas")
public class TestRequest {

private Integer firstNum;
private Integer secondNum;
private Integer sum;

public Integer getFirstNum() {
    return firstNum;
}
public void setFirstNum(Integer firstNum) {
    this.firstNum = firstNum;
}
public Integer getSecondNum() {
    return secondNum;
}
public void setSecondNum(Integer secondNum) {
    this.secondNum = secondNum;
}
public Integer getSum() {
    return sum;
}
public void setSum(Integer sum) {
    this.sum = sum;
}

}

spring-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"
   xmlns:context="http://www.springframework.org/schema/context"
   xmlns:sws="http://www.springframework.org/schema/web-services"
   xmlns:oxm="http://www.springframework.org/schema/oxm"
   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
   http://www.springframework.org/schema/oxm http://www.springframework.org/schema/oxm/spring-oxm-3.0.xsd">

<context:component-scan base-package="com.coral.project.endpoints"/>

<sws:annotation-driven marshaller="marshaller" unmarshaller="marshaller"/>

<sws:dynamic-wsdl id="test" portTypeName="TestCase" locationUri="/testService/"
                  targetNamespace="http://www.example.org/schemasDef/test/definitions">
    <sws:xsd location="/WEB-INF/schemasDef/test.xsd"/>
</sws:dynamic-wsdl>

<bean id="springWSClient" class="com.coral.project.endpoints.SpringWSClient">
    <property name="defaultUri" value="http://localhost:8080/parking/springServices/testService"/>
    <property name="marshaller" ref="marshaller" />
    <property name="unmarshaller" ref="marshaller" />
</bean>

<oxm:jaxb2-marshaller id="marshaller">
    <oxm:class-to-be-bound name="com.coral.project.entity.TestRequest"/>
</oxm:jaxb2-marshaller>
</beans>

SpringWsEndpoint.java

package com.coral.project.endpoints;

import javax.inject.Inject;

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 org.springframework.ws.server.endpoint.annotation.ResponsePayload;

import com.coral.project.entity.TestRequest;
import com.coral.project.services.ifc.SpringWebService;

@Endpoint
public class SpringWsEndpoint {

private static final String NAMESPACE_URI = "http://www.example.org/schemasDef/test/schemas";

@Inject
private SpringWebService springWebService;


@PayloadRoot(namespace = NAMESPACE_URI, localPart = "TestRequest")
@ResponsePayload
public TestRequest handleTestRequestObj(@RequestPayload TestRequest testRequest) throws Exception {

    Integer sum = springWebService.sum(testRequest.getFirstNum(), testRequest.getSecondNum());
    testRequest.setSum(sum);
    return testRequest;

}


}

SpringWsClient.java

package com.coral.project.endpoints;

import java.io.IOException;

import javax.xml.soap.SOAPException;
import javax.xml.transform.TransformerException;

import org.springframework.ws.client.core.support.WebServiceGatewaySupport;

import com.coral.project.entity.TestRequest;

public class SpringWSClient extends WebServiceGatewaySupport {

public TestRequest getTestRequest() throws SOAPException, IOException, TransformerException {
    TestRequest testRequest = new TestRequest();
    testRequest.setFirstNum(6);
    testRequest.setSecondNum(9);

    TestRequest testResponse = (TestRequest)getWebServiceTemplate().marshalSendAndReceive(testRequest);
    return testResponse;
}
}
1 голос
/ 03 января 2017

Спасибо большое, мне пришлось сделать аналогичный трюк для моих собственных нужд, и ваше решение было последним, что мне нужно, чтобы оно заработало.Я суммирую различия здесь для справки.

Я работал над конечной точкой, которая получает произвольный XML и возвращает произвольный XML.Нет маршалинга или демаршаллинга, потому что данные, как говорят, огромные .Получающий конец задокументирован здесь .

Простой контейнер String:

package our.site.etc;

import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement(name="StringResponse",namespace="http://link.to.our/schemas/service/endpoint/yyyy/mm/dd")
public class StringResponse {
private String responseData;

public StringResponse() {
    ;
}

public StringResponse(String data) {
    this.responseData = data;
}

public String getResponseData() {
    return responseData;
}

public void setResponseData(String data) {
    this.responseData = data;
}

}

Метод конечной точки:

@PayloadRoot(localPart = LOCALPART, namespace = NAMESPACE)
@ResponsePayload
public @ResponseBody StringResponse receiveMessage(MessageContext messageContext) throws Exception {
    // do our thing:
    return new StringResponse(super.handleMessage(messageContext));
}

И последнее, что нужно было сделать - это пропустить часть WSClient, просто чтобы определить маршаллер jaxb2:

<oxm:jaxb2-marshaller id="marshaller">
    <oxm:class-to-be-bound name="our.site.etc.StringResponse"/>
</oxm:jaxb2-marshaller>

И теперь моя конечная точка возвращает строку ответа внутри CDATA.Практически он просто передает данные, делая с ним минимальные вещи.

...