无法使用Java客户端访问asmx soap Web服务

时间:2014-01-16 12:48:54

标签: java xml web-services soap wsdl

我正在尝试使用java访问asmx webservice: wsdl如下:

<wsdl:definitions xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tm="http://microsoft.com/wsdl/mime/textMatching/" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/" xmlns:tns="http://infotelconnect.com/" xmlns:s="http://www.w3.org/2001/XMLSchema" xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/" xmlns:http="http://schemas.xmlsoap.org/wsdl/http/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" targetNamespace="http://infotelconnect.com/">
<wsdl:types>
<s:schema elementFormDefault="qualified" targetNamespace="http://infotelconnect.com/">
<s:element name="chk_mob">
<s:complexType>
<s:sequence>
<s:element minOccurs="0" maxOccurs="1" name="directorynumber" type="s:string"/>
<s:element minOccurs="0" maxOccurs="1" name="email" type="s:string"/>
<s:element minOccurs="0" maxOccurs="1" name="alternate" type="s:string"/>
</s:sequence>
</s:complexType>
</s:element>
<s:element name="chk_mobResponse">
<s:complexType>
<s:sequence>
<s:element minOccurs="0" maxOccurs="1" name="chk_mobResult" type="tns:Responsevalid"/>
</s:sequence>
</s:complexType>
</s:element>
<s:complexType name="Responsevalid">
<s:sequence>
<s:element minOccurs="0" maxOccurs="1" name="errcd" type="s:string"/>
<s:element minOccurs="0" maxOccurs="1" name="err" type="s:string"/>
<s:element minOccurs="0" maxOccurs="1" name="subaccnum" type="s:string"/>
<s:element minOccurs="0" maxOccurs="1" name="accnum" type="s:string"/>
<s:element minOccurs="0" maxOccurs="1" name="altnum" type="s:string"/>
</s:sequence>
</s:complexType>
<s:element name="AuthHeader" type="tns:AuthHeader"/>
<s:complexType name="AuthHeader">
<s:sequence>
<s:element minOccurs="0" maxOccurs="1" name="Username" type="s:string"/>
<s:element minOccurs="0" maxOccurs="1" name="Password" type="s:string"/>
<s:element minOccurs="0" maxOccurs="1" name="IP" type="s:string"/>
</s:sequence>
<s:anyAttribute/>
</s:complexType>
</s:schema>
</wsdl:types>
<wsdl:message name="chk_mobSoapIn">
<wsdl:part name="parameters" element="tns:chk_mob"/>
</wsdl:message>
<wsdl:message name="chk_mobSoapOut">
<wsdl:part name="parameters" element="tns:chk_mobResponse"/>
</wsdl:message>
<wsdl:message name="chk_mobAuthHeader">
<wsdl:part name="AuthHeader" element="tns:AuthHeader"/>
</wsdl:message>
<wsdl:portType name="DNvalidationSoap">
<wsdl:operation name="chk_mob">
<wsdl:documentation xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/">Validate Directory Number!</wsdl:documentation>
<wsdl:input message="tns:chk_mobSoapIn"/>
<wsdl:output message="tns:chk_mobSoapOut"/>
</wsdl:operation>
</wsdl:portType>
<wsdl:binding name="DNvalidationSoap" type="tns:DNvalidationSoap">
<soap:binding transport="http://schemas.xmlsoap.org/soap/http"/>
<wsdl:operation name="chk_mob">
<soap:operation soapAction="http://infotelconnect.com/chk_mob" style="document"/>
<wsdl:input>
<soap:body use="literal"/>
<soap:header message="tns:chk_mobAuthHeader" part="AuthHeader" use="literal"/>
</wsdl:input>
<wsdl:output>
<soap:body use="literal"/>
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<wsdl:binding name="DNvalidationSoap12" type="tns:DNvalidationSoap">
<soap12:binding transport="http://schemas.xmlsoap.org/soap/http"/>
<wsdl:operation name="chk_mob">
<soap12:operation soapAction="http://infotelconnect.com/chk_mob" style="document"/>
<wsdl:input>
<soap12:body use="literal"/>
<soap12:header message="tns:chk_mobAuthHeader" part="AuthHeader" use="literal"/>
</wsdl:input>
<wsdl:output>
<soap12:body use="literal"/>
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<wsdl:service name="DNvalidation">
<wsdl:port name="DNvalidationSoap" binding="tns:DNvalidationSoap">
<soap:address location="https://202.164.33.157:7074/DNvalidation.asmx"/>
</wsdl:port>
<wsdl:port name="DNvalidationSoap12" binding="tns:DNvalidationSoap12">
<soap12:address location="https://202.164.33.157:7074/DNvalidation.asmx"/>
</wsdl:port>
</wsdl:service>
</wsdl:definitions>

和netbeans生成的客户端代码如下:

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package org.eclat.client;

import com.sun.xml.ws.security.soap12.Header;
import com.sun.xml.wss.XWSSConstants;
import java.security.SecureRandom;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import javax.xml.soap.SOAPElement;
import javax.xml.soap.SOAPFactory;
import javax.xml.ws.BindingProvider;
import javax.xml.ws.handler.MessageContext;
import org.eclat.vtlservice.AuthHeader;
import org.eclat.vtlservice.Responsevalid;
import org.eclat.vtlservice.DNvalidation;
import org.eclat.vtlservice.DNvalidationSoap;

/**
 *
 * @author surjit
 */
public class Client {

    private static final String WS_URL = "https://202.164.33.157:7074/DNvalidation.asmx?WSDL";


    private static void trustEveryone() { 
     try { 
             HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier(){ 
                     public boolean verify(String hostname, SSLSession session) { 
                             return true; 
                     }}); 
             SSLContext context = SSLContext.getInstance("TLS"); 
             context.init(null, new X509TrustManager[]{new X509TrustManager(){ 
                     public void checkClientTrusted(X509Certificate[] chain, 
                                     String authType) throws CertificateException {} 
                     public void checkServerTrusted(X509Certificate[] chain, 
                                     String authType) throws CertificateException {} 
                     public X509Certificate[] getAcceptedIssuers() { 
                             return new X509Certificate[0]; 
                     }}}, new SecureRandom()); 
             HttpsURLConnection.setDefaultSSLSocketFactory( 
                             context.getSocketFactory()); 
     } catch (Exception e) { // should never happen 
             e.printStackTrace(); 
     } 
 }

    public static  Responsevalid chkMob(String directorynumber, String email, String alternate) {

        DNvalidation service = new org.eclat.vtlservice.DNvalidation();
        DNvalidationSoap port = service.getDNvalidationSoap();

        Map<String, Object> requestContext = ((BindingProvider)port).getRequestContext();

        requestContext.put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, WS_URL);
        Map<String, List<String>> requestHeaders = new HashMap<String, List<String>>();
        requestHeaders.put("Username", Collections.singletonList("username"));
        requestHeaders.put("Password", Collections.singletonList("password"));
        requestHeaders.put("IP", Collections.singletonList("IP"));
        requestContext.put(MessageContext.HTTP_REQUEST_HEADERS, requestHeaders);

        return port.chkMob(directorynumber, email, alternate);

    }

    public static void main(String args[]) {  
        trustEveryone();
       System.out.println(chkMob("parameter1","parameter2","parameter3")); 
    }

}


But when I am running this code..I am getting following error:



Jan 16, 2014 5:38:47 PM [com.sun.xml.ws.policy.jaxws.PolicyConfigParser]  parse
INFO: WSP5018: Loaded WSIT configuration from file: file:/E:/New%20Workspace/src/service/build/web/WEB-INF/classes/META-INF/wsit-client.xml.
Exception in thread "main" javax.xml.ws.soap.SOAPFaultException: System.Web.Services.Protocols.SoapException: Server was unable to process request. ---> System.NullReferenceException: Object reference not set to an instance of an object.
   at DNvalidation.chk_mob(String directorynumber, String email, String alternate) in d:\QTLAPI\App_Code\DNvalidation.cs:line 57
   --- End of inner exception stack trace ---
    at com.sun.xml.ws.fault.SOAP11Fault.getProtocolException(SOAP11Fault.java:189)
    at com.sun.xml.ws.fault.SOAPFaultBuilder.createException(SOAPFaultBuilder.java:122)
    at com.sun.xml.ws.client.sei.SyncMethodHandler.invoke(SyncMethodHandler.java:119)
    at com.sun.xml.ws.client.sei.SyncMethodHandler.invoke(SyncMethodHandler.java:89)
    at com.sun.xml.ws.client.sei.SEIStub.invoke(SEIStub.java:140)
    at com.sun.proxy.$Proxy37.chkMob(Unknown Source)
    at org.eclat.client.Client.chkMob(Client.java:85)`enter code here`
    at org.eclat.client.Client.main(Client.java:91)
Java Result: 1

请建议任何解决方案,以便我能够访问此网络服务。

1 个答案:

答案 0 :(得分:0)

请优化您的代码,您没有正确地为此Web服务形成请求消息。 我认为这条线造成了问题。

return port.chkMob(directorynumber, email, alternate);

首先,它是一个soap webservice,你的请求消息结构应该是这样的,

    <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:inf="http://infotelconnect.com/">
   <soapenv:Header>
      <inf:AuthHeader>
         <!--Optional:-->
         <inf:Username>?</inf:Username>
         <!--Optional:-->
         <inf:Password>?</inf:Password>
         <!--Optional:-->
         <inf:IP>?</inf:IP>
      </inf:AuthHeader>
   </soapenv:Header>
   <soapenv:Body>
      <inf:chk_mob>
         <!--Optional:-->
         <inf:directorynumber>?</inf:directorynumber>
         <!--Optional:-->
         <inf:email>?</inf:email>
         <!--Optional:-->
         <inf:alternate>?</inf:alternate>
      </inf:chk_mob>
   </soapenv:Body>
</soapenv:Envelope>

你在这里形成标题,

Map<String, Object> requestContext = ((BindingProvider)port).getRequestContext();

    requestContext.put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, WS_URL);
    Map<String, List<String>> requestHeaders = new HashMap<String, List<String>>();
    requestHeaders.put("Username", Collections.singletonList("username"));
    requestHeaders.put("Password", Collections.singletonList("password"));
    requestHeaders.put("IP", Collections.singletonList("IP"));
    requestContext.put(MessageContext.HTTP_REQUEST_HEADERS, requestHeaders);

但是在调用webservice操作chk_mob时,

return port.chkMob(directorynumber, email, alternate);

你只是提供参数1,参数2,参数3作为字符串,你在main行中给出了这一行,

System.out.println(chkMob("parameter1","parameter2","parameter3"));

首先制作一个我上面提到的合适的肥皂信封,然后通过在该电话中提供你的肥皂信封来进行网络服务电话。您可以在线找到大量有关此Java客户端的示例和教程。仅供参考,我使用了soapui来生成你的请求消息结构。