JAXB + Spring WS: «Нет адаптера для конечной точки» при использовании JAXBElement - PullRequest
8 голосов
/ 12 февраля 2011

У меня есть веб-сервис, который я пытаюсь реализовать, используя Spring и Jaxb.У меня уже есть несколько работающих сервисов, использующих оба из них - но этот конкретный сервис доставляет мне трудности из-за формата ответа.В моем XSD ответ определяется следующим образом (обратите внимание, что это один элемент):

<!-- Response definition -->
<element name="ServiceResponse" type="Q1:Outcome"/>


<!-- Outcome definition -->
<complexType name="Outcome">
    <sequence>
        <element name="ErrorCode">
            <simpleType>
                <restriction base="string">
                    <maxLength value="8"/>
                </restriction>
            </simpleType>
        </element>
        <element name="ErrorText">
            <simpleType>
                <restriction base="string">
                    <maxLength value="1000"/>
                </restriction>
            </simpleType>
        </element>
        <element name="DocumentId">
            <simpleType>
                <restriction base="string">
                    <maxLength value="30"/>
                </restriction>
            </simpleType>
        </element>
    </sequence>
</complexType>

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

@PayloadRoot( localPart = SERVICE_REQUEST, namespace = NAMESPACE )
public Outcome processFileRequest( ServiceRequest requestObject )

I endс исключением, которое выглядит следующим образом:

java.lang.IllegalStateException: нет адаптера для конечной точки [public dortman.xsd.objects.Outcome dortman.annotated.MyTestEndpoint.processFileRequest (dortman.xsd.objects).ServiceRequest)]: Ваша конечная точка реализует поддерживаемый интерфейс, такой как MessageHandler или PayloadEndpoint?

После нахождения некоторых связанных сообщений на форуме Spring и Stackoverflow кажется, что возвращаемые объекты должны иметь аннотацию XmlRootElement.или быть завернутым в элемент JAXBElement.Чтобы попробовать первый, я изменил ответ в XSD на:

<!-- Response definition -->
<element name="ServiceResponse">
    <complexType>
        <sequence>
            <element name="FileSize" type="long"/>
        </sequence>
    </complexType>
</element>  

Это работает, поскольку JAXB затем генерирует класс ServiceResponse, который имеет аннотацию XmlRootElement.К сожалению, у меня не обязательно есть широта, чтобы изменить XSD - что означает, что мне нужно выбрать другой вариант.Я попробовал это.Мой новый метод обслуживания выглядит следующим образом:

@PayloadRoot( localPart = SERVICE_REQUEST, namespace = NAMESPACE )
public JAXBElement<Outcome> processFileRequest( ServiceRequest requestObject )

И затем я обертываю свой возвращаемый объект, используя метод, созданный в ObjectFactory:

/**
 * Create an instance of {@link JAXBElement }{@code <}{@link Outcome }{@code >}}
 * 
 */
@XmlElementDecl(namespace = "http://www.dortman.com/MyTestService", name = "ServiceResponse")
public JAXBElement<Outcome> createServiceResponse(Outcome value) {
    return new JAXBElement<Outcome>(_ServiceResponse_QNAME, Outcome.class, null, value);
}

Я подаю на сервер, ожидая, что эторешить проблему.Но вместо этого я получаю:

java.lang.IllegalStateException: нет адаптера для конечной точки [public javax.xml.bind.JAXBElement dortman.annotated.MyTestEndpoint.processFileRequest (dortman.xsd.objects.Servicequ): Ваша конечная точка реализует поддерживаемый интерфейс, такой как MessageHandler или PayloadEndpoint?в org.springframework.ws.server.MessageDispatcher.getEndpointAdapter (MessageDispatcher.java:283) в org.springframework.ws.server.MessageDispatcher.dispatch (MessageDispatcher.java:226) в org.springframework.wes.(MessageDispatcher.java:169) по адресу org.springframework.ws.transport.support.WebServiceMessageReceiverObjectSupport.handleConnection (WebServiceMessageReceiverObjectSupport.java:89) по адресу org.springframework.erapHerg.Werserverorg.springframework.ws.transport.http.MessageDispatcherServlet.doService (MessageDispatcherServlet.java:231) при weblogic.servlet.internal.WebAppServletContext.execute (WebAppServletContext.java:2174) в weblogic.servlet.internal.ServletRequestImpl.run (ServletRequestImpl.Java: 1446) в weblogic.work.ExecuteThread.execute (ExecuteThread.java:201) в weblogic.work.ExecuteThread.run (ExecuteThread.java:173)

Очевидно, это былоне впечатлен моим использованием JAXBElement.Кто-нибудь еще сталкивался с этой проблемой?

Мой файл конфигурации (который уже работает с ~ 6 веб-службами, просто ни один из них не демонстрирует этот конкретный вариант XSD) содержит следующее:

<!-- JAXB marshaller to be used by the annotated web services -->
<bean class="org.springframework.ws.server.endpoint.adapter.MarshallingMethodEndpointAdapter">
<constructor-arg>
<bean class="org.springframework.oxm.jaxb.Jaxb2Marshaller">
  <property name="contextPath" value="dortman.xsd.objects" />
  <property name="mtomEnabled" value="true"/>
</bean> 
</constructor-arg>
</bean> 

<bean id="messageFactory" class="org.springframework.ws.soap.axiom.AxiomSoapMessageFactory">
<property name="payloadCaching" value="true"></property>
<property name="attachmentCaching" value="true"></property>
</bean>

Ответы [ 3 ]

7 голосов
/ 12 мая 2011

Это проблема, связанная с XSD, вам нужно исправить XSD.Обычно, когда вы играете с JAXB, эта проблема возникает, вам нужно правильно определить запрос и ответ.

Эта проблема решена.Например, если ваш элемент запроса ввода - «InsertRequest», поэтому нужно определить как

<xs:element name="InsertRequest">
<xs:annotation>
<xs:documentation>Root element for Record Insert Request</xs:documentation>
</xs:annotation>
<xs:complexType>
<xs:sequence>
<xs:element name="GeneralDetails" type="tns:GenralDetailsType"></xs:element>
<xs:element name="FullDetails" type="tns:FullDetailsType"></xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>

Ранее я определил это, как упомянуто ниже: - поэтому, когда я создаю компоненты JAXB, он всегда создает два элемента для этого,какой элемент (InsertRequest или InsertRequestType) должен ссылаться в конечной точке, это была проблема.

<element name="InsertRequest" type="tns:InsertRequestType"></element>


<complexType name="InsertRequestType">
<sequence>
<element name="GeneralDetails" type="tns:GenralDetailsType"></element>
<element name="FullDetails" type="tns:FullDetailsType"></element>
</sequence>
</complexType>
1 голос
/ 05 июля 2012

Когда у меня возникла эта проблема, ответ оказался, что я забыл включить класс элемента в список classesToBeBound для Spring Jaxb2Marshaller. Добавление их в список решило проблему - но наши элементы уже были настроены со встроенным сложным типом.

0 голосов
/ 25 февраля 2011

Вы видите эту ошибку, потому что JAXB не знает, какое имя дать корневому элементу, когда вы возвращаете объект типа Outcome.Если вы генерируете свои элементы из схемы, я ожидаю, что у вас будет класс ServiceResponse, который вы могли бы вернуть взамен.

Если вы не можете получить объект ServiceResponse, я бы подумал, что вы подходите обернуть Outcomeв JAXBElement должно работать.Вы проверили, что _ServiceResponse_QNAME создан с правильным URI пространства имен?

...