Java9之HttpClientAPI实战详解

in 编程
关注公众号【好便宜】( ID:haopianyi222 ),领红包啦~
阿里云,国内最大的云服务商,注册就送数千元优惠券:https://t.cn/AiQe5A0g
腾讯云,良心云,价格优惠: https://t.cn/AieHwwKl
搬瓦工,CN2 GIA 优质线路,搭梯子、海外建站推荐: https://t.cn/AieHwfX9

Java9之HttpClientAPI实战详解

前言

相信关注java9的小伙伴们都知道java9版本内置模块提供了Http功能,当然并不是说之前jdk之前并不支持,那么这次更新又多了什么呢?或者是解决了什么问题?

说明

自JDK 1.0以来,Java已经支持HTTP/1.1。 HTTP API由java.net包中的几种类型组成。 现有的API有以下问题:

2015年5月,IETF(Internet Engineering Task Force)发布了HTTP/2规范。 有关HTTP/2规范的完整文本,请访问https://tools.ietf.org/html/rfc7540。 HTTP/2不会修改应用程序级语义。 也就是说,对应用程序中的HTTP协议的了解和使用情况并没有改变。 它具有更有效的方式准备数据包,然后发送到客户端和服务器之间的电线。 所有之前知道的HTTP,如HTTP头,方法,状态码,URL等都保持不变。 HTTP/2尝试解决与HTTP/1连接所面临的许多性能相关的问题:

JDK 9不是更新现有的HTTP/1.1 API,而是提供了一个支持HTTP/1.1和HTTP/2的HTTP/2 Client API。 该API旨在最终取代旧的API。 新API还包含使用WebSocket协议开发客户端应用程序的类和接口。 有关完整的WebSocket协议规范,请访问https://tools.ietf.org/html/rfc6455。新的HTTP/2客户端API与现有的API相比有以下几个好处:

如果想使用Java9的HttpClient服务,那么你必须熟悉(jdk.incubator.http)包中的以下三个类:

HttpClient http客户端

该类是Java9开始引入的,官方文档的翻译说明是这样的

API中Builder部分用来构建客户端的配置,send相关的几个方法是进行请求发送,不同的是Async是异步操作。其他的基本是客户端的参数配置信息(包括代理,线程,版本,SSL,cookie等),同时也提供了socket支持。

HttpRequest 请求

表示可以发送到服务器的一个HTTP请求。 HttpRequest由HttpRequest builders构建生成。 HttpRequest通过调用HttpRequest.newBuilder获得实例。 一个请求的URI ,head和body都可以设置。 请求体提供了HttpRequest.BodyProcessor对象的DELETE , POST或PUT方法。 GET不用设置body。 一旦所有必需的参数都在构建器设置, HttpRequest.Builder.build()将返回一个HttpRequest实例 。 构建器也可以被多次复制和修改,以构建参数不同的多个相关请求。

HttpResponse 响应

表示HttpRequest的响应。 通常在响应正文,响应状态代码和headers被接收之后,HttpResponse才是可用的。 这取决于发送请求时提供的响应体处理程序。 在所有情况下,在Body被读取之前调用response body handler程序。 此类中提供了访问响应头和响应主体的方法。

响应处理程序和处理器

Response bodies有两种处理方式。 应用程序代码提供响应处理程序( HttpResponse.BodyHandler ), 一个是可以检查响应状态代码和头文件, 一个是返回一个HttpResponse.BodyProcessor以实际读取(或丢弃)正文并将其转换为一些有用的Java对象类型。 处理程序可以返回预定义的处理器类型之一或定制处理器, 如果正文被丢弃,则可以调用BodyProcessor.discard()并返回丢弃响应正文的处理器。 处理器和处理器的静态实现分别在BodyHandler和BodyProcessor中提供。 在所有情况下,提供的处理程序功能都是方便的实现, 它忽略了提供的状态代码和头文件,并返回相关的预定义的BodyProcessor 。

 

实战应用

这里是一个完整的示例应用,涵盖了HttpClient,httpRequest,HttpResponse等的使用。

package com.javanine.http;

import jdk.incubator.http.HttpClient;
import jdk.incubator.http.HttpRequest;
import jdk.incubator.http.HttpResponse;
import jdk.incubator.http.MultiMapResult;

import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLParameters;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.net.*;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.security.NoSuchAlgorithmException;
import java.time.Duration;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Executors;

/**
 * Created by bgt on 2017/10/1.
 * Java9http示例
 * <p>
 * VM 参数中添加模块支持
 * --add-modules jdk.incubator.httpclient
 */
public class HttpDemo {
   // private static HttpClient client = HttpClient.newHttpClient();
    private static HttpClient client = null;

    static {
    //这里是httpclient的配置
      init();


    }

    public static void main(String[] args) {
       // HttpDemo.HttpGet();
        HttpDemo.HttpGet2();
    }

    public static void init(){
        try {
            Authenticator authenticator=new Authenticator() {
            };
        client= HttpClient.newBuilder()
                .authenticator(authenticator)//配置authenticator
                .sslContext(SSLContext.getDefault())//配置 sslContext
                .sslParameters(new SSLParameters())//配置 sslParameters
                .proxy(ProxySelector.getDefault())//配置 proxy
                .executor(Executors.newCachedThreadPool())//配置 executor
                .followRedirects(HttpClient.Redirect.ALWAYS)//配置 followRedirects
                .cookieManager(new CookieManager())//配置 cookieManager
                .version(HttpClient.Version.HTTP_2)//配置 version
                .build();

    } catch (NoSuchAlgorithmException e) {
        e.printStackTrace();
    }
    }
    /**
     * 普通get方式
     *
     *
     * 结果:{
     "msg" : "未查询到用户,请认真检查账户或者是否登录",
     "success" : false
     }
     响应码:200

     */
    public static void HttpGet() {

        HttpRequest request = HttpRequest
                //.newBuilder(URI.create("http://blog.csdn.net/u014042066"))
                .newBuilder(URI.create("http://www.rqbao.com/lotteryAward/gettenrecordlist"))
                .header("refer", "http://www.oschina.com")//携带的参数
                .header("userId", "d3e750db32004972b0ae58f8129f50fc")
                .timeout(Duration.ofSeconds(2))//2秒过期
                .GET()
                .build();
        getReponse(request);

    }

    public static void HttpGet2() {

        HttpRequest request = HttpRequest
                //.newBuilder(URI.create("http://blog.csdn.net/u014042066"))
                .newBuilder(URI.create("http://www.rqbao.com/lotteryAward/gettenrecordlist"))
                .header("refer", "http://www.oschina.com")//携带的参数
                .header("userId", "d3e750db32004972b0ae58f8129f50fc")
                .timeout(Duration.ofSeconds(2))//2秒过期
                .GET()
                .build();
        getAsyReponse2(request);

    }

    /**
     * 文件上传
     */
    public static void HttpPost() {
        try {
            HttpRequest request = HttpRequest
                    .newBuilder(URI.create("http://blog.csdn.net/u014042066"))
                    .header("refer", "http://www.oschina.com")
                    .POST(HttpRequest.BodyProcessor.fromFile(Paths.get("/url.txt")))
                    .build();
            getAsyReponse(request);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }

    }

    /**
     * 携带参数
     */
    public static void HttpPost2() {
        HttpRequest request = HttpRequest
                .newBuilder(URI.create("http://blog.csdn.net/u014042066"))
                .header("refer", "http://www.oschina.com")
                .POST(HttpRequest.BodyProcessor.fromString("name=ricky,pwd=123456"))
                .build();
        getReponse(request);
    }

    /**
     * 输出响应结果
     * @param request
     * @throws IOException
     * @throws InterruptedException
     */
    public static void getReponse(HttpRequest request) {
        HttpResponse<String> response = null;
        try {
            if (client==null) {
                init();
            }
            response = client.send(request, HttpResponse.BodyHandler.asString());
        } catch (IOException e) {
            e.printStackTrace();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        String result = response.body();
        int code = response.statusCode();
        if (code == 200) {
            System.out.println("结果:" + result);
        }
        System.out.println("响应码:" + code);
    }

    /**
     * 输出响应结果 带path形式
     * @param request
     * @throws IOException
     * @throws InterruptedException
     */
    public static void getReponsePath(HttpRequest request) {
        HttpResponse<Path> response = null;
        try {
            client.send(request, HttpResponse.BodyHandler.asFile(Paths.get("/url.text")));
            Path body = response.body();
            System.out.println(body);
        } catch (IOException e) {
            e.printStackTrace();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    /**
     * 输出响应结果 带path形式的异步
     * @param request
     * @throws IOException
     * @throws InterruptedException
     */
    public static void getAsyReponsePath(HttpRequest request) {
        CompletableFuture<Path> response = null;
        client
                .sendAsync(request, HttpResponse.BodyHandler.asFile(Paths.get("/url.text")))
                .thenApply((response1) -> response1.body());

        response.join();
    }

    /**
     * 异步的输出响应结果
     * @param request
     * @throws IOException
     * @throws InterruptedException
     */
    public static void getAsyReponse(HttpRequest request) {
        CompletableFuture<HttpResponse<String>> cf;
        cf = client.sendAsync(request, HttpResponse.BodyHandler.asString());
        HttpResponse<String> response = cf.join();
        System.out.println(response.body());
    }
    /**
     * 异步的输出响应结果
     * @param request
     * @throws IOException
     * @throws InterruptedException
     */
    public static void getAsyReponse2(HttpRequest request) {
        MultiMapResult<String> ress;
        ress = client.sendAsync(request, HttpResponse.MultiProcessor.asMap((req)-> Optional.of(
                HttpResponse.BodyHandler.asString()
        ))).join();
      ress.forEach((req,cf)->{
          HttpResponse<String> resp=cf.join();
          System.out.println("uri:"+resp.uri()+"---body:"+resp.body());
      });
    }
}

Java9的HttpClient提供了丰富的功能,这里只是做了个简单的入门与分享,不对之处还望指正。

相关文章

Java9之Shell入门

https://my.oschina.net/u/3048852/blog/1543044

Java9 Module解惑

https://my.oschina.net/u/3048852/blog/1544711

 

结语

作者: ricky

交流群:244930845

关注公众号【好便宜】( ID:haopianyi222 ),领红包啦~
阿里云,国内最大的云服务商,注册就送数千元优惠券:https://t.cn/AiQe5A0g
腾讯云,良心云,价格优惠: https://t.cn/AieHwwKl
搬瓦工,CN2 GIA 优质线路,搭梯子、海外建站推荐: https://t.cn/AieHwfX9
扫一扫关注公众号添加购物返利助手,领红包
Comments are closed.

推荐使用阿里云服务器

超多优惠券

服务器最低一折,一年不到100!

朕已阅去看看