我正在尝试使用Spring和Jaxb实现的Web服务。我已经使用这两种方法提供了一些工作服务 - 但由于响应的格式,这项特殊服务给我带来了困难。在我的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 )
我最终得到一个如下所示的异常:
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然后生成一个具有XmlRootElement注释的ServiceResponse类。不幸的是,我没有必要改变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.ServiceRequest)]: 您的端点是否实现了MessageHandler或PayloadEndpoint等受支持的接口? 在org.springframework.ws.server.MessageDispatcher.getEndpointAdapter(MessageDispatcher.java:283) 在org.springframework.ws.server.MessageDispatcher.dispatch(MessageDispatcher.java:226) 在org.springframework.ws.server.MessageDispatcher.receive(MessageDispatcher.java:169) at org.springframework.ws.transport.support.WebServiceMessageReceiverObjectSupport.handleConnection (WebServiceMessageReceiverObjectSupport.java:89) 在org.springframework.ws.transport.http.WebServiceMessageReceiverHandlerAdapter.handle (WebServiceMessageReceiverHandlerAdapter.java:57) 在org.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个Web服务,只是它们没有显示这个特定的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>
答案 0 :(得分:7)
这是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 bean时,它总是为此创建两个元素,哪个元素(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 :(得分:1)
当我遇到这个问题时,答案结果是我忘记在Spring Jaxb2Marshaller的classesToBeBound列表中包含元素类。将这些添加到列表中可以解决问题 - 但我们的元素已经设置为内联复杂类型。
答案 2 :(得分:0)
您看到此错误,因为当您返回Outcome类型的对象时,JAXB不知道为根元素指定的名称。如果您要从模式生成元素,我希望您有一个可以返回的ServiceResponse类。
如果你无法获得ServiceResponse对象,我认为你在JAXBElement中包装Outcome的方法应该有效。您是否检查过_ServiceResponse_QNAME是否使用正确的命名空间URI构建?