世面上有很多很多好用的客户端,如HttpClient,OkHttp等,如果您已经用惯了其他的客户端,那么可以继续用,如果您在编写Http请求的时候,感觉要写的代码很散,或者要写的内容很多,很复杂,那么您可以尝试一下RestBuilder,他设计的初衷就是通过傻瓜式链式调用,完成http请求。
- hello RestBuilder
发送一个非常简单的http请求
String response =
RestBuilder
.builder()
.sendForObj(HttpMethod.GET, "http://www.baidu.com", String.class);
- get请求路径url参数拼接
String response =
RestBuilder
.builder()
.pathParam("age","10")
.pathParam("name","xiaoming")
.sendForObj(HttpMethod.GET, "http://www.baidu.com", String.class);
拼接后的url
http://www.baidu.com?name=xiaoming&age=10
- 基于restful风格的参数拼接
String response =
RestBuilder
.builder()
.restfulPathParam("age","10")
.restfulPathParam("name","xiaoming")
.sendForObj(HttpMethod.GET, "http://www.baidu.com/${age}/${name}", String.class);
拼接后的url
http://www.baidu.com/10/xiaoming
- 设置
Content-type
&添加Header
String response =
RestBuilder
.builder()
.contentType(MediaType.APPLICATION_JSON)
.header("token","xxxxxxxxxxxxxxx")
.sendForObj(HttpMethod.GET, "http://www.baidu.com", String.class);
- 表单请求
String response =
RestBuilder
.builder()
.contentType(MediaType.APPLICATION_FORM_URLENCODED)
.formData("username","xiaoming")
.formData("password","123456")
.sendForObj(HttpMethod.POST, "http://www.baidu.com", String.class);
http请求信息
HTTP POST http://www.baidu.com
Accept=[text/plain, application/json, application/*+json, /]
Writing [{username=[xiaoming], password=[123456]}] as "application/x-www-form-urlencoded"
-
添加body
-
方式一
不断添加k,v参数,最终会整合成一个json对象
String response = RestBuilder .builder() .contentType(MediaType.APPLICATION_JSON) .bodyParam("username","xiaoming") .bodyParam("password","123456") .sendForObj(HttpMethod.POST, "http://www.baidu.com", String.class);
http请求信息
HTTP POST http://www.baidu.com
Accept=[text/plain, application/json, application/*+json, /]
Writing [{"password":"123456","username":"xiaoming"}] as "application/json"-
方式二
直接传入对象,如果是String类型,直接当做body,如果是其他类型,最终转换成json形式
String response = RestBuilder .builder() .contentType(MediaType.APPLICATION_JSON) .bodyObj(() -> User.builder() .name("xiaoming") .password("123456") .build()) .sendForObj(HttpMethod.POST, "http://www.baidu.com", String.class);
- 添加监控日志
调用链中加入
monitor()
方法String response = RestBuilder .builder() .contentType(MediaType.APPLICATION_JSON) .bodyObj(() -> User.builder() .name("xiaoming") .password("123456") .build()) .monitor() .sendForObj(HttpMethod.POST, "http://www.baidu.com", String.class);
- 设置
readTimeout&connectTimeout
String response = RestBuilder .builder() .timeout(2000,2000) .sendForObj(HttpMethod.POST, "http://www.baidu.com", String.class);
-
获取响应的Http状态码,响应头等信息
将
sendForObj
换成sendForEntity
ResponseEntity
responseEntity = RestBuilder .builder() .timeout(2000, 2000) .sendForEntity(HttpMethod.POST, "http://www.baidu.com", String.class); -
获取响应流
一般用于文件下载使用,将
sendForObj
换成sendForInputStream
即可。
InputStream inputStream = RestBuilder .builder() .timeout(2000, 2000) .sendForInputStream(HttpMethod.POST, "http://www.baidu.com");
-
复杂响应类型
获取的响应类型形如:
Map
形式,这时我们可以使用JDK提供的>> TypeToken
设置响应类型
Type type = new TypeToken
>>() {}.getType(); HashMap > response = RestBuilder .builder() .timeout(2000,2000) .sendForObj(HttpMethod.POST, "http://www.baidu.com", type); -
[注]
- 底层封装的是RestTemplate,使用到的所有Http相关API均来自Spring
- RestTemplate不会频繁的被创建,如果不设置超时时间,那么使用默认的restTemplate对象,如果设置了超时时间会尝试从缓存池中获取restTemplate对象,如果不存在,才会创建restTempalte对象。
- 这里需要添加gson依赖,用于json处理,
com.google.code.gson
gson
2.8.6
org.projectlombok
lombok
true
- 代码
@Slf4j
public class RestBuilder {
private static final RestTemplate REST_TEMPLATE;
private HttpHeaders httpHeaders = new HttpHeaders();
private String postBodyStr;
private Map restfulPathParamMap;
private Map getParamMap;
private Map bodyParam;
private MultiValueMap formData;
private HttpEntity> httpEntity;
private String requestPath;
private Integer readTimeout;
private Integer connectTimeout;
private Boolean setTimeout = false;
private Boolean monitor = false;
private static final Cache CACHE;
private static final Object LOCK = new Object();
static {
REST_TEMPLATE = new RestTemplate();
MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
converter.setSupportedMediaTypes(Collections.singletonList(MediaType.ALL));
REST_TEMPLATE.getMessageConverters().add(converter);
CACHE = CacheBuilder.newBuilder()
.maximumSize(50)
.expireAfterWrite(30, TimeUnit.MINUTES)
.build();
}
private RestBuilder() {
}
public static RestBuilder builder() {
return new RestBuilder();
}
/**
* 添加header
*
* @param headerKey key
* @param value value
* @return {@link RestBuilder}
*/
public RestBuilder header(String headerKey, String value) {
Assert.hasText(headerKey, "headerKey must not be null");
httpHeaders.add(headerKey, value);
return this;
}
/**
* 设置Http ContentType
*
* @param mediaType {@link MediaType}
* @return {@link RestBuilder}
*/
public RestBuilder contentType(MediaType mediaType) {
if (Objects.isNull(httpHeaders)) {
httpHeaders = new HttpHeaders();
}
httpHeaders.setContentType(mediaType);
return this;
}
/**
* 设置GET请求参数,URL拼接形式
*
* @param pathParam key
* @param value value
* @return {@link RestBuilder}
*/
public RestBuilder pathParam(String pathParam, String value) {
Assert.hasText(pathParam, "supplier must not be null");
if (Objects.isNull(getParamMap)) {
getParamMap = new HashMap<>();
}
getParamMap.put(pathParam, value);
return this;
}
/**
* 设置post表单
*
* @param param key
* @param value value
* @return {@link RestBuilder}
*/
public RestBuilder formData(String param, String value) {
Assert.hasText(param, "supplier not be null");
if (Objects.isNull(this.formData)) {
formData = new LinkedMultiValueMap<>();
}
this.formData.add(param, value);
return this;
}
/**
* 设置body参数,最终会被转换成json
*
* @param key key
* @param value value
* @return {@link RestBuilder}
*/
public RestBuilder bodyParam(String key, String value) {
Assert.hasText(key, "function must not be null");
if (Objects.isNull(bodyParam)) {
this.bodyParam = new HashMap<>();
}
bodyParam.put(key, value);
return this;
}
/**
* 设置请求body,最终会转换成json
*
* @param supplier {@link Object}
* @return {@link RestBuilder}
*/
public RestBuilder bodyObj(Supplier