【问题标题】:Java web service method receiving null argument from C# clientJava Web 服务方法从 C# 客户端接收空参数
【发布时间】:2011-11-18 06:21:20
【问题描述】:

我正在开发一个 Java 6 应用程序服务器,该服务器具有用于接收包含 HL7 消息的 SOAP 消息的 Web 服务。 Java 应用程序在 Glassfish 3.1 上运行。客户端是第三方开发的 C# 应用程序(在 Microsoft .net 4.0 框架上运行),它将这些 SOAP 消息发送到 Java 服务器。

我最初的问题是客户端无法解析服务器生成的 WSDL。我已经通过实现我自己的自定义 WSDL 并相应地调整它来解决这个问题。这允许客户端解析 WSDL 并将 SOAP 消息发送到我的 Java 服务器应用程序。

但是,每次在服务器端收到消息时,参数(名为“putXML”)都会收到一个null 值。

Glassfish 服务器日志在收到消息时显示以下内容:

Received WS-I BP non-conformant Unquoted SoapAction HTTP header: http://MyProject.MyPackage/putHL7Data
Received Message: null

这是我创建并与我的 SOAP Web 服务关联的自定义 WSDL:

<?xml version="1.0" encoding="utf-8"?>
<wsdl:definitions
      targetNamespace="http://MyProject.MyPackage/"
      xmlns="http://schemas.xmlsoap.org/wsdl/"
      xmlns:http="http://schemas.xmlsoap.org/wsdl/http/" 
      xmlns:s="http://www.w3.org/2001/XMLSchema"
      xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" 
      xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/" 
      xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" 
      xmlns:tm="http://microsoft.com/wsdl/mime/textMatching/"
      xmlns:tns="http://MyProject.MyPackage/" 
      xmlns:wsam="http://www.w3.org/2007/05/addressing/metadata" 
      xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
      xmlns:wsp="http://www.w3.org/ns/ws-policy" 
      xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"
      xmlns:xsd="http://www.w3.org/2001/XMLSchema">   
   <wsdl:types>
      <s:schema elementFormDefault="qualified" targetNamespace="http://MyProject.MyPackage/">
         <s:element name="putHL7Data">
            <s:complexType>
               <s:sequence>
                  <s:element name="putXML" type="s:string" minOccurs="0" maxOccurs="1"/>
               </s:sequence>
            </s:complexType>
         </s:element>
         <s:element name="putHL7DataResponse">
            <s:complexType>
               <s:sequence>
                  <s:element name="return" type="s:string" minOccurs="0" maxOccurs="1"/>
               </s:sequence>
            </s:complexType>
         </s:element>
      </s:schema>
   </wsdl:types>
   <wsdl:message name="putHL7DataSoapIn">
      <wsdl:part name="parameters" element="tns:putHL7Data"/>
   </wsdl:message>
   <wsdl:message name="putHL7DataSoapOut">
      <wsdl:part name="parameters" element="tns:putHL7DataResponse"/>
   </wsdl:message>
   <wsdl:portType name="MyHandlerSoap">
      <wsdl:operation name="putHL7Data">
         <wsdl:input message="tns:putHL7DataSoapIn"/>
         <wsdl:output message="tns:putHL7DataSoapOut"/>
      </wsdl:operation>
   </wsdl:portType>
   <wsdl:binding name="MyHandlerSoap" type="tns:MyHandlerSoap">
      <soap:binding transport="http://schemas.xmlsoap.org/soap/http" style="document"/>
      <wsdl:operation name="putHL7Data">
         <wsdl:input>
            <soap:body use="literal"/>
         </wsdl:input>
         <wsdl:output>
            <soap:body use="literal"/>
         </wsdl:output>
      </wsdl:operation>
   </wsdl:binding>
   <wsdl:service name="MyHandler">
      <wsdl:port name="MyHandlerPort" binding="tns:MyHandlerSoap">
         <soap:address location="REPLACE_WITH_ACTUAL_URL"/>
      </wsdl:port>
   </wsdl:service>
</wsdl:definitions>

这里是 Java 网络服务:

@WebService(serviceName = "MyHandler", wsdlLocation = "WEB-INF/wsdl/MyHandler.wsdl")
public class MyHandler {
   @WebMethod(operationName = "putHL7Data")
   public String putHL7Data(@WebParam(name = "putXML") String xml) {
      // Handle message
   }
}

是不是我做错了什么?

我可以做些什么来修复 Java Web 服务以使其正确接收非空值?

这是客户端的问题吗?如果是这样,我需要创建某种拦截器吗?

更新

今天我尝试创建一个使用我的 Java SOAP Web 服务的快速 C# 客户端。下面是代码:

namespace TestSoap
{
    class Program
    {
        static void Main(string[] args)
        {
            ServiceReference1.MyHandlerSoapClient ws = new ServiceReference1.MyHandlerSoapClient();
            string result = ws.putHL7Data("Test");    
            Console.WriteLine("Response: " + result);
            Console.ReadLine();
        }
    }
}

当我运行此客户端时,我在参数中收到相同的 null 值,而我希望看到 Test 字符串。另外,我希望 result 包含一个响应字符串,但它也返回一个 null 值。

请记住,我无法修改第三方 C# 客户端应用程序。 Java端有什么我可以做的吗?

更新 2

我最近添加了一个处理程序链类,用于捕获和记录原始 SOAP 消息。客户端发送的消息如下所示:

<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <soap:Header/>
  <soap:Body>
    <putHL7Data xmlns="http://MyProject.MyPackage/">
      <putXML>... Encoded XML Here ...</putXML>
    </putHL7Data>
  </soap:Body>
</soap:Envelope>

【问题讨论】:

  • 服务器接收到 null 似乎是因为客户端在请求中包含了参数。
  • @DwB 我不确定你的意思。你能详细说明一下吗?
  • 源语言对 Web 服务调用的影响为零。如果服务调用的参数在服务器中为空,那是因为它是从客户端作为空发送的。
  • @DwB 我知道客户端正在发送一个非空字符串。
  • 你捕获到HTTP请求了吗?如果您捕获了请求,您只能知道它正在发送一个非空字符串。假设这是真的,那么 null 只能是从 HTTP 请求中的 xml 到调用 java 代码的转换失败的结果。如果是这种情况,我怀疑有问题的参数在客户端编码不正确。例如。服务器期望 并且客户端发送 kpow

标签: java web-services soap wsdl glassfish-3


【解决方案1】:

我的 glassfish 控制台中有相同的消息。在我的带有 ksoap 功能的 android 项目中,我更改了以下代码:

soapEnvelope.setOutputSoapObject(soapReq);
HttpTransportSE httpTransport = new HttpTransportSE(url,timeOut);
try{

        if (headers!=null){
            // original code // my headers are null
            httpTransport.call("http://service.iswitch.com/", soapEnvelope,headers);
        }else{
            httpTransport.call("\"http://service.iswitch.com/"\", soapEnvelope);
        }
        SoapObject result=(SoapObject)soapEnvelope.bodyIn;
        if (result.hasProperty("moveResult"))
        {

.... 它有效...);

我用http://www.wsdl2code.com生成的类

【讨论】:

    【解决方案2】:

    @dlawrence 指出正确的方向后,我能够解决我的问题。正如我在问题中提到的,我仍然需要使用自定义构建的 wsdl。我只需要对 wsdl 和 Java 代码进行一些更改即可解决问题。

    这是代表我对 wsdl 所做更改的差异:

    --- /tmp/a  2011-09-19 15:05:21.132065003 -0400
    +++ /tmp/b  2011-09-19 14:41:28.302064999 -0400
    @@ -15,11 +15,11 @@
           xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"
           xmlns:xsd="http://www.w3.org/2001/XMLSchema">   
        <wsdl:types>
    -      <s:schema elementFormDefault="qualified" targetNamespace="http://MyProject.MyPackage/">
    +      <s:schema targetNamespace="http://MyProject.MyPackage/">        
              <s:element name="putHL7Data">
                 <s:complexType>
                    <s:sequence>
    -                  <s:element name="putXML" type="s:string" minOccurs="0" maxOccurs="1"/>
    +                  <s:element name="putXML" type="s:string" form="qualified" minOccurs="0" maxOccurs="1"/>
                    </s:sequence>
                 </s:complexType>
              </s:element>
    @@ -47,6 +47,6 @@
        <wsdl:binding name="MyHandlerSoap" type="tns:MyHandlerSoap">
           <soap:binding transport="http://schemas.xmlsoap.org/soap/http" style="document"/>
           <wsdl:operation name="putHL7Data">
    -         <soap:operation soapAction="" style="document"/>
    +         <soap:operation soapAction="http://MyProject.MyPackage/putHL7Data" style="document"/>
              <wsdl:input>
                 <soap:body use="literal"/>
              </wsdl:input>
    

    基本上这是一个由三部分组成的修复...
    1)。我需要从&lt;s:schema&gt; 标记中删除elementFormDefault="qualified" 属性。
    2)。然后我必须在我的&lt;s:element name="putXML" ...&gt; 标签上添加属性form="qualified"
    3)。最后,我需要确保我的&lt;soap:operation&gt; 标签上有soapAction="http://MyProject.MyPackage/putHL7Data" 属性。

    这是我对 Java Web 方法所做更改的差异:

    --- /tmp/a  2011-09-19 14:57:49.582065002 -0400
    +++ /tmp/b  2011-09-19 15:00:06.942065007 -0400
    @@ -1,7 +1,7 @@
     @WebService(serviceName = "MyHandler", wsdlLocation = "WEB-INF/wsdl/MyHandler.wsdl")
     public class MyHandler {
        @WebMethod(operationName = "putHL7Data")
    -   public String putHL7Data(@WebParam(name = "putXML") String xml) {
    +   public String putHL7Data(@WebParam(name = "putXML", targetNamespace="http://MyProject.MyPackage/") String xml) {
           // Handle message
        }
     }
    

    如您所见,我所要做的就是将targetNamespace 属性添加到我的@WebParam

    【讨论】:

      【解决方案3】:

      您是否尝试过删除@WebParam 属性?它不应该是必需的,因为您的网络服务在这里没有歧义,并且您可能需要设置 targetNamespace 才能正确找到属性。

      【讨论】:

      • 我尝试删除“@WebParam”,但没有任何效果。 “targetNamespace”会去哪里?在“@WebParam”定义中?
      • 是的,应该是@WebParam的一个属性。
      • 感谢您的提示!通过查看将“targetNamespace”添加到生成的 wsdl 的作用,我能够弄清楚如何调整我的自定义 wsdl。我将很快发布我自己的答案,解释我为解决问题所做的工作。
      • 有类似问题,将 targetNamespce 添加到 WebParam 有帮助
      猜你喜欢
      • 2017-12-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-09-04
      • 2019-04-02
      • 2022-01-09
      • 2022-06-16
      相关资源
      最近更新 更多