为啥我可以将 Web 服务用作 Java 应用程序,但不能使用 struts2

Posted

技术标签:

【中文标题】为啥我可以将 Web 服务用作 Java 应用程序,但不能使用 struts2【英文标题】:Why am I able to use web service as a java application but not possible with struts2为什么我可以将 Web 服务用作 Java 应用程序,但不能使用 struts2 【发布时间】:2013-11-24 11:14:29 【问题描述】:

我正在创建一个Web服务客户端。以下是需要注意的点:

我不应该将证书添加到 cacerts 或 jssecacert(任何密钥库)。 所以我使用的是幼稚的信任管理器(信任所有证书) 当我将其作为常规 Java 应用程序执行时,我能够使用 Web 服务并获得结果。 如果我将相同的代码复制到我的 struts2 中,它就不起作用。

代码是:

import java.net.MalformedURLException;
import java.net.URL;
import java.security.GeneralSecurityException;

import javax.net.ssl.*;

public class main 

/**
 * @param args
 */

static 
    System.out.println("Inside static block");
    HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier() 
        @Override
        public boolean verify(String hostname, SSLSession arg1) 
            // TODO Auto-generated method stub
            if (hostname.equals("***.***.**.**")) 
                System.out.println("verify success");
                return true;
            
            System.out.println("Verify unsuccessful");
            return false;
        
    );




public static void main(String[] args) 
    // TODO Auto-generated method stub

    // Create a trust manager that does not validate certificate chains
    TrustManager[] trustAllCerts = new TrustManager[]  new X509TrustManager() 
        public java.security.cert.X509Certificate[] getAcceptedIssuers() 
            return null;
        

        public void checkClientTrusted(
                java.security.cert.X509Certificate[] certs, String authType) 
        

        public void checkServerTrusted(
                java.security.cert.X509Certificate[] certs, String authType) 
        
     ;
    // Install the all-trusting trust manager
    try 
        SSLContext sc = SSLContext.getInstance("SSL");
        sc.init(null, trustAllCerts, new java.security.SecureRandom());
        HttpsURLConnection
                .setDefaultSSLSocketFactory(sc.getSocketFactory());
     catch (GeneralSecurityException e) 
    
    // Now you can access an https URL without having the certificate in the
    // truststore
    try 
        URL url = new URL(
                "https://path.service.asmx?WSDL");
     catch (MalformedURLException e) 
    

    Service o_service = new Service();
    ServiceSoap o_serServiceSoap = o_service.getServiceSoap();
    System.out.println(o_serServiceSoap.getUserInformation("information",
            "information", "information", "information", "information"));




复制到我的 struts2 项目中的相同代码会出现以下异常:

Caused by: javax.net.ssl.SSLHandshakeException: SSLHandshakeException invoking https://path.service.asmx: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(Unknown Source)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(Unknown Source)
    at java.lang.reflect.Constructor.newInstance(Unknown Source)
    at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.mapException(HTTPConduit.java:1338)
    at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.close(HTTPConduit.java:1322)
    at org.apache.cxf.transport.AbstractConduit.close(AbstractConduit.java:56)
    at org.apache.cxf.transport.http.HTTPConduit.close(HTTPConduit.java:627)
    at org.apache.cxf.interceptor.MessageSenderInterceptor$MessageSenderEndingInterceptor.handleMessage(MessageSenderInterceptor.java:62)
    ... 79 more
Caused by: javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
    at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Unknown Source)
    at com.sun.net.ssl.internal.ssl.SSLSocketImpl.fatal(Unknown Source)
    at com.sun.net.ssl.internal.ssl.Handshaker.fatalSE(Unknown Source)
    at com.sun.net.ssl.internal.ssl.Handshaker.fatalSE(Unknown Source)
    at com.sun.net.ssl.internal.ssl.ClientHandshaker.serverCertificate(Unknown Source)
    at com.sun.net.ssl.internal.ssl.ClientHandshaker.processMessage(Unknown Source)
    at com.sun.net.ssl.internal.ssl.Handshaker.processLoop(Unknown Source)
    at com.sun.net.ssl.internal.ssl.Handshaker.process_record(Unknown Source)
    at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readRecord(Unknown Source)
    at com.sun.net.ssl.internal.ssl.SSLSocketImpl.performInitialHandshake(Unknown Source)
    at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(Unknown Source)
    at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(Unknown Source)
    at sun.net.www.protocol.https.HttpsClient.afterConnect(Unknown Source)
    at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(Unknown Source)
    at sun.net.www.protocol.http.HttpURLConnection.getOutputStream(Unknown Source)
    at sun.net.www.protocol.https.HttpsURLConnectionImpl.getOutputStream(Unknown Source)
    at org.apache.cxf.transport.http.URLConnectionHTTPConduit$URLConnectionWrappedOutputStream.setupWrappedStream(URLConnectionHTTPConduit.java:168)
    at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.handleHeadersTrustCaching(HTTPConduit.java:1282)
    at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.onFirstWrite(HTTPConduit.java:1238)
    at org.apache.cxf.transport.http.URLConnectionHTTPConduit$URLConnectionWrappedOutputStream.onFirstWrite(URLConnectionHTTPConduit.java:195)
    at org.apache.cxf.io.AbstractWrappedOutputStream.write(AbstractWrappedOutputStream.java:47)
    at org.apache.cxf.io.AbstractThresholdOutputStream.write(AbstractThresholdOutputStream.java:69)
    at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.close(HTTPConduit.java:1295)
    ... 82 more
Caused by: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
    at sun.security.validator.PKIXValidator.doBuild(Unknown Source)
    at sun.security.validator.PKIXValidator.engineValidate(Unknown Source)
    at sun.security.validator.Validator.validate(Unknown Source)
    at com.sun.net.ssl.internal.ssl.X509TrustManagerImpl.validate(Unknown Source)
    at com.sun.net.ssl.internal.ssl.X509TrustManagerImpl.checkServerTrusted(Unknown Source)
    at com.sun.net.ssl.internal.ssl.X509TrustManagerImpl.checkServerTrusted(Unknown Source)
    ... 101 more
Caused by: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
    at sun.security.provider.certpath.SunCertPathBuilder.engineBuild(Unknown Source)
    at java.security.cert.CertPathBuilder.build(Unknown Source)

有人可以帮我解决这个问题吗?谢谢。

【问题讨论】:

在这一点catch (GeneralSecurityException e) 你可能会吞下问题的原因。将其替换为catch (GeneralSecurityException e) throw new RuntimeException(e); 你要把这个放到行动课上吗?主要方法? 当它无法访问信任库和/或密钥库时有时会引发该错误(检查 javax.net.ssl.keystore 和 javax.net.ssl.truststore 系统属性以查看您指的是谁) @NGoyal:是的,我将其放入动作类中。 你能把代码贴在这里吗...动作类...也许可以给出清晰的画面.. 【参考方案1】:

[...] 还有 79 个原因:javax.net.ssl.SSLHandshakeException:sun.security.validator.ValidatorException:PKIX 路径构建失败:sun。 security.provider.certpath.SunCertPathBuilderException:无法在 com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Unknown Source) 中找到请求目标的有效证书路径 ) 在 [...]

这是堆栈跟踪的重要部分。

This article 解释发生了什么以及如何解决它。

您可以尝试关注Mkyong article(基于上述),这可能会更容易一些。

同时确保您已将应用服务器配置为支持 SSL 和 HTTPS (Tomcat Example)。

【讨论】:

我浏览了那篇文章。但我的第一个也是最重要的标准是我不想安装证书。有没有其他办法?

以上是关于为啥我可以将 Web 服务用作 Java 应用程序,但不能使用 struts2的主要内容,如果未能解决你的问题,请参考以下文章

您可以将 iPhone 用作 Web 开发人员吗?服务器? [复制]

Java 或 PHP 服务器端 Web 应用程序,为啥? [关闭]

为啥在 Web 推送库上使用推送通知服务?

服务器启动的java服务为啥会自动关闭

是否可以将 iCloud 中的 Core Data 用作服务器,将 iPad 用作客户端?

java web项目在eclipse内测浏览器可以打开 为啥在外浏览器打不显示404?