gpt4 book ai didi

java - 无法映射 SOAP 服务响应

转载 作者:塔克拉玛干 更新时间:2023-11-03 05:32:15 24 4
gpt4 key购买 nike

这个问题已经困扰我将近两天了,我真的需要一些帮助来解决这个问题。

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

第一个服务工作得很好,但由于某些原因,无法将来自第二个服务的响应解码为响应对象。

工作服务:

@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 为 null。

我能看到的唯一区别是 XML 中的第二个服务响应负载缺少外部元素,这似乎是问题所在。但是,我不知道如何“修复”它,因此它不寻找外部元素。

如果有任何不清楚或遗漏的地方,请告诉我,我会尽力为您提供所有信息。

编辑:

不,很遗憾,我无法控制服务本身,我只有 .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);

客户端服务 stub (ReportsControllerService & 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:

ReportsControllerServiceMonitoringControllerService 扩展 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 是一个接口(interface),它包含服务中存在的每个操作端点的方法

/**
* 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 时这两种服务都可以工作,因此我可以重构,但我想了解为什么这种方式不起作用。

最佳答案

我相信我可能已经发现您的网络服务运行异常的原因。根据规范,RPC 网络服务必须在其 soap 绑定(bind)中满足以下条件(即 @SOAPBinding 注释)

  1. RPC样式:校验

  2. LITERAL使用:检查

  3. WRAPPEDparameterStyle:从您给出的描述来看,WRAPPED 似乎不是这里的情况,当您收到一个没有任何包装的裸体 PersonnelInfoResponse(并且可能发送一个裸体 PersonnelInfoRequest)时,表明服务本身已损坏。

摘自 the JAX-WS spec :

Use of RPC style requires the use of WRAPPED parameter style. Deviations from this is an error

关于java - 无法映射 SOAP 服务响应,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30079342/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com