之前写了一篇resttemplate使用实例,由于spring 5全面引入reactive,同时也有了resttemplate的reactive版webclient,本文就来对应展示下webclient的基本使用。
请求携带header
携带cookie
@test
public void testwithcookie(){
mono 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 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 resp = webclient.get()
.uri("https://baidu.com")
.retrieve()
.bodytomono(string.class);
logger.info("result:{}",resp.block());
}
get请求
使用placeholder传递参数
@test
public void testurlplaceholder(){
mono 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 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 formdata = new linkedmultivaluemap<>();
formdata.add("name1","value1");
formdata.add("name2","value2");
mono 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 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 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 entity = new httpentity<>(new classpathresource("parallel.png"), headers);
multivaluemap parts = new linkedmultivaluemap<>();
parts.add("file", entity);
mono 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 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 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的,非常值得使用。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持萬仟网。
如您对本文有疑问或者有任何想说的,请点击进行留言回复,万千网友为您解惑!