当前位置: 首页 > 知识库问答 >
问题:

JAX-WS web服务中复杂类型的JAXB解析

柯清野
2023-03-14

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

这是我在尝试发布Web服务时遇到的例外:

异常线程"main"javax.xml.ws.WebServiceExc0019:类org.econet.ecomanager.msgexchange.webservice.SendMessageReqType没有属性的名称请求在com.sun.xml.ws.server.sei.Endpoint ArgumentsBuilder$DocLit.(Endpoint ArgumentsBuilder.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.数据库。数据库mpl.java:112)com.sun.xml.ws.db.数据库提供商mpl.create(数据库提供商mpl.java:75)com.sun.xml.ws.db.数据库提供商mpl.create(数据库提供商mpl.java:59)com.sun.xml.ws.db.数据库工厂mpl.create在com. sun. xml. ws. server运行时(数据库工厂mpl.java:128)。Endpoint Factory. createSEIModel(Endpoint Factory. java: 436)在com. sun. xml. ws. server。在com. sun. xml. ws. server上创建(Endpoint Factory. java: 270)。在com. sun. xml. ws. api. server上创建Endpoint(Endpoint Factory. java: 147)。创建(WSEndpoint. java: 574)在com. sun. xml. ws. api. server。创建(WSEndpoint. java: 557)在com. sun. xml. ws. transport. http. server。Endpoint Inp. createEndpoint(Endpoint Inp. java: 321)在com. sun. xml. ws. transport. http. server。在com. sun. xml. ws. spi.发布(Endpoint Imp. java: 245)。在javax. xml. ws.发布(Endpoint. java: 240)在org. econet. ecomanager. msgExchange. webservice。由javax. xml. bind引起。JAXB异常:请求不是类org. econet. ecomanager. msgExchange. webservice上的有效属性。SendMessageReqType at com. sun. xml. bind. v2. runtime.JAXBContextImp. getElementProperties tyAccitor(JAXBContextInp. java: 985)在com. sun. xml. ws. db. glassfish。java: 121)在com. sun. xml. ws. server. sei。Endpoint ArgumentsBuilder$DocLit.(Endpoint ArgumentsBuilder. java: 596)...16更多

web服务接口是:

@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);

...

}

web服务实现如下所示:

@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的atribute(受保护)。

问题在于JAXB无法解释数据类型以将其转换为XML结构,但我迄今为止所做的尝试都没有成功,只是尝试了不同的注释。我搜索了很多,几乎所有可用的JAX-WS示例都只使用基本类型,少数使用复杂类型的示例也没有帮助。

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

共有2个答案

祁曦哲
2023-03-14

我设法解决了这个问题。事实上,这是使用多个同名的web服务方法/操作的结果,只需更改参数即可对其进行查看。一种类似Java的编程方法,在处理we服务时是不可接受的。在更改了方法名称之后,所有的方法都工作得很好。

太叔昊苍
2023-03-14

默认情况下,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>

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

<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>
 类似资料:
  • 问题内容: 我有一个深层的XML结构,其中包含许多没有意义的包装程序,我将它们映射到一个Java类。使用@XmlPath映射简单的数据类型是在公园里散步,但是当涉及到实际上需要自己的类的类型时,我不太确定该怎么做,尤其是当这些类型也应该放在列表中时。 我在将以下示例中的所有类型映射到我的类时遇到问题。由于包装器驻留在使用I 映射的资源中,因此我不能使用,否则我通常会这样做。 示例XML结构 根ja

  • 我有一个很深的XML结构,它有很多无意义的包装器,我要映射到一个Java类。用@xmlpath映射简单的数据类型是一种尝试,但当涉及到实际上需要自己的类的类型时,我不太确定该如何做,特别是当这些类型也应该放在列表中时。 XML结构示例 root.java RefObj.java 更新 在发布了前面的示例之后,我意识到它实际上是按照预期工作的,这让我更加困惑。尽管我试图在生产代码中复制(以前的)工作

  • 数据-我使用XML中的许多附加列获取此类数据,并使用com。databricks spark-xml\u 2.11库,用于将xml数据转换为数据帧。 要求-必须从数组(struct)类型或列custom\u属性转换数据。示例中的custom\u属性,如示例输出所示。My struct有三个字段,分别命名为“\u VALUE”、“属性\u id”、“值”。我需要将属性id转换为列名称,数据为-检查“

  • 问题是如何使用对象类型发送Header,而不是HTTPClient声明中提供的HttpHeaders。 我在VS代码中得到的错误信息如下所示 “{headers:GetLoggedInUserHeaderRequestParam;}”类型的[ts]参数不可分配给“{headers?:HttpHeaders{[Header:string]:string string[];};};”类型“的参数;”观

  • 问题内容: 请原谅我,但我可能不熟悉正确询问此问题所需的所有术语。 我正在使用jax-rs 的实现在Java中使用一个相当简单的REST Web服务。方法头是这样的: MessageContext在哪里。 我要完成的两件事似乎无法弄清: 如果满足某些条件(例如,出现错误),则更改内容类型 更改响应的状态码 我尝试通过通过MessageContext访问响应来更改响应: 但是这些变化与发送的响应无关

  • 我正在用ASP开发一个Web API。净核心。当我使用post请求执行API时,在UnitController的post方法的断点之前会引发异常。 例外 请求启动HTTP/1.1 POSThttp://localhost:5000/api/unit应用程序/json 31失败:Microsoft. AspNetCore. Server. Kestrel[13]连接ID"0HKVTL9A1LTD4"