spring5 webclient使用指南详解
程序员文章站
2023-12-13 21:47:58
之前写了一篇resttemplate使用实例,由于spring 5全面引入reactive,同时也有了resttemplate的reactive版webclient,本文就...
之前写了一篇resttemplate使用实例,由于spring 5全面引入reactive,同时也有了resttemplate的reactive版webclient,本文就来对应展示下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<resource> 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的,非常值得使用。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。