无法映射SOAP服务响应

时间:2015-05-06 14:14:40

标签: java web-services soap jax-ws

这个问题让我感到困难了近两天,我真的需要一些帮助来搞清楚。

我使用 wsimport 从Java项目的两个不同.wsdl文件生成代码。

第一个服务工作正常,但由于某种原因,第二个服务的响应无法解组到响应对象。

工作服务:

@WebMethod(action = "[actionName]")
@WebResult(name = "getSimpleCompanyInfoResponse", partName = "getSimpleCompanyInfoResponse")
public GetSimpleCompanyInfoResponse getSimpleCompanyInfo(
        @WebParam(name = "getSimpleCompanyInfoRequest", partName = "getSimpleCompanyInfoRequest") GetSimpleCompanyInfoRequest getSimpleCompanyInfoRequest);

回应POJO:

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "getSimpleCompanyInfoResponse", propOrder = {
    //variables
})
public class GetSimpleCompanyInfoResponse {
    //variables
}

响应XML:

<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="[namespaceUri]" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <SOAP-ENV:Body>
        <ns1:getSimpleCompanyInfoResponse>
            <getSimpleCompanyInfoResponse>
                //variables
            </getSimpleCompanyInfoResponse>
        </ns1:getSimpleCompanyInfoResponse>
    </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

工作服务:

@WebMethod(operationName = "PersonnelInfo", action = "[actionName]")
@WebResult(name = "PersonnelInfoResponse", partName = "PersonnelInfoResponse")
public PersonnelInfoResponse personnelInfo(
@WebParam(name = "PersonnelInfoRequest", partName = "PersonnelInfoRequest") PersonnelInfoRequest personnelInfoRequest);

回应POJO:

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "PersonnelInfoResponse", propOrder = {
    //variables
})
public class PersonnelInfoResponse {
    //variables
}

响应XML:

<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="[namespaceUri]" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <SOAP-ENV:Body>
        <ns1:PersonnelInfoResponse>
            //variables
        </ns1:PersonnelInfoResponse>
    </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

使用 -Dcom.sun.xml.internal.ws.transport.http.client.HttpTransportPipe.dump = true 或使用Wireshark监控我可以看到来自第二个服务的响应信封罚款和解组不会抛出任何异常,但最终 PersonnelInfoResponse 为空。

我能看到的唯一区别是XML中的第二个服务响应有效负载缺少外部元素,这似乎是问题所在。但是,我不知道如何修复&#34;它所以它不会寻找外部元素。

如果有任何不清楚或遗漏的信息,请告知我们,我会尝试向您提供所有信息。

修改

不,我很遗憾无法控制服务本身,我只有.wsdl和.xsd。

我正在调用这样的服务:

ReportsControllerPortType port = new ReportsControllerService().getReportsControllerPort();

PersonnelInfoRequest request = new PersonnelInfoRequest();
//fill the required fields in the request, username, password, etc.

PersonnelInfoResponse response = port.personnelInfo(request);

客户端服务存根(ReportsControllerService&amp; ReportsControllerPortType)也由 wsimport 根据.wsdl和.xsd自动生成。

编辑2:

删除操作名称不起作用,服务无法初始化。以下是.wsdl-s的定义:

工作服务:

<wsdl:message name="getSimpleCompanyInfoRequest">
    <wsdl:part name="getSimpleCompanyInfoRequest" type="tns:getSimpleCompanyInfoRequest" />
</wsdl:message>
<wsdl:message name="getSimpleCompanyInfoResponse">
    <wsdl:part name="getSimpleCompanyInfoResponse" type="tns:getSimpleCompanyInfoResponse" />
</wsdl:message>

<wsdl:portType name="MonitoringControllerPortType">
    <wsdl:operation name="getSimpleCompanyInfo">
        <wsdl:input message="tns:getSimpleCompanyInfoRequest" />
        <wsdl:output message="tns:getSimpleCompanyInfoResponse" />
    </wsdl:operation>
</wsdl:portType>

<wsdl:binding name="MonitoringControllerBinding" type="tns:MonitoringControllerPortType">
    <soap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http" />

    <wsdl:operation name="getSimpleCompanyInfo">
        <soap:operation soapAction="[domain]/#getSimpleCompanyInfo" style="rpc" />
        <wsdl:input>
            <soap:body use="literal" namespace="[namespaceUri]" />
        </wsdl:input>
        <wsdl:output>
            <soap:body use="literal" namespace="[namespaceUri]" />
        </wsdl:output>
    </wsdl:operation>
</wsdl:binding>

<wsdl:service name="MonitoringControllerService">
    <wsdl:port name="MonitoringControllerPort" binding="tns:MonitoringControllerBinding">
        <soap:address location="[serviceUri]" />
    </wsdl:port>
</wsdl:service>

工作服务:

<wsdl:message name="PersonnelInfoRequest">
    <wsdl:part name="PersonnelInfoRequest" type="tns:PersonnelInfoRequest" />
</wsdl:message>
<wsdl:message name="PersonnelInfoResponse">
    <wsdl:part name="PersonnelInfoResponse" type="tns:PersonnelInfoResponse" />
</wsdl:message>

<wsdl:portType name="ReportsControllerPortType">
    <wsdl:operation name="PersonnelInfo">
        <wsdl:input message="tns:PersonnelInfoRequest" />
        <wsdl:output message="tns:PersonnelInfoResponse" />
    </wsdl:operation>
</wsdl:portType>

<wsdl:binding name="ReportsControllerBinding" type="tns:ReportsControllerPortType">
    <soap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http" />
    <wsdl:operation name="PersonnelInfo">
        <soap:operation soapAction="[domain]/#PersonnelInfo" style="rpc" />
        <wsdl:input>
            <soap:body use="literal" namespace="[namespaceUri]" />
        </wsdl:input>
        <wsdl:output>
            <soap:body use="literal" namespace="[namespaceUri]" />
        </wsdl:output>
    </wsdl:operation>
</wsdl:binding>

<wsdl:service name="ReportsControllerService">
    <wsdl:port name="ReportsControllerPort" binding="tns:ReportsControllerBinding">
        <soap:address location="[serviceUri]" />
    </wsdl:port>
</wsdl:service>

编辑3:

ReportsControllerService MonitoringControllerService 扩展 javax.xml.ws.Service ,并包含所使用的.wsdl架构位置和命名空间的定义。服务类返回一个PortType对象,如下所示:

/**
 * This class was generated by the JAX-WS RI. JAX-WS RI 2.2.9-b130926.1035 Generated source version: 2.2
 */
@WebServiceClient(name = "ReportsControllerService", targetNamespace = "[namespaceUri]", wsdlLocation = "[wsdlUri]")
public class ReportsControllerService extends Service {

    @WebEndpoint(name = "ReportsControllerPort")
    public ReportsControllerPortType getReportsControllerPort() {
        return super.getPort(new QName("[namespaceUri]", "ReportsControllerPort"), ReportsControllerPortType.class);
    }
}

ReportsControllerPortType 是一个接口,其中包含服务中存在的每个操作端点的方法

/**
 * This class was generated by the JAX-WS RI. JAX-WS RI 2.2.9-b130926.1035 Generated source version: 2.2
 */
@WebService(name = "ReportsControllerPortType", targetNamespace = "[namespaceUri]")
@SOAPBinding(style = SOAPBinding.Style.RPC)
@XmlSeeAlso({ObjectFactory.class})
public interface ReportsControllerPortType {

    @WebMethod(operationName = "PersonnelInfo", action = "[actionName]")
    @WebResult(name = "PersonnelInfoResponse", partName = "PersonnelInfoResponse")
    public PersonnelInfoResponse personnelInfo(
        @WebParam(name = "PersonnelInfoRequest", partName = "PersonnelInfoRequest") PersonnelInfoRequest personnelInfoRequest);
    }
}

问题是,所有这些类都是由JAX-WS自动生成的(正如您可以从注释中看到的)基于.wsdl模式。实现在JDK内部被抽象,我也无法控制它。是的,我可以重构代码,所以我绕过了JAX-WS,但据我所知,这应该像事实上的标准方式来使用基于.wsdl的SOAP服务。

该项目使用Spring作为基础框架,我已经确认当我使用Spring-WS时这两种服务都可以工作,所以我可以重构但我想知道为什么这种方式不起作用。

2 个答案:

答案 0 :(得分:1)

我相信我可能已经发现为什么您的网络服务行为不端。根据规范,RPC网络服务必须在其soap绑定中满足以下条件(即您拥有的@SOAPBinding注释)

  1. style的{​​{1}}:检查

  2. RPC的{​​{1}}:检查

  3. use LITERAL的{​​{1}}:根据您提供的说明,parameterStyle似乎不属于这种情况,因为您看到的是{&1;}。在没有任何包装的情况下重新接收裸WRAPPED(并且可能发送裸WRAPPED}表示服务本身已损坏。

  4. 摘自the JAX-WS spec

      

    使用PersonnelInfoResponse样式需要使用PersonnelInfoRequest参数样式。偏离此是一个错误

答案 1 :(得分:0)

There is one obvious difference between your 2 calls :

You should try to remove operationName = "PersonnelInfo" from your second call which is not present in the first working one.