浅谈HttpClient、okhttp和RestTemplate的区别
浅谈HttpClient、okhttp和RestTemplate的区别⼀、HttpClient
1、pom依赖
<!--HttpClient-->
<dependency>
<groupId>commons-httpclient</groupId>
<artifactId>commons-httpclient</artifactId>
<version>3.1</version>
</dependency>
2、HttpClient代码实现
public class HttpClientUtil {
/**
* httpClient的get请求⽅式
* 使⽤GetMethod来访问⼀个URL对应的⽹页实现步骤:
* 1.⽣成⼀个HttpClient对象并设置相应的参数;
* 2.⽣成⼀个GetMethod对象并设置响应的参数;
* 3.⽤HttpClient⽣成的对象来执⾏GetMethod⽣成的Get⽅法;
* 4.处理响应状态码;
* 5.若响应正常,处理HTTP响应内容;
* 6.释放连接。
* @param url
* @param charset
* @return
*/
public static String doGet(String url, String charset) {
//1.⽣成HttpClient对象并设置参数
HttpClient httpClient = new HttpClient();
//设置Http连接超时为5秒
//2.⽣成GetMethod对象并设置参数
GetMethod getMethod = new GetMethod(url);
//设置get请求超时为5秒
//设置请求重试处理,⽤的是默认的重试处理:请求三次
String response = "";
//3.执⾏HTTP GET 请求
try {
int statusCode = uteMethod(getMethod);
//4.判断访问的状态码
if (statusCode != HttpStatus.SC_OK) {
}
//5.处理HTTP响应内容
//HTTP响应头部信息,这⾥简单打印
Header[] headers = ResponseHeaders();
for(Header h : headers) {
System.out.Name() + "---------------" + h.getValue());
}
//读取HTTP响应内容,这⾥简单打印⽹页内容
//读取为字节数组
byte[] responseBody = ResponseBody();
response = new String(responseBody, charset);
System.out.println("-----------response:" + response);
//读取为InputStream,在⽹页内容数据量⼤时候推荐使⽤
//InputStream response = ResponseBodyAsStream();
} catch (HttpException e) {
//发⽣致命的异常,可能是协议不对或者返回的内容有问题
System.out.println("请检查输⼊的URL!");
e.printStackTrace();
} catch (IOException e) {
//发⽣⽹络异常
System.out.println("发⽣⽹络异常!");
} finally {
//6.释放连接
}
return response;
}
/**
* post请求
* @param url
* @param json
* @return
*/
public static String doPost(String url, JSONObject json){
HttpClient httpClient = new HttpClient();
PostMethod postMethod = new PostMethod(url);
postMethod.addRequestHeader("accept", "*/*");
postMethod.addRequestHeader("connection", "Keep-Alive");
//设置json格式传送
postMethod.addRequestHeader("Content-Type", "application/json;charset=GBK");
//必须设置下⾯这个Header
postMethod.addRequestHeader("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.81 Safari/537.36");        //添加请求参数
postMethod.addParameter("commentId", String("commentId"));
String res = "";
try {
int code = uteMethod(postMethod);
if (code == 200){
res = ResponseBodyAsString();
System.out.println(res);
}
} catch (IOException e) {
e.printStackTrace();
}
return res;
}
public static void main(String[] args) {
System.out.println(doGet("tcc.taobao/cc/json/mobile_tel_segment.htm?tel=130********", "GBK"));
System.out.println("-----------分割线------------");
System.out.println("-----------分割线------------");
System.out.println("-----------分割线------------");
JSONObject jsonObject = new JSONObject();
jsonObject.put("commentId", "130********");
System.out.println(doPost("tcc.taobao/cc/json/mobile_tel_segment.htm?tel=130********", jsonObject));
}
}
3、建议
代码复杂,还得操⼼资源回收等。代码很复杂,冗余代码多,不建议直接使⽤。
⼆、okhttp
1、简介
OkHttp是⼀个⾼效的HTTP客户端,允许所有同⼀个主机地址的请求共享同⼀个socket连接;连接池减少请求延时;透明的GZIP压缩减少响应数据的⼤⼩;缓存响应内容,避免⼀些完全重复的请求
当⽹络出现问题的时候OkHttp依然坚守⾃⼰的职责,它会⾃动恢复⼀般的连接问题,如果你的服务有多个IP地址,当第⼀个IP请求失败
时,OkHttp会交替尝试你配置的其他IP,OkHttp使⽤现代TLS技术(SNI, ALPN)初始化新的连接,当握⼿失败时会回退到TLS 1.0。
2、pom依赖
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
<version>3.10.0</version>
</dependency>
它的请求/响应 API 使⽤构造器模式builders来设计,它⽀持阻塞式的同步请求和带回调的异步请求。
3、配置⽂件
@Configuration
public class OkHttpConfig {
@Bean
public OkHttpClient okHttpClient() {
return new OkHttpClient.Builder()
//.sslSocketFactory(sslSocketFactory(), x509TrustManager())
.retryOnConnectionFailure(false)
.connectionPool(pool())
.connectTimeout(30, TimeUnit.SECONDS)
.
readTimeout(30, TimeUnit.SECONDS)
.writeTimeout(30,TimeUnit.SECONDS)
.build();
}
@Bean
public X509TrustManager x509TrustManager() {
return new X509TrustManager() {
@Override
public void checkClientTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {
}
@Override
public void checkServerTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {
}
@Override
public X509Certificate[] getAcceptedIssuers() {
return new X509Certificate[0];
}
};
}
public SSLSocketFactory sslSocketFactory() {
try {
//信任任何链接
SSLContext sslContext = Instance("TLS");
sslContext.init(null, new TrustManager[]{x509TrustManager()}, new SecureRandom());
SocketFactory();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (KeyManagementException e) {
e.printStackTrace();
}
return null;
}
/**
* Create a new connection pool with tuning parameters appropriate for a single-user application.
* The tuning parameters in this pool are subject to change in future OkHttp releases. Currently
*/
@Bean
public ConnectionPool pool() {
return new ConnectionPool(200, 5, TimeUnit.MINUTES);
}
}
4、客户端⼯具
@Slf4j
public class OkHttpClient {
private static final MediaType JSON = MediaType.parse("application/json; charset=utf-8");
private volatile static okhttp3.OkHttpClient client;
private static final int MAX_IDLE_CONNECTION = Integer
.("httpclient.max_idle_connection"));
private static final long KEEP_ALIVE_DURATION = Long
.("httpclient.keep_alive_duration"));
private static final long CONNECT_TIMEOUT = Long.("tTimeout"));    private static final long READ_TIMEOUT = Long.("httpclient. "));
/**
* 单例模式(双重检查模式) 获取类实例
*
* @return client
*/
private static okhttp3.OkHttpClient getInstance() {
if (client == null) {
synchronized (okhttp3.OkHttpClient.class) {
if (client == null) {
client = new okhttp3.OkHttpClient.Builder()
.connectTimeout(CONNECT_TIMEOUT, TimeUnit.SECONDS)
.readTimeout(READ_TIMEOUT, TimeUnit.SECONDS)
.connectionPool(new ConnectionPool(MAX_IDLE_CONNECTION, KEEP_ALIVE_DURATION,
TimeUnit.MINUTES))
.
build();
}
}
}
return client;
}
public static String syncPost(String url, String json) throws IOException {
RequestBody body = ate(JSON, json);
Request request = new Request.Builder()
.url(url)
.post(body)
.
build();
try {
Response response = Instance().newCall(request).execute();
if (response.isSuccessful()) {
String result = response.body().string();
log.info("syncPost response = {}, responseBody= {}", response, result);
return result;
}
String result = response.body().string();
log.info("syncPost response = {}, responseBody= {}", response, result);
throw new IOException("三⽅接⼝返回http状态码为" + de());
} catch (Exception e) {
<("syncPost() url:{} have a ecxeption {}", url, e);
throw new RuntimeException("syncPost() have a ecxeption {}" + e.getMessage());
}
}
public static String syncGet(String url, Map<String, Object> headParamsMap) throws IOException {
Request request;
final Request.Builder builder = new Request.Builder().url(url);
try {
if (!CollectionUtils.isEmpty(headParamsMap)) {
final Iterator<Map.Entry<String, Object>> iterator = Set()
.
iterator();
while (iterator.hasNext()) {
final Map.Entry<String, Object> entry = ();
builder.Key(), (String) Value());
}
request = builder.build();
Response response = Instance().newCall(request).execute();
String result = response.body().string();
log.info("syncGet response = {},responseBody= {}", response, result);
if (!response.isSuccessful()) {
throw new IOException("三⽅接⼝返回http状态码为" + de());
}
return result;
} catch (Exception e) {
<("remote interface url:{} have a ecxeption {}", url, e);
throw new RuntimeException("三⽅接⼝返回异常");
}
}
}
三、RestTemplate
1、pom依赖
<dependency>
<groupId>org.springframework.boot</groupId>
连接apple id服务器时出错
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
2、get请求(不带参的即把参数取消即可)
// 1-getForObject()
User user1 = ForObject(uri, User.class);
// 2-getForEntity()
ResponseEntity<User> responseEntity1 = ForEntity(uri, User.class); HttpStatus statusCode = StatusCode();
HttpHeaders header = Headers();
User user2 = Body();
// 3-exchange()
RequestEntity requestEntity = (new URI(uri)).build();
ResponseEntity<User> responseEntity2 = hange(requestEntity, User.class); User user3 = Body();
⽅式⼀:
Notice notice = ForObject("p/notice/list/{1}/{2}"
, Notice.class,1,5);
⽅式⼆:
Map<String,String> map = new HashMap();
map.put("start","1");
map.put("page","5");
Notice notice = ForObject("p/notice/list/"
, Notice.class,map);
3、post请求
// 1-postForObject()
User user1 = stTemplate.postForObject(uri, user, User.class);
// 2-postForEntity()
ResponseEntity<User> responseEntity1 = stTemplate.postForEntity(uri, user, User.class); // 3-exchange()
RequestEntity<User> requestEntity = RequestEntity.post(new URI(uri)).body(user); ResponseEntity<User> responseEntity2 = hange(requestEntity, User.class);⽅式⼀:
String url = "demo/api/book/";
HttpHeaders headers = new HttpHeaders();
MediaType type = MediaType.parseMediaType("application/json; charset=UTF-8");
headers.setContentType(type);
String requestJson = "{...}";
HttpEntity<String> entity = new HttpEntity<String>(requestJson,headers);
String result = restTemplate.postForObject(url, entity, String.class);
System.out.println(result);
⽅式⼆:
@Test
public void rtPostObject(){
RestTemplate restTemplate = new RestTemplate();
String url = "96/register/checkEmail";
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
MultiValueMap<String, String> map= new LinkedMultiValueMap<>();
map.add("email", "844072586@qq");
HttpEntity<MultiValueMap<String, String>> request = new HttpEntity<>(map, headers);
ResponseEntity<String> response = restTemplate.postForEntity( url, request , String.class );
System.out.Body());
}
使⽤RestTemplate需注意:
使⽤RestTemplate发送请求,当请求体是String时,应这样配置:
RestTemplate restTemplate = new RestTemplate(factory);
restTemplate
.
getMessageConverters()
.set(1, new StringHttpMessageConverter(StandardCharsets.UTF_8));
如果没有⾃定义StringHttpMessageConverter,默认的StringHttpMessageConverter使⽤的字符集是ISO_8859_1,当请求体包含中⽂时,会乱码。
以上为个⼈经验,希望能给⼤家⼀个参考,也希望⼤家多多⽀持。

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。