javax.net.ssl.SSLPeerUnverifiedException 异常如何处理

项目背景

最近在项目上对接了国内某公司的报警信息,对接过程中有个不太好解决的问题,我在这里跟大家分享一下,希望能够对大家有所帮助。
希望你能够认真、用心观看,会对你有帮助的。

异常再现

我需要在服务器上访问用户给我提供的一个公网的 https 接口地址,如下:

我在本地打成 jar 包后,我运行了一下,发现没有任何问题。

于是就通过用户的堡垒机,登录上去开始部署 jdk,然后将 jar 包上传,然后启动。

启动命令如下:

bash 复制代码
	java -server -jar sd-yunli.jar -server.port=8999 >> yunli.log 2>&1 &

启动之后报了个错误,如下:

提示找不到主机,于是我就去/etc/hosts中配置 host 主机名,如下:

配置好了,我再次启动了 jar 包,还是报同样的错误。

分析问题

我在离开客户现场之前,用户使用curl命令在服务器上,验证了他的接口没有问题。

大家可以看到没有任何问题,接口成功响应,所以我就不知道这是怎么回事了。

照理说同一台服务器使用curl命令,跟我用java程序跑应该差不多啊,怎么会这样呢?

大家别急,接下来就是重点。

剖析问题

curl命令

我们首先看下,curl命令为什么可以?

我们通过命令,查看curl命令的执行过程,执行如下命令:

bash 复制代码
curl -v -X POST "接口地址" -F "files=@图片名称1" -F "files=@图片名称2"


我们看到该命令是通过一个代理完成了操作,所以就验证了为什么 curl 命令可以,我们用 java 程序不可以

验证网络端口是否互通


通过telnet命令验证了,我本地是通的,服务器上是不通的。

解决问题

通过对 curl 命令的执行过程进行了剖析,我们发现 curl 走了代理,于是开始配置代理来解决这个问题。

使用环境变量(用户给出建议)

验证结果,还是连接超时

通过 java 命令参数
java 复制代码
java -Dhttps.proxyHost=10.*.*.16 -Dhttps.proxyPort=3*28 -server -jar sd-yunli.jar -server.port=8999 >> yunli.log 2>&1 &

验证结果,还是连接超时

通过自定义验证(解决问题)
  1. 通过实现接口,自定义主机验证。

    java 复制代码
    package com.yunli.sd.config;
    
    import lombok.extern.slf4j.Slf4j;
    
    import javax.net.ssl.SSLSession;
    
    /**
     * 自定义主机名验证器
     * @author pgq
     * @date 2026/02/08 10:33
     */
    @Slf4j
    public class HostnameVerifier implements javax.net.ssl.HostnameVerifier {
    
        @Override
        public boolean verify(String hostname, SSLSession session) {
            log.info("验证主机名:{}", hostname);
            return true;
        }
    
    }
  2. 在 http 请求中使用该验证

    java 复制代码
    package com.yunli.sd.utils;
    
    import com.yunli.sd.config.HostnameVerifier;
    import com.yunli.sd.fetch.dto.WarningDto;
    import okhttp3.*;
    import org.apache.http.client.methods.CloseableHttpResponse;
    import org.apache.http.client.methods.HttpPost;
    import org.apache.http.entity.StringEntity;
    import org.apache.http.impl.client.CloseableHttpClient;
    import org.apache.http.impl.client.HttpClients;
    import org.apache.http.util.EntityUtils;
    import lombok.extern.slf4j.Slf4j;
    import java.io.File;
    
    
    @Slf4j
    public class HttpUtils {
    
        public static String uploadFile(WarningDto warningDto, String url) {
            String result = "";
            try {
                OkHttpClient client = new OkHttpClient.Builder().hostnameVerifier(new HostnameVerifier()).build();
                MultipartBody.Builder requestBodyBuilder = new MultipartBody.Builder()
                        .setType(MultipartBody.FORM);
                File file1 = new File(warningDto.getOriginalPicture());
                requestBodyBuilder.addFormDataPart("files", file1.getName(),
                        RequestBody.create(MediaType.parse("image/jpeg"), file1));
                File file2 = new File(warningDto.getDrawPicture());
                requestBodyBuilder.addFormDataPart("files", file2.getName(),
                        RequestBody.create(MediaType.parse("image/jpeg"), file2));
                Request request = new Request.Builder()
                        .url(url)
                        .post(requestBodyBuilder.build())
                        .build();
                Response response = client.newCall(request).execute();
                if (response.isSuccessful()) {
                    result = response.body().string();
                    log.info("上传成功,响应内容:{}", result);
                } else {
                    log.info("上传失败,错误码:" + response.code());
                }
            } catch (Exception e) {
                log.error("上传接口异常:{}", e);
                e.printStackTrace();
            }
            return result;
        }
    }

    启动命令:

    java 复制代码
    java -Dhttps.proxyHost=10.*.*.16 -Dhttps.proxyPort=3128 -server -jar sd-yunli.jar -server.port=8999 >> yunli.log 2>&1 &
总结
  • 通过自定义接口,解决 https 接口地址证书验证无法通过的问题

  • 其实我们也需要跟 curl 命令一样也需要走代理,我们通过 jar 命令行启动参数,去指定 https 协议需要使用的 host 和 port

相关推荐
Jony_2 天前
高可用移动网络连接
网络协议
用户298698530142 天前
程序员效率工具:Spire.Doc如何助你一键搞定Word表格排版
后端·c#·.net
chilix2 天前
Linux 跨网段路由转发配置
网络协议
牧马人win2 天前
SmartDapper.Repository
.net
mudtools3 天前
搭建一套.net下能落地的飞书考勤系统
后端·c#·.net
玩泥巴的4 天前
搭建一套.net下能落地的飞书考勤系统
c#·.net·二次开发·飞书
gihigo19984 天前
基于TCP协议实现视频采集与通信
网络协议·tcp/ip·音视频
白太岁4 天前
通信:(5) 电路交换、报文交换与分组交换
运维·服务器·网络·网络协议