(转发) spring 5 webclient使用指南

spring 5 webclient使用指南

请求携带header
携带cookie
@Test
public void testWithCookie(){
    Mono<String> resp = WebClient.create()
            .method(HttpMethod.GET)
            .uri("http://baidu.com")
            .cookie("token","xxxx")
            .cookie("JSESSIONID","XXXX")
            .retrieve()
            .bodyToMono(String.class);
    LOGGER.info("result:{}",resp.block());
}
携带basic auth
@Test
public void testWithBasicAuth(){
    String basicAuth = "Basic "+ Base64.getEncoder().encodeToString("user:pwd".getBytes(StandardCharsets.UTF_8));
    LOGGER.info(basicAuth);
    Mono<String> resp = WebClient.create()
            .get()
            .uri("http://baidu.com")
            .header(HttpHeaders.AUTHORIZATION,basicAuth)
            .retrieve()
            .bodyToMono(String.class);
    LOGGER.info("result:{}",resp.block());
}
设置全局user-agent
@Test
public void testWithHeaderFilter(){
    WebClient webClient = WebClient.builder()
            .defaultHeader(HttpHeaders.USER_AGENT, "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36")
            .filter(ExchangeFilterFunctions
                    .basicAuthentication("user","password"))
            .filter((clientRequest, next) -> {
                LOGGER.info("Request: {} {}", clientRequest.method(), clientRequest.url());
                clientRequest.headers()
                        .forEach((name, values) -> values.forEach(value -> LOGGER.info("{}={}", name, value)));
                return next.exchange(clientRequest);
            })
            .build();
    Mono<String> resp = webClient.get()
            .uri("https://baidu.com")
            .retrieve()
            .bodyToMono(String.class);
    LOGGER.info("result:{}",resp.block());
}
get请求
使用placeholder传递参数
@Test
public void testUrlPlaceholder(){
    Mono<String> resp = WebClient.create()
            .get()
            //多个参数也可以直接放到map中,参数名与placeholder对应上即可
            .uri("http://www.baidu.com/s?wd={key}&other={another}","北京天气","test") //使用占位符
            .retrieve()
            .bodyToMono(String.class);
    LOGGER.info("result:{}",resp.block());

}
使用uriBuilder传递参数
@Test
public void testUrlBiulder(){
    Mono<String> resp = WebClient.create()
            .get()
            .uri(uriBuilder -> uriBuilder
                    .scheme("http")
                    .host("www.baidu.com")
                    .path("/s")
                    .queryParam("wd", "北京天气")
                    .queryParam("other", "test")
                    .build())
            .retrieve()
            .bodyToMono(String.class);
    LOGGER.info("result:{}",resp.block());
}
post表单
@Test
public void testFormParam(){
    MultiValueMap<String, String> formData = new LinkedMultiValueMap<>();
    formData.add("name1","value1");
    formData.add("name2","value2");
    Mono<String> resp = WebClient.create().post()
            .uri("http://www.w3school.com.cn/test/demo_form.asp")
            .contentType(MediaType.APPLICATION_FORM_URLENCODED)
            .body(BodyInserters.fromFormData(formData))
            .retrieve().bodyToMono(String.class);
    LOGGER.info("result:{}",resp.block());
}
post json
使用bean来post
static class Book {
    String name;
    String title;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }
}

@Test
public void testPostJson(){
    Book book = new Book();
    book.setName("name");
    book.setTitle("this is title");
    Mono<String> resp = WebClient.create().post()
            .uri("http://localhost:8080/demo/json")
            .contentType(MediaType.APPLICATION_JSON_UTF8)
            .body(Mono.just(book),Book.class)
            .retrieve().bodyToMono(String.class);
    LOGGER.info("result:{}",resp.block());
}
直接post raw json
@Test
public void testPostRawJson(){
    Mono<String> resp = WebClient.create().post()
            .uri("http://localhost:8080/demo/json")
            .contentType(MediaType.APPLICATION_JSON_UTF8)
            .body(BodyInserters.fromObject("{\n" +
                    "  \"title\" : \"this is title\",\n" +
                    "  \"author\" : \"this is author\"\n" +
                    "}"))
            .retrieve().bodyToMono(String.class);
    LOGGER.info("result:{}",resp.block());
}
post二进制–上传文件
@Test
public void testUploadFile(){
    HttpHeaders headers = new HttpHeaders();
    headers.setContentType(MediaType.IMAGE_PNG);
    HttpEntity<ClassPathResource> entity = new HttpEntity<>(new ClassPathResource("parallel.png"), headers);
    MultiValueMap<String, Object> parts = new LinkedMultiValueMap<>();
    parts.add("file", entity);
    Mono<String> resp = WebClient.create().post()
            .uri("http://localhost:8080/upload")
            .contentType(MediaType.MULTIPART_FORM_DATA)
            .body(BodyInserters.fromMultipartData(parts))
            .retrieve().bodyToMono(String.class);
    LOGGER.info("result:{}",resp.block());
}
下载二进制

下载图片
@Test
public void testDownloadImage() throws IOException {
Mono resp = WebClient.create().get()
.uri(“http://www.toolip.gr/captcha?complexity=99&size=60&length=9”)
.accept(MediaType.IMAGE_PNG)
.retrieve().bodyToMono(Resource.class);
Resource resource = resp.block();
BufferedImage bufferedImage = ImageIO.read(resource.getInputStream());
ImageIO.write(bufferedImage, “png”, new File(“captcha.png”));

}
下载文件
@Test
public void testDownloadFile() throws IOException {
    Mono<ClientResponse> resp = WebClient.create().get()
            .uri("http://localhost:8080/file/download")
            .accept(MediaType.APPLICATION_OCTET_STREAM)
            .exchange();
    ClientResponse response = resp.block();
    String disposition = response.headers().asHttpHeaders().getFirst(HttpHeaders.CONTENT_DISPOSITION);
    String fileName = disposition.substring(disposition.indexOf("=")+1);
    Resource resource = response.bodyToMono(Resource.class).block();
    File out = new File(fileName);
    FileUtils.copyInputStreamToFile(resource.getInputStream(),out);
    LOGGER.info(out.getAbsolutePath());
}
错误处理
@Test
public void testRetrieve4xx(){
    WebClient webClient = WebClient.builder()
            .baseUrl("https://api.github.com")
            .defaultHeader(HttpHeaders.CONTENT_TYPE, "application/vnd.github.v3+json")
            .defaultHeader(HttpHeaders.USER_AGENT, "Spring 5 WebClient")
            .build();
    WebClient.ResponseSpec responseSpec = webClient.method(HttpMethod.GET)
            .uri("/user/repos?sort={sortField}&direction={sortDirection}",
                    "updated", "desc")
            .retrieve();
    Mono<String> mono = responseSpec
            .onStatus(e -> e.is4xxClientError(),resp -> {
                LOGGER.error("error:{},msg:{}",resp.statusCode().value(),resp.statusCode().getReasonPhrase());
                return Mono.error(new RuntimeException(resp.statusCode().value() + " : " + resp.statusCode().getReasonPhrase()));
            })
            .bodyToMono(String.class)
            .doOnError(WebClientResponseException.class, err -> {
                LOGGER.info("ERROR status:{},msg:{}",err.getRawStatusCode(),err.getResponseBodyAsString());
                throw new RuntimeException(err.getMessage());
            })
            .onErrorReturn("fallback");
    String result = mono.block();
    LOGGER.info("result:{}",result);
}

可以使用onStatus根据status code进行异常适配
可以使用doOnError异常适配
可以使用onErrorReturn返回默认值
小结
webclient是新一代的async rest template,api也相对简洁,而且是reactive的,非常值得使用
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值