Dav*_*ave 8 java web-services spring-ws jaxb
我有一个Web服务,我试图使用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>
Run Code Online (Sandbox Code Playgroud)
我有一个看起来像这样的服务方法:
@PayloadRoot( localPart = SERVICE_REQUEST, namespace = NAMESPACE )
public Outcome processFileRequest( ServiceRequest requestObject )
Run Code Online (Sandbox Code Playgroud)
我最终得到一个如下所示的异常:
java.lang.IllegalStateException:没有适配器端点[公共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>
Run Code Online (Sandbox Code Playgroud)
这是有效的,因为JAXB然后生成一个具有XmlRootElement注释的ServiceResponse类.不幸的是,我没有必要改变XSD - 这意味着我需要追求另一种选择.所以我试过了.我的新服务方法如下所示:
@PayloadRoot( localPart = SERVICE_REQUEST, namespace = NAMESPACE )
public JAXBElement<Outcome> processFileRequest( ServiceRequest requestObject )
Run Code Online (Sandbox Code Playgroud)
然后我使用在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);
}
Run Code Online (Sandbox Code Playgroud)
我提交服务器期望这可以解决问题.但相反,我得到:
java.lang.IllegalStateException:没有适配器端点[公共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)org.springframework.ws.transport.support.WebServiceMessageReceiverObjectSupport.handleConnection(WebServiceMessageReceiverObjectSupport.java:89)at org.springframework.ws.transport.http.WebServiceMessageReceiverHandlerAdapter.handle(WebServiceMessageReceiverHandlerAdapter.java:57)at at weblogic.servlet.internal.ServletRequestImpl.run(ServletRequestImpl. java:1446)at weblogic.work.ExecuteThread.execute(ExecuteThread.java:201)at 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>
Run Code Online (Sandbox Code Playgroud)
小智 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>
Run Code Online (Sandbox Code Playgroud)
以前我的定义如下所述: - 所以当我创建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>
Run Code Online (Sandbox Code Playgroud)
您看到此错误是因为当您返回 Outcome 类型的对象时,JAXB 不知道为根元素指定什么名称。如果您从架构生成元素,我希望您有一个可以返回的 ServiceResponse 类。
如果您无法获取 ServiceResponse 对象,我认为您将 Outcome 包装在 JAXBElement 中的方法应该可行。您是否检查过 _ServiceResponse_QNAME 是否使用正确的命名空间 URI 构建?
| 归档时间: |
|
| 查看次数: |
13252 次 |
| 最近记录: |