SpringBoot - 网络请求客户端WebClient使用详解3(POST请求)
四、POST 请求
1,发送一个 JSON 格式数据(使用 json 字符串)
(1)下面代码使用 post 方式发送一个 json 格式的字符串,并将结果打印出来(以字符串的形式)。
@RestController public class HelloController { // 创建 WebClient 对象 private WebClient webClient = WebClient.builder() .baseUrl("http://jsonplaceholder.typicode.com") .build(); @GetMapping("/test") public void test() { // 需要提交的 json 字符串 String jsonStr = "{\"userId\": 222,\"title\": \"abc\",\"body\": \"航歌\"}"; // 发送请求 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)运行结果如下:
2,发送一个 JSON 格式数据(使用 Java Bean)
(1)下面代码使用 post 方式发送一个 Bean 对象,并将结果打印出来(以字符串的形式)。结果同上面是一样的:@RestController public class HelloController { // 创建 WebClient 对象 private WebClient webClient = WebClient.builder() .baseUrl("http://jsonplaceholder.typicode.com") .build(); @GetMapping("/test") public void test() { // 要发送的数据对象 PostBean postBean = new PostBean(); postBean.setUserId(222); postBean.setTitle("abc"); postBean.setBody("航歌"); // 发送请求 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; } }
(2)上面发送的 Bean 对象实际上会转成如下格式的 JSON 数据提交:
3,使用 Form 表单的形式提交数据
(1)下面样例使用 POST 方式发送 multipart/form-data 格式的数据:
@RestController public class HelloController { // 创建 WebClient 对象 private WebClient webClient = WebClient.builder() .baseUrl("http://jsonplaceholder.typicode.com") .build(); @GetMapping("/test") public void test() { //提交参数设置 MultiValueMap<String, String> map = new LinkedMultiValueMap<>(); map.add("title", "abc"); map.add("body", "航歌"); // 发送请求 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; } }
(2)上面代码最终会通过如下这种 form 表单方式提交数据:
4,将结果转成自定义对象
上面样例我们都是将响应结果以 String 形式接收,其实 WebClient 还可以自动将响应结果转成自定的对象或则数组。具体可以参考我前面写的文章:5,设置 url 参数
(1)如果 url 地址上面需要传递一些参数,可以使用占位符的方式:
String url = "http://jsonplaceholder.typicode.com/{1}/{2}"; String url = "http://jsonplaceholder.typicode.com/{type}/{id}";
(2)具体的用法可以参考我前面写的文章:
6,subscribe 订阅(非阻塞式调用)
(1)前面的样例我们都是人为地使用 block 方法来阻塞当前程序。其实 WebClient 是异步的,也就是说等待响应的同时不会阻塞正在执行的线程。只有在响应结果准备就绪时,才会发起通知。
@RestController public class HelloController { // 创建 WebClient 对象 private WebClient webClient = WebClient.builder() .baseUrl("http://jsonplaceholder.typicode.com") .build(); @GetMapping("/test") public void test() { System.out.println("--- begin ---"); // 需要提交的 json 字符串 String jsonStr = "{\"userId\": 222,\"title\": \"abc\",\"body\": \"航歌\"}"; Mono<String> mono = webClient .post() // POST 请求 .uri("/posts") // 请求路径 .contentType(MediaType.APPLICATION_JSON_UTF8) .body(BodyInserters.fromObject(jsonStr)) .retrieve() // 获取响应体 .bodyToMono(String.class); //响应数据类型转换 // 订阅(异步处理结果) mono.subscribe(result -> { System.out.println(result); }); System.out.println("--- end ---"); return; } }
(2)运行结果如下:
附:使用 exchange() 方法获取完整的响应内容
1,方法介绍
(1)前面我们都是使用 retrieve() 方法直接获取到了响应的内容,如果我们想获取到响应的头信息、Cookie 等,可以在通过 WebClient 请求时把调用 retrieve() 改为调用 exchange()。
(2)通过 exchange() 方法可以访问到代表响应结果的对象,通过该对象我们可以获取响应码、contentType、contentLength、响应消息体等。
2,使用样例
下面代码请求一个网络接口,并将响应体、响应头、响应码打印出来。其中响应体的类型设置为 String。
@RestController public class HelloController { // 创建 WebClient 对象 private WebClient webClient = WebClient.builder() .baseUrl("http://jsonplaceholder.typicode.com") .build(); @GetMapping("/test") public void test() { // 需要提交的 json 字符串 String jsonStr = "{\"userId\": 222,\"title\": \"abc\",\"body\": \"航歌\"}"; // 发送请求 Mono<ClientResponse> mono = webClient .post() // POST 请求 .uri("/posts") // 请求路径 .contentType(MediaType.APPLICATION_JSON_UTF8) .body(BodyInserters.fromObject(jsonStr)) .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; } }