okhttp报错:clientBuilder.sslSocketFactory(SSLSocketFactory) not supported on jdk 9+

这篇具有很好参考价值的文章主要介绍了okhttp报错:clientBuilder.sslSocketFactory(SSLSocketFactory) not supported on jdk 9+。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一、问题现象

最近在用okHttp处理http请求调用,编写jmeter压测脚本时,出现一个奇怪的问题,idea中可以正常调用。但是打成jar包后,在jmeter中去使用时,则调不通,报错:
clientBuilder.sslSocketFactory(SSLSocketFactory) not supported on jdk 9+, 但是发现自己安装的jdk版本其实就是jdk8。

二、解决方案

查了半天,大概有两种解决办法:
1,使用更低版本的jdk
2,使用更高版本的okHttp(4.3.0版本及以上)

查了一下我项目工程中的OKhttp的版本,果然版本比较低,是3.x版本的。因此使用方法2,项目工程maven里面将okhttp的依赖版本改为4.3.0版本:

<dependency>
    <groupId>com.squareup.okhttp3</groupId>
    <artifactId>okhttp</artifactId>
    <version>4.3.0</version>
</dependency>

这样之后再次运行,不再报错:not supported on jdk 9+,但是报另外一个新的错:java.lang.NoSuchFieldError: Companion。
项目pom.xml文件中,鼠标右键》maven》Show Dependencies,查看各个依赖间的关系图:

okhttp sslsocketfactory,Java,okhttp,java,开发语言

可以看到okhttp与okio关联,网上查了一下原因,是底层依赖 okhttp 与okio的版本不兼容导致,okhttp是 v4.3.0,而okio的版本还是比较低的版本v1.14.0,因此会出现上述问题:

okhttp sslsocketfactory,Java,okhttp,java,开发语言

解决办法就是pom.xml文件中使用更高版本的okio, 比如:V2.8.0

<dependency>
    <groupId>com.squareup.okio</groupId>
    <artifactId>okio</artifactId>
    <version>2.8.0</version>
</dependency>

此后又碰到另外一个问题,当使用jmeter3.2版本时,用上面的方法已经不会报错了。但是当我换成jmeter 5.4.3版本后,还是要继续报:not supported on jdk 9+的错误。

因此我再尝试下面的做法,然后就不报错了。
新建一个类SSLSocketClient,代码如下:

import javax.net.ssl.*;
import java.security.KeyStore;
import java.security.SecureRandom;
import java.security.cert.X509Certificate;
import java.util.Arrays;

public class SSLSocketClient {

    //获取这个SSLSocketFactory
    public static SSLSocketFactory getSSLSocketFactory() {
        try {
            SSLContext sslContext = SSLContext.getInstance("SSL");
            sslContext.init(null, getTrustManager(), new SecureRandom());
            return sslContext.getSocketFactory();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    //获取TrustManager
    private static TrustManager[] getTrustManager() {
        return new TrustManager[]{
                new X509TrustManager() {
                    @Override
                    public void checkClientTrusted(X509Certificate[] chain, String authType) {
                    }

                    @Override
                    public void checkServerTrusted(X509Certificate[] chain, String authType) {
                    }

                    @Override
                    public X509Certificate[] getAcceptedIssuers() {
                        return new X509Certificate[]{};
                    }
                }
        };
    }

    //获取HostnameVerifier
    public static HostnameVerifier getHostnameVerifier() {
        return (s, sslSession) -> true;
    }

    public static X509TrustManager getX509TrustManager() {
        X509TrustManager trustManager = null;
        try {
            TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
            trustManagerFactory.init((KeyStore) null);
            TrustManager[] trustManagers = trustManagerFactory.getTrustManagers();
            if (trustManagers.length != 1 || !(trustManagers[0] instanceof X509TrustManager)) {
                throw new IllegalStateException("Unexpected default trust managers:" + Arrays.toString(trustManagers));
            }
            trustManager = (X509TrustManager) trustManagers[0];
        } catch (Exception e) {
            e.printStackTrace();
        }

        return trustManager;
    }
}

然后OkHttpClient初始化时设置sslSocketFactory和hostnameVerifier,代码如下:

OkHttpClient okHttpClient = new OkHttpClient.Builder()
                .readTimeout(60, TimeUnit.SECONDS)
                .connectTimeout(60, TimeUnit.SECONDS)

                .sslSocketFactory(SSLSocketClient.getSSLSocketFactory(), SSLSocketClient.getX509TrustManager())
                .hostnameVerifier(SSLSocketClient.getHostnameVerifier())
                .build();

完整的HttpUtils工具类代码如下:

import okhttp3.*;
import core.SSLSocketClient; //导入上面写的SSLSocketClient类,SSLSocketClient类是放在工程中的core文件夹下

import java.io.IOException;
import java.util.Map;
import java.util.concurrent.TimeUnit;


public class HttpUtils {
    private final static MediaType MEDIA_TYPE = MediaType.parse("application/json; charset=UTF-8");
    private static OkHttpClient client;
    private static final Integer DEFAULT_TIMEOUT = 10;

    static {
        client = new OkHttpClient.Builder()
                .connectTimeout(DEFAULT_TIMEOUT, TimeUnit.SECONDS)
                .readTimeout(DEFAULT_TIMEOUT, TimeUnit.SECONDS)
                .sslSocketFactory(SSLSocketClient.getSSLSocketFactory(), SSLSocketClient.getX509TrustManager())
                .hostnameVerifier(SSLSocketClient.getHostnameVerifier())
                .build();
    }

    public static Response post(String url, Object param, Map<String, String> headers) throws IOException{
        if (param instanceof String){
            return post(url, (String) param, headers);
        } else if (param instanceof Map){
            return post(url, (Map<String, String>) param, headers);
        }
        else {
            throw new IOException("没有对的参数类型,请检查");
        }
    }

    private static Response post(String url, String param, Map<String, String> headers) throws IOException{
        RequestBody requestBody = RequestBody.create(MEDIA_TYPE, param);
        Request.Builder builder = new Request.Builder().url(url);

        for (String key : headers.keySet()) {
            builder.addHeader(key, headers.get(key));
        }
        Request request = builder.post(requestBody).build();
        return client.newCall(request).execute();
    }

    private static Response post(String url, Map<String, String> param, Map<String, String> headers) throws IOException{
        FormBody.Builder bodyBuilder = new FormBody.Builder();
        for (String key: param.keySet()){
            bodyBuilder.add(key, param.get(key));
        }
        RequestBody requestBody = bodyBuilder.build();
        Request.Builder builder = new Request.Builder().url(url);

        for (String key : headers.keySet()) {
            builder.addHeader(key, headers.get(key));
        }
        Request request = builder.post(requestBody).build();
        return client.newCall(request).execute();
    }
}

=================================================================================================
以上就是本次的全部内容,如果对你有帮助,麻烦点个赞+收藏+关注,一键三连啦~ 欢迎关注下方我的公众号:程序员杨叔,各类文章都会第一时间在上面发布,持续分享各类测试开发知识干货,你的支持就是作者更新最大的动力。文章来源地址https://www.toymoban.com/news/detail-731932.html

到了这里,关于okhttp报错:clientBuilder.sslSocketFactory(SSLSocketFactory) not supported on jdk 9+的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 报错ssh: Could not resolve hostname

    …按照网上好多教程试了一下: 新建密钥,添加到gitee,重新测试。 修改host,加入gitee的ip地址到里面去。 修改.gifconfig配置文件,配置成ssh的仓库链接。 这上面的方法都不行,后面发现一篇文章:SSH连服务器时,连接不上,出现以下错误的原因与解决办法。 才知道是因为一

    2024年02月06日
    浏览(51)
  • Jenkins 构建报错 Could not load

    在Windows和mac电脑上本地打包都可以,但是放到Jenkins上,就会找不到文件。 经过排查Linux是严格区分大小写的,win 和 mac都不区分,所以在提交代码时修改 用记事本在项目目录下的 .git 文件下 config 文件 最好在项目初始化时就设置

    2024年01月25日
    浏览(48)
  • 【Ubuntu报错】NetworkManager is not running

    如果你在运行 nmcli 命令时遇到\\\"NetworkManager is not running\\\"错误,这意味着NetworkManager服务没有在你的系统上运行。 你可以尝试以下步骤来启动NetworkManager服务: 检查NetworkManager服务的状态:运行以下命令来检查NetworkManager服务的状态: 如果服务当前处于停止状态,你可以继续下一

    2024年02月16日
    浏览(45)
  • IDEA 报错Git is not installed

    原因没有配置git地址 setting内找到git,添加本地git地址就可以了    

    2024年02月10日
    浏览(45)
  • 【Ubuntu报错】command not found: nmcli

    如果在你的Linux系统上运行 nmcli 时出现\\\"command not found\\\"错误,这可能意味着 nmcli 命令行工具没有安装或没有在系统的环境变量中找到。 nmcli 命令通常随着NetworkManager软件包一起提供。为了解决这个问题,你可以尝试以下步骤: 如果未安装,你可以使用适合你的Linux发行版的包

    2024年02月16日
    浏览(44)
  • Flask下载文件报错304 NOT MODIFIED

    前端 Vue 下下来的文件无法正常打开,大小比正常的略大一点,通过 Postman 直接调用是正常的 由前端解决 如果响应大小比文件略大一点,从 responses 中取出关键数据再组成文件 如果响应大小很小,例如七百多B, 删掉请求头中的 If-None-Match和If-Modified-Since HTTP缓存和浏览器的本

    2024年02月12日
    浏览(44)
  • Vue报错:Injection “xxxx“ not found

    子组件或者孙组件在父组件 provide 提供的依赖注入时,子组件或孙组件是在不同页面引入的,有的页面使用 provide 提供了依赖,有的没有提供依赖就会报错 在vue2的文档中API — Vue.js 可以使用对象方式的default 降级  将一般的写法 改为 即可解决

    2024年02月11日
    浏览(46)
  • cancal报错 config dir not found

    替换classpath中间封号两边的值

    2024年02月16日
    浏览(27)
  • 前端控制台报错is not defined

    背景: 前端控制台报错is not defined的bug,在一个页面渲染的模板里,多个接口都使用了同一个模板,但是接口返回的参数是不同的。有些接口返回了这个参数,另一些接口可能压根就没有这个参数。这个时候进行页面渲染,调用了那个不存在的参数,就报了is not defined的错。

    2024年02月08日
    浏览(56)
  • Linux命令ifconfig报错command not found

    最近在安装Vmware CentOS,输入ifconfig查看VM的IP地址,提示command not found,发现没安装命令包,此篇文章记录整个问题解决方法。 1、ifconfig 执行结果 2、查看是否真的没有设置IP地址 命令行中输入ip addr,若看到有ip地址,则说明已设置正常,若没有则需要设置一个。 3、设置ip地址

    2024年02月16日
    浏览(49)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包