java8中okHttp发送http2请求

转载:https://blog.csdn.net/guzhipeng/article/details/125218701

 

问题背景:
最近想用springboot2.0搭建支持http2.0的服务器。搭好了之后,通过Chrome访问,显示http协议版本为h2(服务器升级成功,证书配置成功)。
【Java】okhttp3如何发送http2请求?

 

 

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

 

 

后台代码:
1.springboot配置:
【Java】okhttp3如何发送http2请求?

 

 

2.EchoController:(只是简单的返回一个ECHO字符串)
【Java】okhttp3如何发送http2请求?

 

 

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();

}

}

 

 

运行测试:
【Java】okhttp3如何发送http2请求?
response:
Response{protocol=http/1.1, code=200, message=OK, url=https://localhost:8080/echo}

 

 

【Java】okhttp3如何发送http2请求?

 

 

百度了一篇文章,尝试在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协议了。
【Java】okhttp3如何发送http2请求?

 

 

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

回答

https://stackoverflow.com/que...

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

posted @ 2022-08-09 15:37  路要一步一步走  阅读(2436)  评论(0编辑  收藏  举报