okhttp3如何发送http2请求?

发布于 2022-09-11 16:13:10 字数 4743 浏览 26 评论 0

问题背景:
最近想用springboot2.0搭建支持http2.0的服务器。搭好了之后,通过Chrome访问,显示http协议版本为h2(服务器升级成功,证书配置成功)。
clipboard.png

现在想自己写个客户端进行测试。百度了一下okhttp3可以支持http2.0,配好了公钥之后,接口是可以发通了,但是看了下response用的protocol还是http1.1版本。

后台代码:
1.springboot配置:
clipboard.png

2.EchoController:(只是简单的返回一个ECHO字符串)
clipboard.png

3.客户端测试:

public class EchoTest {
    private static String url = "https://localhost:8080/echo";
    
    private static OkHttpClient client;

    @Test
    public void echoHttps() throws Exception {

        // build request
        Request request = new Request.Builder()
                .url(url)
                .build();
        // send request
        Response response = client.newCall(request).execute();
        // print message
        String rslt = response.body().string();
        String protocol = response.protocol().name();
        System.out.println(rslt); // 打印响应:ECHO
        System.out.println(protocol); // 打印http protocol
    }
    
    @BeforeClass
    public static void initClient() throws Exception {
        // 导入公钥证书
        KeyStore keyStore = KeyStore.getInstance("JKS"); // .jks格式
        Resource resource = new ClassPathResource("secret/mytruststore.jks");
        keyStore.load(resource.getInputStream(), "line1983".toCharArray());
        
        // 初始化证书管理factory
        TrustManagerFactory factory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
        factory.init(keyStore);
        
        // 获得X509TrustManager
        TrustManager[] trustManagers = factory.getTrustManagers();
        X509TrustManager trustManager = (X509TrustManager) trustManagers[0];

        // 初始化sslContext
        SSLContext sslContext = SSLContext.getInstance("TLSv1.2"); // 这里选择的是tls1.2版本
        sslContext.init(null, new TrustManager[] { trustManager }, null);
        
        // 获得sslSocketFactory
        SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory();

        // 初始化client builder
        OkHttpClient.Builder builder = new OkHttpClient.Builder();
        builder.sslSocketFactory(sslSocketFactory, trustManager)
                .hostnameVerifier(new HostnameVerifier() { // 放过host验证
                    @Override
                    public boolean verify(String hostname, SSLSession session) {
                        return true;
                    }
                });
        
        // build client
        client = builder.build();
    }
}

运行测试:
clipboard.png
response:
Response{protocol=http/1.1, code=200, message=OK, url=https://localhost:8080/echo}

clipboard.png

百度了一篇文章,尝试在build request的时候,对头部进行一些修改:
客户端在请求头部中指定Connection和Upgrade两个字段发起 HTTP/1.1 协议升级. HTTP/2 的协议名称是 h2c, 代表 HTTP/2 ClearText.

        // build request
        Request request = new Request.Builder()
                .url(url)
                .addHeader("Connection", "Upgrade, HTTP2-Settings")
                .addHeader("Upgrade", "h2c")
                .build();

但结果还是一样:
ECHO!!
HTTP_1_1


之前有按照@Feng_Yu评论的StackOverflow上的思路去尝试在build okHttpClient的时候,指定h2协议,

        // 初始化client builder
        OkHttpClient.Builder builder = new OkHttpClient.Builder();
        List<Protocol> protocols = new ArrayList<>();
        protocols.add(Protocol.HTTP_1_1); // 这里如果,只指定h2的话会抛异常
        protocols.add(Protocol.HTTP_2); // 这里如果,只指定h2的话会抛异常
        builder.sslSocketFactory(sslSocketFactory, trustManager)
                .protocols(protocols) // 设置builder protocols
                .hostnameVerifier(new HostnameVerifier() { // 放过host验证
                    @Override
                    public boolean verify(String hostname, SSLSession session) {
                        return true;
                    }
                });

最后发现还是一样,能收到正确的响应,但是协议还是http1.1。后面在debug的时候发现使用默认方法对client进行build的时候,就已经选择了h2协议了。
clipboard.png

搞不定,有会弄的大神麻烦指教一下。。。请他冰嚯阔落。。
各路大神提点建议也都行!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

巷子口的你 2022-09-18 16:13:10

jdk1.7,1.8 原生不支持http2.0,okhttp可以发2.0的请求,你的代码改后是没问题的,但需要引入alpn-boot jar包配合才能模拟http2.0

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文