You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

将IBMMQ(队列和主题)REST API转为Java时遇ValidatorException异常

IBM MQ REST API Java调用SSL握手异常解决方案

问题本质

你遇到的SSLHandshakeException是因为JVM默认不信任IBM MQ REST服务使用的SSL证书(大概率是自签名证书),导致无法完成SSL握手。而CURL能正常运行,是因为它默认跳过了证书验证环节,或者已经配置了信任该证书。

解决方案

方案1:测试环境临时绕过验证(禁止生产环境使用)

通过自定义SSL信任管理器,让Java代码信任所有证书,快速解决测试阶段的问题。修改后的完整代码如下:

import javax.net.ssl.*;
import java.io.IOException;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.X509Certificate;

public class IbmmqQueue {

    // 初始化信任所有证书的SSL上下文
    static {
        try {
            TrustManager[] trustAllCerts = new TrustManager[]{
                new X509TrustManager() {
                    public X509Certificate[] getAcceptedIssuers() { return null; }
                    public void checkClientTrusted(X509Certificate[] certs, String authType) {}
                    public void checkServerTrusted(X509Certificate[] certs, String authType) {}
                }
            };

            SSLContext sc = SSLContext.getInstance("SSL");
            sc.init(null, trustAllCerts, new java.security.SecureRandom());
            HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());

            // 禁用主机名验证
            HostnameVerifier allHostsValid = (hostname, session) -> true;
            HttpsURLConnection.setDefaultHostnameVerifier(allHostsValid);
        } catch (NoSuchAlgorithmException | KeyManagementException e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) throws IOException {
        URL url = new URL("https://localhost:9443/ibmmq/rest/v1/admin/qmgr/QM1/queue");
        HttpURLConnection http = (HttpURLConnection) url.openConnection();
        http.setRequestMethod("POST");
        http.setDoOutput(true);
        http.setRequestProperty("Content-Type", "application/json");
        http.setRequestProperty("license", "accept");
        http.setRequestProperty("Authorization", "Basic YWRtaW46cGFzc3cwcmQ=");
        http.setRequestProperty("ibm-mq-rest-csrf-token", ";");

        String data = "{\n   \"name\": \"fourthQueue1\",\n   \"type\": \"local\",\n \n   \"storage\" : {\n      \"maximumDepth\" : 5000\n   }\n}";

        byte[] out = data.getBytes(StandardCharsets.UTF_8);

        OutputStream stream = http.getOutputStream();
        stream.write(out);

        System.out.println(http.getResponseCode() + " " + http.getResponseMessage());
        http.disconnect();
    }
}

方案2:生产环境正规处理(推荐)

将IBM MQ的SSL证书导入到JVM的信任证书库中,让JVM合法信任该证书:

  1. 导出MQ REST服务的证书
    执行以下OpenSSL命令(需安装OpenSSL):

    openssl s_client -connect localhost:9443 < /dev/null | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' > mq-rest-cert.crt
    
  2. 将证书导入JVM信任库
    找到你的JRE安装目录下的lib/security/cacerts文件,执行以下keytool命令(默认密码为changeit):

    keytool -import -alias mq-rest-cert -file mq-rest-cert.crt -keystore $JAVA_HOME/jre/lib/security/cacerts
    

    执行过程中输入yes确认信任该证书。

  3. 重启Java应用
    让JVM加载更新后的信任库,之后再运行代码即可正常建立SSL连接。


附:原问题代码与异常信息

原Java代码

import javax.net.ssl.*;
import java.io.IOException;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.X509Certificate;

public class IbmmqQueue {

        public static void main(String[] args) throws IOException {
            
            URL url = new URL("https://localhost:9443/ibmmq/rest/v1/admin/qmgr/QM1/queue");
            HttpURLConnection http = (HttpURLConnection)url.openConnection();
            http.setRequestMethod("POST");
            http.setDoOutput(true);
            http.setRequestProperty("Content-Type", "application/json");
            http.setRequestProperty("license", "accept");
            http.setRequestProperty("Authorization", "Basic YWRtaW46cGFzc3cwcmQ=");
            http.setRequestProperty("ibm-mq-rest-csrf-token", ";");

            String data = "{\n   \"name\": \"fourthQueue1\",\n   \"type\": \"local\",\n \n   \"storage\" : {\n      \"maximumDepth\" : 5000\n   }\n}";

            byte[] out = data.getBytes(StandardCharsets.UTF_8);

            OutputStream stream = http.getOutputStream();
            stream.write(out);

            System.out.println(http.getResponseCode() + " " + http.getResponseMessage());
            http.disconnect();
        }
}

异常信息

Exception in thread "main" 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 sun.security.ssl.Alerts.getSSLException(Alerts.java:192)
    at sun.security.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1946)
    at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:316)
    at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:310)
    at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1639)
    at sun.security.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:223)
    at sun.security.ssl.Handshaker.processLoop(Handshaker.java:1037)
    at sun.security.ssl.Handshaker.process_record(Handshaker.java:965)
    at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1064)
    at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1367)
    at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1395)
    at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1379)
    at sun.net.www.protocol.https.HttpsClient.afterConnect(HttpsClient.java:559)
    at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:185)
    at sun.net.www.protocol.http.HttpURLConnection.getOutputStream0(HttpURLConnection.java:1334)
    at sun.net.www.protocol.http.HttpURLConnection.getOutputStream(HttpURLConnection.java:1309)
    at sun.net.www.protocol.https.HttpsURLConnectionImpl.getOutputStream(HttpsURLConnectionImpl.java:259)
    at IbmmqQueue.main(IbmmqQueue.java:30)
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(PKIXValidator.java:397)
    at sun.security.validator.PKIXValidator.engineValidate(PKIXValidator.java:302)
    at sun.security.validator.Validator.validate(Validator.java:262)
    at sun.security.ssl.X509TrustManagerImpl.validate(X509TrustManagerImpl.java:324)
    at sun.security.ssl.X509TrustManagerImpl.checkTrusted(X509TrustManagerImpl.java:229)
    at sun.security.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:124)
    at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1621)
    ... 13 more
Caused by: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
    at sun.security.provider.certpath.SunCertPathBuilder.build(SunCertPathBuilder.java:141)
    at sun.security.provider.certpath.SunCertPathBuilder.engineBuild(SunCertPathBuilder.java:126)
    at java.security.cert.CertPathBuilder.build(CertPathBuilder.java:280)
    at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:392)
    ... 19 more

内容的提问来源于stack exchange,提问作者Shiva Subramaniam

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.16 10:25:23