【问题标题】:JAXB resolution of complex types in JAX-WS web serviceJAX-WS Web 服务中复杂类型的 JAXB 解析
【发布时间】:2013-11-05 13:05:27
【问题描述】:

几天来,我面临一个关于 JAX-WS Web 服务的恼人错误。我打算使用自定义类型(基本上是“JAX-WS 原始”类型的结构,如 int、long 和 string)作为参数和返回值的方法生成 Web 服务。

这是我在尝试发布网络服务时遇到的异常:

线程“主”javax.xml.ws.WebServiceException 中的异常:类 org.econet.ecomanager.msgexchange.webservice.SendMessageReqType 不 具有名称请求的属性 com.sun.xml.ws.server.sei.EndpointArgumentsBuilder$DocLit.(EndpointArgumentsBuilder.java:608) 在 com.sun.xml.ws.server.sei.TieHandler.createArgumentsBuilder(TieHandler.java:143) 在 com.sun.xml.ws.server.sei.TieHandler.(TieHandler.java:115) 在 com.sun.xml.ws.db.DatabindingImpl.(DatabindingImpl.java:112) 在 com.sun.xml.ws.db.DatabindingProviderImpl.create(DatabindingProviderImpl.java:75) 在 com.sun.xml.ws.db.DatabindingProviderImpl.create(DatabindingProviderImpl.java:59) 在 com.sun.xml.ws.db.DatabindingFactoryImpl.createRuntime(DatabindingFactoryImpl.java:128) 在 com.sun.xml.ws.server.EndpointFactory.createSEIModel(EndpointFactory.java:436) 在 com.sun.xml.ws.server.EndpointFactory.create(EndpointFactory.java:270) 在 com.sun.xml.ws.server.EndpointFactory.createEndpoint(EndpointFactory.java:147) 在 com.sun.xml.ws.api.server.WSEndpoint.create(WSEndpoint.java:574) 在 com.sun.xml.ws.api.server.WSEndpoint.create(WSEndpoint.java:557) 在 com.sun.xml.ws.transport.http.server.EndpointImpl.createEndpoint(EndpointImpl.java:321) 在 com.sun.xml.ws.transport.http.server.EndpointImpl.publish(EndpointImpl.java:245) 在 com.sun.xml.ws.spi.ProviderImpl.createAndPublishEndpoint(ProviderImpl.java:134) 在 javax.xml.ws.Endpoint.publish(Endpoint.java:240) 在 org.econet.ecomanager.msgexchange.webservice.EcoMsgExchangeSystemsSideWSPublisher.main(EcoMsgExchangeSystemsSideWSPublisher.java:8) 引起:javax.xml.bind.JAXBException:请求无效 类属性 org.econet.ecomanager.msgexchange.webservice.SendMessageReqType 在 com.sun.xml.bind.v2.runtime.JAXBContextImpl.getElementPropertyAccessor(JAXBContextImpl.java:985) 在 com.sun.xml.ws.db.glassfish.JAXBRIContextWrapper.getElementPropertyAccessor(JAXBRIContextWrapper.java:121) 在 com.sun.xml.ws.server.sei.EndpointArgumentsBuilder$DocLit.(EndpointArgumentsBuilder.java:596) ... 16 更多

网络服务接口是:

@WebService(serviceName = "EcoMsgExchangeSystemsSide",
            targetNamespace="http://www.econet-cno.org/ecomsgexchange/ns",
            portName = "EcoMsgExchangeSystemsSidePort")
@BindingType (value = javax.xml.ws.soap.SOAPBinding.SOAP11HTTP_BINDING)
public interface EcoMsgExchangeSystemsSide {

    @WebMethod(operationName="sendMessage")
    @RequestWrapper(className="org.econet.ecomanager.msgexchange.webservice.SendMessageReqType")
    @ResponseWrapper(className="org.econet.ecomanager.msgexchange.webservice.SendMessageRespType")
    @WebResult(name="sendMessageResp")
    public SendMessageRespType sendMessage(@WebParam(name="request") SendMessageReqType request);

...

}

网络服务实现如下:

@WebService(serviceName = "EcoMsgExchangeSystemsSideService",
            portName = "EcoMsgExchangeSystemsSidePort",
            targetNamespace="http://www.econet-cno.org/ecomsgexchange/ns",
            endpointInterface="org.econet.ecomanager.msgexchange.webservice.EcoMsgExchangeSystemsSide")
public class EcoMsgExchangeSystemsSideImpl implements EcoMsgExchangeSystemsSide {

    public SendMessageRespType sendMessage(SendMessageReqType request) {
        long messageId = sendMessage(request.getClientId(), request.getClientPassword(), request.getRecipientId(), 
                request.getFileName()+"."+request.getFileExtension(), request.getFileBytes());
        SendMessageRespType response = new SendMessageRespType();
        if(messageId != -1) {
            response.setMessageId(messageId);
            response.setSenderId(request.getRecipientId());
            response.setFileName(request.getFileName());
            response.setFileExtension(request.getFileExtension());
            return response;
        }
        else
            return null;
    }

...

}

类 SendMessageReqType 和 SendMessageRespType 仅使用 @XmlRootElement 进行注释,并具有一组定义了 getter 和 setter 的属性(受保护)。

问题出在 JAXB 中,它无法解释数据类型以将它们转换为 XML 结构,但到目前为止我所做的所有尝试都没有成功,尝试不同的注释。我搜索了很多,几乎所有可用的 JAX-WS 示例都只使用原始类型,少数使用复杂类型的示例也没有帮助。

有人知道我做错了什么吗?

【问题讨论】:

    标签: web-services jakarta-ee jaxb jax-ws


    【解决方案1】:

    默认情况下,JAX-WS 参数类型被包装。所以你的参数已经被一些生成的元素包裹了,比如sendMessagesendMessageResponse

    <xs:element name="sendMessage" type="tns:sendMessage"/>
    <xs:element name="sendMessageResponse" type="tns:sendMessageResponse"/>
    <xs:complexType name="sendMessage">
        <xs:sequence>
          <xs:element minOccurs="0" name="request" type="tns:sendMessageReqType"/>
        </xs:sequence>
    </xs:complexType>
    <xs:complexType name="sendMessageReqType">
        <xs:sequence/>
    </xs:complexType>
    <xs:complexType name="sendMessageResponse">
        <xs:sequence>
          <xs:element minOccurs="0" name="sendMessageResp" type="tns:sendMessageRespType"/>
        </xs:sequence>
    </xs:complexType>
    <xs:complexType name="sendMessageRespType">
        <xs:sequence/>
    </xs:complexType>
    
    <wsdl:message name="sendMessage">
        <wsdl:part element="tns:sendMessage" name="parameters">
        </wsdl:part>
    </wsdl:message>
    <wsdl:message name="sendMessageResponse">
        <wsdl:part element="tns:sendMessageResponse" name="parameters">
        </wsdl:part>
    </wsdl:message>
    

    如果您想使用自己的包装元素而不是生成的元素,请通过将 @SOAPBinding(parameterStyle=ParameterStyle.BARE) 添加到您的 SEI(即 EcoMsgExchangeSystemsSide)并删除 @*Wrapper 注释来切换到裸参数样式(它们在这种形式中没有意义) .结果将是:

    <xs:complexType name="sendMessageReqType">
        <xs:sequence/>
    </xs:complexType>
    <xs:complexType name="sendMessageRespType">
        <xs:sequence/>
    </xs:complexType>
    <xs:element name="request" nillable="true" type="sendMessageReqType"/>
    <xs:element name="sendMessageResp" nillable="true" type="sendMessageRespType"/>
    
    
    <wsdl:message name="sendMessage">
        <wsdl:part element="tns:request" name="request">
        </wsdl:part>
    </wsdl:message>
    <wsdl:message name="sendMessageResponse">
        <wsdl:part element="tns:sendMessageResp" name="sendMessageResp">
        </wsdl:part>
    </wsdl:message>
    

    【讨论】:

    • 感谢@dawid 的回答。事实上,我不想用我创建的那些替换生成的包装类,我想要的是使用复杂类型作为参数和返回值。如果我替换默认生成的包装器,我认为对于客户端,SendMessageReqType 的每个类属性都将被假定为sendMessage() 的参数,对吗?实际上我的问题不在于方法参数,我可以使用几种原始类型而不是复杂类型。主要问题是返回值,我需要不止一种类型,例如文件名和文件字节。
    • 我以为您使用@*Wrapper 注释来替换生成的包装器。这就是那些注释的意图。如果您不想替换包装器,则不需要这些注释。如果您删除它们,那么您将得到您想要的 - 您将在复杂类型类周围拥有包装器类型。如果您可以指定您对 WSDL 或 SOAP 消息的期望,那么对您的帮助会更容易。
    • 抱歉@dawid 提供这么晚的反馈。我发现了这个问题,这是一个新手错误。我使用了相同的不同 Web 服务方法,只是参数不同。与此同时,我试图改变其中一个名字,瞧!问题解决了。即使您的答案不是我需要的,我也认为,考虑到我的问题描述,它是此类问题的有效答案。我应该将其标记为已接受吗?
    • @tftdias - 我很高兴听到您设法解决了一个问题 :) 您最初的问题是 > 任何知道我做错了什么的人?如果您觉得我帮助您确定了问题,请接受答案。如果不是,您仍然可以投票以感谢我的努力:) 如果您现在对问题有更多了解,您还可以与其他人分享症状(通过编辑问题)以及您如何处理问题(通过添加您的答案)。
    • 谢谢@dawid!问题已回答。
    【解决方案2】:

    我设法解决了这个问题。实际上,这是使用多个具有相同名称的 Web 服务方法/操作的结果,只是更改了它们之间的参数。一种类似于 Java 的编程方法,在处理我们的服务时是不可接受的。更改方法名称后一切正常。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-10-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-01-23
      • 1970-01-01
      相关资源
      最近更新 更多