jdk11使用了一个新的HttpClient来更方便快捷的处理http请求和响应,新的httpclient支持HTTP/1.1和HTTP/2协议,也支持异步请求,支持websocket请求,可以使用连接池处理,API也支持流式调用,代码更简洁明了;
测试demo:
先写一个简单的httpserver用于测试http请求:
@BeforeEach
void beforetest() {
System.out.println("===before===");
try {
HttpServer server = HttpServer.create(new InetSocketAddress(9999), 0);
server.createContext("/", new HttpHandler(){
@Override
public void handle(HttpExchange exchange) throws IOException {
String exchangeUrl = exchange.getRequestURI().toString().substring(1);
System.out.println("__"
+ "exchangeUrl=" + exchangeUrl);
Headers headers = exchange.getRequestHeaders();
headers.forEach((k, v) -> System.out.println("_Header:" + k + "=" + v));
InputStream body = exchange.getRequestBody();
System.out.println("__RequestBody:" + new String(body.readAllBytes()));
exchange.sendResponseHeaders(200, 0);
OutputStream os = exchange.getResponseBody();
try {
os.write("test".getBytes());
} catch (Exception e) {
e.printStackTrace();
}finally {
os.close();
}
}
});
server.setExecutor(Executors.newCachedThreadPool());
server.start();
System.out.println("http start");
} catch (IOException e) {
e.printStackTrace();
}
}
测试http请求的代码:
@Test
void test() {
System.out.println("===test===");
try {
HttpClient client = HttpClient.newBuilder()
.version(Version.HTTP_1_1)
// .version(Version.HTTP_2)
.connectTimeout(Duration.ofSeconds(5))
// .proxy(proxySelector)
// .authenticator(authenticator)
// .sslContext(sslContext)
// .followRedirects(Redirect.NEVER)
// .executor(Executors.newCachedThreadPool())
.build();
HttpRequest request = HttpRequest.newBuilder()
// .version(Version.HTTP_1_1)
.timeout(Duration.ofSeconds(3))
.header("Content-Type", "text/plain; charset=UTF-8")
.header("hello", "world")
.uri(URI.create("http://192.168.1.30:9999/xyz?a=1&b=2"))
// .GET()
.POST(BodyPublishers.ofString("HELLO WORLD"))
.build();
HttpResponse<String> res = client.send(request, BodyHandlers.ofString());
System.out.println(res);
System.out.println(res.body());
System.out.println("开始异步请求:");
client.sendAsync(request, BodyHandlers.ofString())
.thenApply(r -> r)
.thenAccept(r -> {
System.out.println("异步statusCode:" + r.statusCode());
System.out.println("异步返回body:" + r.body());
});
System.out.println("异步请求结束。");
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
执行结果:
测试websocket请求,先写一个websocket服务端用于测试,我写的服务端收到消息后自动返回“你好”,httpClient的代码,发送三次消息:
@Test
void test2() {
HttpClient client = HttpClient.newHttpClient();
try {
WebSocket webSocket = client.newWebSocketBuilder()
.connectTimeout(Duration.ofSeconds(3))
.buildAsync(new URI("ws://192.168.1.30:80/test"), new Listener() {
@Override
public void onOpen(WebSocket webSocket) {
webSocket.request(1);
System.out.println("onOpen:" + webSocket);
}
@Override
public CompletionStage<?> onText(WebSocket webSocket, CharSequence data, boolean last) {
webSocket.request(1);
System.out.println("onText:" + data);
return null;
}
@Override
public CompletionStage<?> onClose(WebSocket webSocket, int statusCode, String reason) {
System.out.println("onClose:" + statusCode + reason);
webSocket.sendClose(statusCode, reason);
return null;
}
@Override
public void onError(WebSocket webSocket, Throwable error) {
System.out.println("onError");
webSocket.abort();
}
}).join();
for (var i = 1; i <= 3; i++) {
webSocket.sendText("clientTEST" + i, true);
Thread.sleep(200);
}
webSocket.abort();
Thread.sleep(200);
System.out.println("EndTest");
} catch (URISyntaxException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
运行结果: