WebClient Get、Post请求

原创
2021/02/10 20:22
阅读数 405

一、Get 请求

1、获取 String 结果数据

下面代码将响应结果映射为一个 String 字符串,并打印出来。

@RestController
public class DemoController {
 
    // 创建 WebClient 对象
    private WebClient webClient = WebClient.builder()
            .baseUrl("http://jsonplaceholder.typicode.com")
            .build();
 
    @GetMapping("/demo")
    public void demo() {
        Mono<String> mono = webClient
                .get() // GET 请求
                .uri("/posts/1")  // 请求路径
                .retrieve() // 获取响应体
                .bodyToMono(String.class); //响应数据类型转换
        System.out.println(mono.block());
        return;
    }
}

 

2、将结果转换为对象

当响应的结果是 JSON 时,也可以直接指定为一个 Object,WebClient 将接收到响应后把 JSON 字符串转换为对应的对象。

@RestController
public class DemoController {
 
    // 创建 WebClient 对象
    private WebClient webClient = WebClient.builder()
            .baseUrl("http://jsonplaceholder.typicode.com")
            .build();
 
    @GetMapping("/demo")
    public void demo() {
        Mono<PostBean> mono = webClient
                .get() // GET 请求
                .uri("/posts/1")  // 请求路径
                .retrieve() // 获取响应体
                .bodyToMono(PostBean.class); //响应数据类型转换
        System.out.println(mono.block());
        return;
    }
}

其中定义的实体 Bean 代码如下:

@Data
public class PostBean {
    
    private int userId;
    private int id;
    private String title;
    private String body;
    
}

 

3、将结果转成集合

假设接口返回的是一个 json 数组,内容如下:

我们也可以将其转成对应的 Bean 集合:

@RestController
public class DemoController {
 
    // 创建 WebClient 对象
    private WebClient webClient = WebClient.builder()
            .baseUrl("http://jsonplaceholder.typicode.com")
            .build();
 
    @GetMapping("/demo")
    public void demo() {
        Flux<PostBean> flux = webClient
                .get() // GET 请求
                .uri("/posts")  // 请求路径
                .retrieve() // 获取响应体
                .bodyToFlux(PostBean.class); //响应数据类型转换
        List<PostBean> posts = flux.collectList().block();
        System.out.println("结果数:" + posts.size());
        return;
    }
}

 

4、参数传递的几种方式

下面 3 种方式的结果都是一样的。

使用占位符的形式传递参数:

Mono<String> mono = webClient
        .get() // GET 请求
        .uri("/{1}/{2}", "posts", "1")  // 请求路径
        .retrieve() // 获取响应体
        .bodyToMono(String.class); //响应数据类型转换

另一种使用占位符的形式:

String type = "posts";
int id = 1;
 
Mono<String> mono = webClient
        .get() // GET 请求
        .uri("/{type}/{id}", type, id)  // 请求路径
        .retrieve() // 获取响应体
        .bodyToMono(String.class); //响应数据类型转换
        System.out.println(mono.block());

我们也可以使用 map 装载参数:

Map<String,Object> map = new HashMap<>();
map.put("type", "posts");
map.put("id", 1);
 
Mono<String> mono = webClient
        .get() // GET 请求
        .uri("/{type}/{id}", map)  // 请求路径
        .retrieve() // 获取响应体
        .bodyToMono(String.class); //响应数据类型转换

 

二、Post 请求

 1、发送一个 JSON 格式数据(使用 json 字符串)

下面代码使用 post 方式发送一个 json 格式的字符串,并将结果打印出来(以字符串的形式)。

@RestController
public class DemoController {
 
    // 创建 WebClient 对象
    private WebClient webClient = WebClient.builder()
            .baseUrl("http://jsonplaceholder.typicode.com")
            .build();
 
    @GetMapping("/demo")
    public void demo() {
        // 需要提交的 json 字符串
        String jsonStr = "{\"userId\": 22,\"title\": \"hello\",\"body\": \"piao\"}";

        // 发送请求
        Mono<String> mono = webClient
                .post() // POST 请求
                .uri("/posts")  // 请求路径
                .contentType(MediaType.APPLICATION_JSON_UTF8)
                .body(BodyInserters.fromObject(jsonStr))
                .retrieve() // 获取响应体
                .bodyToMono(String.class); //响应数据类型转换

        // 输出结果
        System.out.println(mono.block());
        return;
    }
}

运行结果如下:

 

2、发送一个 JSON 格式数据(使用 Java Bean)

下面代码使用 post 方式发送一个 Bean 对象,并将结果打印出来(以字符串的形式)。

结果同上面是一样的:

@RestController
public class DemoController {
 
    // 创建 WebClient 对象
    private WebClient webClient = WebClient.builder()
            .baseUrl("http://jsonplaceholder.typicode.com")
            .build();
 
    @GetMapping("/demo")
    public void demo() {
        // 要发送的数据对象
        PostBean postBean = new PostBean();
        postBean.setUserId(22);
        postBean.setTitle("hello");
        postBean.setBody("piao");

        // 发送请求
        Mono<String> mono = webClient
                .post() // POST 请求
                .uri("/posts")  // 请求路径
                .contentType(MediaType.APPLICATION_JSON_UTF8)
                .syncBody(postBean)
                .retrieve() // 获取响应体
                .bodyToMono(String.class); //响应数据类型转换

        // 输出结果
        System.out.println(mono.block());
        return;
    }
}

 

 

3、使用 Form 表单的形式提交数据

下面样例使用 POST 方式发送 multipart/form-data 格式的数据:

@RestController
public class DemoController {
 
    // 创建 WebClient 对象
    private WebClient webClient = WebClient.builder()
            .baseUrl("http://jsonplaceholder.typicode.com")
            .build();
 
    @GetMapping("/demo")
    public void demo() {
        //提交参数设置
        MultiValueMap<String, String> map = new LinkedMultiValueMap<>();
        map.add("title", "hello");
        map.add("body", "piao");

        // 发送请求
        Mono<String> mono = webClient
                .post() // POST 请求
                .uri("/posts")  // 请求路径
                .contentType(MediaType.APPLICATION_FORM_URLENCODED)
                .body(BodyInserters.fromFormData(map))
                .retrieve() // 获取响应体
                .bodyToMono(String.class); //响应数据类型转换

        // 输出结果
        System.out.println(mono.block());
        return;
    }
}

 

4、将结果转成自定义对象

上面样例我们都是将响应结果以 String 形式接收,其实 WebClient 还可以自动将响应结果转成自定的对象或则数组。具体可以参考Get请求里面案例。

 

5、设置 url 参数

如果 url 地址上面需要传递一些参数,可以使用占位符的方式:

String url = "http://jsonplaceholder.typicode.com/{1}/{2}";
String url = "http://jsonplaceholder.typicode.com/{type}/{id}";

具体的用法可以参考Get请求案例。

 

三、subscribe 订阅(非阻塞式调用)

前面的样例我们都是人为地使用 block 方法来阻塞当前程序。其实 WebClient 是异步的,也就是说等待响应的同时不会阻塞正在执行的线程。只有在响应结果准备就绪时,才会发起通知。

这里是我们以 Get 请求为例, Post请求也是一样,只是换了请求方式。

@RestController
public class DemoController {
 
    // 创建 WebClient 对象
    private WebClient webClient = WebClient.builder()
            .baseUrl("http://jsonplaceholder.typicode.com")
            .build();
 
    @GetMapping("/demo")
    public void demo() {
        System.out.println("--- begin ---");
 
        Mono<String> mono = webClient
                .get() // GET 请求
                .uri("/posts/1")  // 请求路径
                .retrieve() // 获取响应体
                .bodyToMono(String.class); //响应数据类型转换
 
        // 订阅(异步处理结果)
        mono.subscribe(result -> {
            System.out.println(result);
        });
 
        System.out.println("--- end ---");
        return;
    }
}

运行结果如下:

 

四、使用 exchange() 方法获取完整的响应内容

1、方法介绍

前面我们都是使用 retrieve() 方法直接获取到了响应的内容,如果我们想获取到响应的头信息、Cookie 等,可以在通过 WebClient 请求时把调用 retrieve() 改为调用 exchange()。

通过 exchange() 方法可以访问到代表响应结果的对象,通过该对象我们可以获取响应码、contentType、contentLength、响应消息体等。

 

2、使用样例 

这里是我们以 Get 请求为例, Post请求也是一样,只是换了请求方式。

下面代码请求一个网络接口,并将响应体、响应头、响应码打印出来。其中响应体的类型设置为 String。

@RestController
public class DemoController {
 
    // 创建 WebClient 对象
    private WebClient webClient = WebClient.builder()
            .baseUrl("http://jsonplaceholder.typicode.com")
            .build();
 
    @GetMapping("/demo")
    public void demo() {
        Mono<ClientResponse> mono = webClient
                .get() // GET 请求
                .uri("/posts/1")  // 请求路径
                .exchange();
 
        // 获取完整的响应对象
        ClientResponse response = mono.block();
 
        HttpStatus statusCode = response.statusCode(); // 获取响应码
        int statusCodeValue = response.rawStatusCode(); // 获取响应码值
        Headers headers = response.headers(); // 获取响应头
 
        // 获取响应体
        Mono<String> resultMono = response.bodyToMono(String.class);
        String body = resultMono.block();
 
        // 输出结果
        System.out.println("statusCode:" + statusCode);
        System.out.println("statusCodeValue:" + statusCodeValue);
        System.out.println("headers:" + headers.asHttpHeaders());
        System.out.println("body:" + body);
        return;
    }
}

展开阅读全文
加载中
点击引领话题📣 发布并加入讨论🔥
打赏
0 评论
0 收藏
0
分享
返回顶部
顶部