Java常用HTTP客户端
- Java原生HttpURLConnection
- Apache HttpClient
- OkHttp
- Spring RestTemplate
示例
public interface Client {
/**
*
* @param body
* @return
*/
Response post(Object body) throws Exception;
}
public class ApacheHttpClient implements Client {
private static final String DEFAULT_CONTENT_TYPE_VALUE = "application/json";
private static final String DEFAULT_CHARSET_NAME = "UTF-8";
private String url;
private final HttpClient client;
private JsonSerializer jsonSerializer;
/**
*
* @param url
*/
public ApacheHttpClient(String url) {
this(url, HttpClientBuilder.create().build());
}
/**
*
* @param url
* @param client
*/
public ApacheHttpClient(String url, HttpClient client) {
this(url, client, new JacksonJsonSerializer());
}
/**
*
* @param url
* @param client
* @param jsonSerializer
*/
public ApacheHttpClient(String url, HttpClient client, JsonSerializer jsonSerializer) {
if (StringUtils.isBlank(url)) {
throw new IllegalArgumentException("Url can't be null!");
}
if (Objects.isNull(client)) {
throw new IllegalArgumentException("client can't be null!");
}
if (Objects.isNull(jsonSerializer)) {
throw new IllegalArgumentException("jsonSerializer can't be null!");
}
this.url = url;
this.client = client;
this.jsonSerializer = jsonSerializer;
}
@Override
public Response post(Object body) throws Exception {
if (Objects.isNull(body)) {
return Response.NULL_BODY_RESPONSE;
}
if (body instanceof Collection && ((Collection<?>) body).size() <= 0) {
return Response.EMPTY_BODY_RESPONSE;
}
HttpPost post = new HttpPost(url);
String jsonString = jsonSerializer.serialize(body);
StringEntity entity = new StringEntity(jsonString, DEFAULT_CHARSET_NAME);
entity.setContentType(DEFAULT_CONTENT_TYPE_VALUE);
post.setEntity(entity);
HttpResponse httpResponse = client.execute(post);
HttpEntity httpEntity = httpResponse.getEntity();
String result = EntityUtils.toString(httpEntity, "UTF-8");
Response response = new Response(httpResponse.getStatusLine().getStatusCode(),
httpResponse.getStatusLine().getReasonPhrase(), result);
httpResponse.getEntity().getContent().close();
return response;
}
}
存在问题
- 面向方法
- 耦合HTTP客户端
- 手动处理请求响应
- 无法通用,重复编码
- 面向接口实现HTTP调用
HTTP请求和响应的组成
- 请求:请求行、请求头、请求体
- 响应:响应行、响应头、响应体
从访问百度主页开始
声明接口
package com.zby.service;
public interface BaiduClient {
@RequestLine(url = "http://www.baidu.com", method = "GET")
String index();
}
声明注解
package com.zby.annotation;
@Inherited