【问题标题】:How to call JAX WS from a stand alone java file?如何从独立的 java 文件中调用 JAX WS?
【发布时间】:2013-09-06 09:20:53
【问题描述】:

我正在尝试从独立的 java 类(包含 main 方法)调用 jax ws Web 服务。我已经在 SOAP UI 中尝试过,它会返回响应。

我的 Java 代码:ma​​in() 方法中:

GInformation getGMInfo = new GInformation();
GInformationResult getGMResult = new GInformationResult();

GKService GKProxy = getProxy();

//Set the Request
XMLGregorianCalendar xmlGreg = null;
getGMInfo.setRequestId("");
getGMInfo.setMessageDateTime(xmlGreg);

try {
    //Get the response
    getGMResult = GKProxy.getGInformation(getGMInfo);
    System.out.println("Address: "+getGMResult.getInfo());
} catch (OperationFaultException e) {
    e.printStackTrace();
} catch (SystemFaultException e) {
    e.printStackTrace();
} 

但它失败并出现这样的错误:

org.apache.axis2.AxisFault: WSWS7130E: No Secure Sockets Layer (SSL) configuration is available for the https://mklip.verd.Gin/WS/v2.8 endpoint.

我已经尝试纠正这个问题很长时间了,而且我快要发疯了。 有人能告诉我我在做什么错吗? 是否有可能从一个独立的 java 类调用 jax-ws 或者我们需要网络服务器吗?但是这个应用程序没有网络服务器。

【问题讨论】:

  • @PaulVargas :不要认为它是重复的。我知道这是证书问题。但真正的问题是如何绕过它?这里有解决方法吗?如果是这样,我该怎么做?还是我需要 wsdl 服务托管商的证书才能使其工作?
  • 只有当你想通过 HTTPS 调用服务器时才需要配置 SSL。如果您不想要安全连接,可以将地址更改为 HTTP 连接。

标签: java web-services jax-ws


【解决方案1】:

我不得不越来越深入地研究来解决这个问题。我遇到的问题是受信任的证书问题。所以首先,我得到了调用服务所需的证书(cert1.cer,cert2.cer)。

然后我使用以下步骤在本地集成证书:

1. Place the below cry certificates in the path "C:\Program Files\IBM\SDP\jdk\jre\lib\security"

   cert1.cer, cert2.cer 

2. cacerts is the trusStore file. It's present in :
   C:/Program Files/IBM/SDP/jdk/jre/lib/security/cacerts

3. In command prompt perform the below execution
C:\Program Files\IBM\SDP\jdk\jre\lib\security>"C:\Program Files\IBM\SDP\jdk\jre\bin\keytool" -import -alias cert1 -file cert1.cer -keystore cacerts

4. If it asks keystore password, mention changeit, which is the default keystore password

Enter keystore password: changeit

Trust this certificate? [no]:  yes
Certificate was added to keystore

5. Peform the steps 3 and 4 for the second certificate(cert2.cer).

但这还不够。我必须像这样以编程方式设置javax.net.ssl

System.setProperty("javax.net.ssl.trustStore", "C:\\Program Files\\IBM\\SDP\\jdk\\jre\\lib\\security\\cacerts");
System.setProperty("javax.net.ssl.trustStorePassword", "changeit");
System.setProperty("javax.net.ssl.keyStore", "C:\\Program Files\\IBM\\SDP\\jdk\\jre\\lib\\security\\cacerts");
System.setProperty("javax.net.ssl.keyStorePassword", "changeit");

以上几行代码确保trustStorekeyStore在WS调用期间为SSL调用设置好了。

这并不容易,因此我在这里提供了解释和答案,以便万一有人遇到同样的问题,那么他/她可以将其作为参考来缓解他们的问题。干杯!

【讨论】:

  • 如果您使用的 JRE 的证书受 cacerts 信任,为什么还需要显式设置 trustStorekeyStore
【解决方案2】:

将下面的行作为程序的第一行。这将解决问题。 System.setProperty("com.ibm.SSL.ConfigURL", "file:C:\IBM\WebSphere\AppServer\profiles\AppSrv01\properties\ssl.client.props");

【讨论】:

    【解决方案3】:

    您是否尝试将端点地址设置为您的网络服务地址。 就我而言,我使用客户端代码从 WSDL 文件生成 jar。

    我的测试用例中的一个例子是

    public static void main(String[] args){
              SecurityRefServiceLocator securityRefServiceLocator = new SecurityRefServiceLocator();
                securityRefServiceLocator.setSecurityrefPortEndpointAddress("http://xxxxx:13600/my_ss/webservice/refreshSecurity?wsdl");
                WebserviceClient webserviceClient = new WebserviceClient();
                webserviceClient.setSecurityRefServiceLocator(securityRefServiceLocator);
                System.out.println(webserviceClient.refreshSecurity(8798789l,"1114"));
    
    }
    
    }
    

    WeberviceClient 代码

    public WebServiceReturnCode refreshSecurity(Long securityId, String productId) {
    
        try{
            SecurityRef securityRef = securityRefServiceLocator.getSecurityrefPort();
    
            SecurityServiceBindingStub  securityServiceBindingStub=
                (SecurityServiceBindingStub) securityRef;
    
            securityServiceBindingStub.setUsername("user");
            securityServiceBindingStub.setPassword("password");
    
            securityServiceBindingStub.setTimeout(timeout);
    
            SecurityServiceRequest parameter = new SecurityServiceRequest();
    
            parameter.setMessageId("MSG-" + securityId);
            parameter.setSecurityId(securityId.toString());
            SecurityServiceResponse refreshSecurity = securityRef.refreshSecurity(parameter);
            ResponseType msgResponse = refreshSecurity.getMsgResponse();
            //evaluate msg response and send E200; if fail
            if(msgResponse.equals(ResponseType.SUCCESS)){
                return WebServiceReturnCode.SUCCESS;
            }
            // Response was not favorable
            return "WSE200";
    
        }catch(Exception e){
            // Exception occurred. Mark this as technical failure to webservice call.
            return "WSE100";
        }finally{
    }
    }
    
    public SecurityRefServiceLocator getSecurityRefServiceLocator() {
        return securityRefServiceLocator;
    }
    
    public void setSecurityRefServiceLocator(
            SecurityRefServiceLocator securityRefServiceLocator) {
        this.securityRefServiceLocator = securityRefServiceLocator;
    }
    

    【讨论】:

    • 是的,我已经尝试过使用这段代码:bp.getRequestContext().put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, "https://mklip.verd.Gin/WS/v2.8?wsdl");。这不起作用并给出相同的异常。
    • 你能不能尝试按照我的方式......从 wsdl 生成客户端代码。请获取从 URL 生成的 WSDL 文件。然后尝试测试它。我在这里看到的唯一区别是您的 URL 具有 SSL,而在我的情况下它不是安全 URL。可能这需要不同的方法,我会对此进行平行研究。
    • 从端点 url 获取 WSDL 文件并不是一个好主意。有时,您从这样的 url 获得的 wsdl 会在没有适当的 xsd 引用的情况下为您提供不发达的 wsdl(就像在我的情况下,我什至无法使用该 wsdl 生成客户端,因为它给了我几个 wsdl parsing errors ,因为它没有正确的 xsd 引用)。所以我使用旧的 wsdl 并使用我上面发布的答案来解决 SSL 配置问题。
    猜你喜欢
    • 1970-01-01
    • 2010-11-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多