Весенний веб-сервис не работает - PullRequest
7 голосов
/ 17 октября 2011

Я настроил свой веб-сервис следующим образом:

ApplicationContext:

<sws:annotation-driven />    
 <bean class="org.springframework.ws.server.endpoint.mapping.PayloadRootAnnotationMethodEndpointMapping" >
<property name="interceptors">
 <list>
    <bean class="org.springframework.ws.server.endpoint.interceptor.PayloadLoggingInterceptor"/>
</list>
</property>

Примечание: перехватчик загружается при запуске, но ничего не пишет, если поступает запрос.

У меня есть класс PersonServiceImpl с методом addPersonRequest (). Все работает, если я использую org.dom4j.Element в качестве параметра метода;

@Endpoint
public class PersonServiceImpl {
     @PayloadRoot(namespace = "http://www.example.org/person/schema", localPart = "AddPersonRequest")
     @ResponsePayload
       public AddPersonRequest addPersonRequest(@RequestPayload Element element) {
        System.out.println(element.asXML());
        Person response = new Person();
        response.setId(2);
        response.setFirstName("Mad");
        response.setLastName("Mike");
        return response;
     }
}

Но если я изменю параметры моего метода, как показано ниже (поэтому следует использовать автоматическую сортировку Spring-ws), request.getFirstName () выводит null. (JAXB2 находится на пути к классам).

Класс Person аннотирован @XMLType и @ XMLRootElement.

Примечание: сортировка работает нормально.

@Endpoint
public class PersonServiceImpl {
     @PayloadRoot(namespace = "http://www.example.org/person/schema", localPart = "AddPersonRequest")
     @ResponsePayload
       public AddPersonRequest addPersonRequest(@RequestPayload Person request, SoapHeader header) {
        System.out.println(header.getName());
        System.out.println(request.getFirstName());
        Person response = new Person();
        response.setId(2);
        response.setFirstName("Mad");
        response.setLastName("Mike");
        return response;
     }
}

Person.java:

@XmlType
@XmlRootElement(namespace="http://www.example.org/person/schema", name="Person")
public class Person implements Serializable {

    private int id;
    private String firstName;
    private String lastName;

    @XmlElement
    public String getFirstName() {
        return firstName;
    }
    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

    @XmlElement
    public String getLastName() {
        return lastName;
    }
    public void setLastName(String lastName) {
        this.lastName = lastName;
    }

    @XmlAttribute
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
}

Тест-запрос, отправленный через soapUI (сгенерированный из wsdl):

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:sch="http://www.example.org/person/schema"> 
<soapenv:Header/>
<soapenv:Body>

  <sch:AddPersonRequest>

     <sch:Person sch:Id="1">

        <sch:FirstName>firstname</sch:FirstName>

        <sch:LastName>lastname</sch:LastName>

     </sch:Person>

  </sch:AddPersonRequest>

</soapenv:Body>
</soapenv:Envelope>

Ответы [ 3 ]

2 голосов
/ 18 октября 2011

Вы упомянули, что маршаллинг работает. Я не вижу причин, по которым демаршаллинг не сработает. Вы тестировали маршалл и демаршалл в изоляции?

Просто чтобы убедиться, что запрос мыла в порядке, Можете ли вы добавить перехватчик журналирования и распечатать фактический запрос, поступающий от клиента, обращающегося к веб-службе, Добавьте этот фрагмент в свой файл контекста

  <sws:interceptors>
    <bean class="org.springframework.ws.soap.server.endpoint.interceptor.SoapEnvelopeLoggingInterceptor">
        <property name="logRequest" value="true"></property>
        <property name="logResponse" value="true"></property>
    </bean>
</sws:interceptors>

Вы должны увидеть подобное сообщение в журнале, содержащее весь запрос мыла, я добавляю запрос сообщения журнала из пользовательского интерфейса saop в

   DEBUG [http-8080-2]:endpoint.interceptor.SoapEnvelopeLoggingInterceptor.logMessage - Request:
    <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:sch="http://hoost:port/context/patient/schemas">
      <soapenv:Header/>
         <soapenv:Body>
            <sch:addRequest>
              <sch:patient>
                  <sch:id>?</sch:id>
                     <sch:lastname>Joe</sch:lastname>
                </sch:patient>
             </sch:addRequest>
        </soapenv:Body>
      </soapenv:Envelope>

ОБНОВЛЕНИЕ ответа

Возможно, ваш запрос на мыло не уверен,

        <sch:FirstName>firstname</sch:FirstName> (this should be)

        <sch:firstName>firstname</sch:firstName>

Еще одно обновление

Исключение связано с тем, как вы определили конечную точку. В своем запросе мыла ( sch: AddPersonRequest ) вы отправляете addPersonRequest, а не Person в качестве полезной нагрузки, поэтому измените конечную точку, чтобы отразить это, @RequestPayload должен быть AddPersonRequest, а не Person

     @PayloadRoot(namespace = "http://www.example.org/person/schema", localPart = "AddPersonRequest")
     @ResponsePayload
      public AddPersonRequest addPersonRequest(@RequestPayload AddPersonRequest request, SoapHeader header) {
2 голосов
/ 18 октября 2011

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

Хотя я уже сталкивался с подобными проблемами, и они были решены путем добавления JAXBElement <> вокруг фактического класса.Как этот фрагмент:

@PayloadRoot(
    localPart = "PutOrganisationUnitRequest", 
    namespace = DEFAULT_NAMESPACE
)
@ResponsePayload public JAXBElement<Response> putOrganisationUnits (
    @RequestPayload JAXBElement<PutOrganisationUnitRequest> organisations,
    MessageContext messageContext) {

Еще одна вещь, которую вы можете проверить, - это пространства имен в вашем классе jaxb и в вашем определении конечной точки.

1 голос
/ 09 июня 2016

Эта реализация веб-сервиса Spring - полный мусор. Мозговой идиот мог бы работать лучше, чем эти "профи"

Как трудно было просто следовать принципам JSON и восстанавливать дерево объектов, следуя предложенному корневому типу.

НЕТ-ОДНОМУ нужны эти пространства имен. Никогда не бывает, чтобы один и тот же запрос имел два элемента с одинаковым именем, но из разных пространств имен. Но эти пространства имен - это бесконечная боль.

Просто сопоставьте элементы XML с полями объекта. Это только то, что требуется. Назначайте пространства имен из WSDL при генерации ответов, если кто-то заботится о них при получении end, но полностью игнорирует их при отмене маршалинга запроса.

Когда я смотрю на все это, я действительно хочу потратить месяц и создать инфраструктуру веб-сервиса NORMAL SOAP с сериализацией / десериализацией XML, которая заботится только об именах элементов и автоматическом создании объектов запроса / ответа, если дерево XML соответствует объекту дерево.

...