http2 java_java9系列(六)HTTP/2 Client (Incubator)

基本实例

sync get

/**

* --add-modules jdk.incubator.httpclient

* @throws IOException

* @throws InterruptedException

* @throws URISyntaxException

*/

@Test

public void testGet() throws IOException, InterruptedException, URISyntaxException {

HttpClient httpClient = HttpClient.newHttpClient();

HttpRequest httpRequest = HttpRequest.newBuilder()

.uri(new URI("https://www.baidu.com"))

.header("User-Agent", "jdk 9 http client")

.GET()

.build();

HttpResponse httpResponse = httpClient.send(httpRequest, HttpResponse.BodyHandler.asString());

System.out.println(httpResponse.statusCode());

System.out.println(httpResponse.body());

}

由于jdk9模块化了,junit这里没有模块化,需要在javac编译时添加--add-modules jdk.incubator.httpclient,否则报错如下:

Error:(3, 21) java: 程序包 jdk.incubator.http 不可见

(程序包 jdk.incubator.http 已在模块 jdk.incubator.httpclient 中声明, 但该模块不在模块图中)

在java运行时也要添加--add-modules jdk.incubator.httpclient,否则报NoClassDefFoundError

java.lang.NoClassDefFoundError: jdk/incubator/http/HttpResponse

at java.base/java.lang.Class.getDeclaredMethods0(Native Method)

at java.base/java.lang.Class.privateGetDeclaredMethods(Class.java:3139)

at java.base/java.lang.Class.getDeclaredMethods(Class.java:2266)

at org.junit.internal.MethodSorter.getDeclaredMethods(MethodSorter.java:54)

at org.junit.runners.model.TestClass.scanAnnotatedMembers(TestClass.java:65)

at org.junit.runners.model.TestClass.(TestClass.java:57)

at org.junit.runners.ParentRunner.createTestClass(ParentRunner.java:88)

at org.junit.runners.ParentRunner.(ParentRunner.java:83)

at org.junit.runners.BlockJUnit4ClassRunner.(BlockJUnit4ClassRunner.java:65)

at org.junit.internal.builders.JUnit4Builder.runnerForClass(JUnit4Builder.java:10)

at org.junit.runners.model.RunnerBuilder.safeRunnerForClass(RunnerBuilder.java:59)

at org.junit.internal.builders.AllDefaultPossibilitiesBuilder.runnerForClass(AllDefaultPossibilitiesBuilder.java:26)

at org.junit.runners.model.RunnerBuilder.safeRunnerForClass(RunnerBuilder.java:59)

at org.junit.internal.requests.ClassRequest.getRunner(ClassRequest.java:33)

at org.junit.internal.requests.FilterRequest.getRunner(FilterRequest.java:36)

at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:49)

at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:47)

at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242)

at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)

Caused by: java.lang.ClassNotFoundException: jdk.incubator.http.HttpResponse

at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:582)

at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:185)

at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:496)

... 19 more

async get

@Test

public void testAsyncGet() throws URISyntaxException, InterruptedException, ExecutionException {

HttpClient client = HttpClient.newHttpClient();

HttpRequest request = HttpRequest.newBuilder()

.uri(new URI("https://www.baidu.com"))

.GET()

.build();

CompletableFuture> response = client.sendAsync(request, HttpResponse.BodyHandler.asString());

response.whenComplete((resp,t) -> {

if(t != null){

t.printStackTrace();

}else{

System.out.println(resp.body());

System.out.println(resp.statusCode());

}

}).join();

}

post form

@Test

public void testPostForm() throws URISyntaxException {

HttpClient client = HttpClient.newHttpClient();

HttpRequest request = HttpRequest.newBuilder()

.uri(new URI("http://www.w3school.com.cn/demo/demo_form.asp"))

.header("Content-Type","application/x-www-form-urlencoded")

.POST(HttpRequest.BodyProcessor.fromString("name1=value1&name2=value2"))

.build();

client.sendAsync(request, HttpResponse.BodyHandler.asString())

.whenComplete((resp,t) -> {

if(t != null){

t.printStackTrace();

}else{

System.out.println(resp.body());

System.out.println(resp.statusCode());

}

}).join();

}

HTTP/2

curl http2

安装

brew install curl --with-nghttp2

==> Installing dependencies for curl: jemalloc, nghttp2

==> Installing curl dependency: jemalloc

==> Downloading https://homebrew.bintray.com/bottles/jemalloc-5.0.1.sierra.bottl

######################################################################## 100.0%

==> Pouring jemalloc-5.0.1.sierra.bottle.tar.gz

? /usr/local/Cellar/jemalloc/5.0.1: 16 files, 1.6MB

==> Installing curl dependency: nghttp2

==> Downloading https://homebrew.bintray.com/bottles/nghttp2-1.31.0.sierra.bottl

######################################################################## 100.0%

==> Pouring nghttp2-1.31.0.sierra.bottle.tar.gz

? /usr/local/Cellar/nghttp2/1.31.0: 33 files, 6.3MB

==> Installing curl --with-nghttp2

==> Downloading https://curl.haxx.se/download/curl-7.58.0.tar.bz2

######################################################################## 100.0%

==> ./configure --disable-silent-rules --prefix=/usr/local/Cellar/curl/7.58.0 --

==> make install

==> Caveats

This formula is keg-only, which means it was not symlinked into /usr/local,

because macOS already provides this software and installing another version in

parallel can cause all kinds of trouble.

If you need to have this software first in your PATH run:

echo 'export PATH="/usr/local/opt/curl/bin:$PATH"' >> ~/.zshrc

For compilers to find this software you may need to set:

LDFLAGS: -L/usr/local/opt/curl/lib

CPPFLAGS: -I/usr/local/opt/curl/include

For pkg-config to find this software you may need to set:

PKG_CONFIG_PATH: /usr/local/opt/curl/lib/pkgconfig

==> Summary

? /usr/local/Cellar/curl/7.58.0: 415 files, 3MB, built in 2 minutes 37 seconds

检查

curl -V

curl 7.58.0 (x86_64-apple-darwin16.7.0) libcurl/7.58.0 OpenSSL/1.0.2n zlib/1.2.8 nghttp2/1.31.0

Release-Date: 2018-01-24

Protocols: dict file ftp ftps gopher http https imap imaps ldap ldaps pop3 pop3s rtsp smb smbs smtp smtps telnet tftp

Features: AsynchDNS IPv6 Largefile NTLM NTLM_WB SSL libz TLS-SRP HTTP2 UnixSockets HTTPS-proxy

访问

curl -I --http2 https://http2.akamai.com/demo

HTTP/2 200

server: Apache

etag: "07ce30bc53aa7834dff55f92a6d05a56:1466062139"

last-modified: Thu, 16 Jun 2016 07:28:59 GMT

accept-ranges: bytes

content-length: 2421

content-type: text/html

rtt: 186

ghost_ip: 23.193.143.145

ghost_service_ip: 107.14.44.207

client_real_ip: 210.21.215.42

client_ip: 210.21.215.42

myproto: h2

protocol_negotiation: h2

expires: Mon, 05 Mar 2018 01:15:17 GMT

cache-control: max-age=0, no-cache, no-store

pragma: no-cache

date: Mon, 05 Mar 2018 01:15:17 GMT

accept-ch: DPR, Width, Viewport-Width, Downlink, Save-Data

access-control-max-age: 86400

access-control-allow-credentials: false

access-control-allow-headers: *

access-control-allow-methods: GET,HEAD,POST

access-control-allow-origin: *

strict-transport-security: max-age=31536000 ; includeSubDomains

HTTP/2实例

@Test

public void testHttp2() throws URISyntaxException, IOException, InterruptedException {

HttpClient.newBuilder()

.followRedirects(HttpClient.Redirect.SECURE)

.version(HttpClient.Version.HTTP_2)

.build()

.sendAsync(HttpRequest.newBuilder()

.uri(new URI("https://http2.akamai.com/demo"))

.GET()

.build(),

HttpResponse.BodyHandler.asString())

.whenComplete((resp,t) -> {

if(t != null){

t.printStackTrace();

}else{

System.out.println(resp.body());

System.out.println(resp.statusCode());

}

}).join();

}

小结

jdk9的httpclient现在还在incubator中,最大的特性便是支持HTTP/2,当然也优化了httpclient的api,同时也支持了异步模式。鉴于它还处在incubator,如果不是着急使用HTTP/2,建议还是使用spring5的webclient,它是遵循reactive-streams规范的,使用起来更加方便。reactor-netty貌似要在0.9.0.RELEASE版本才支持HTTP/2。

doc

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值