浅谈HttpClient、okhttp和RestTemplate的区别

网友投稿 1118 2023-01-08

浅谈HttpClient、okhttp和RestTemplate的区别

浅谈HttpClient、okhttp和RestTemplate的区别

一、HttpClient

1、pom依赖

commons-httpclient

commons-httpclient

3.1

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秒

httpClient.getHttpConnectionManager().getParams().setConnectionTimeout(5000);

//2.生成GetMethod对象并设置参数

GetMethod getMethod = new GetMethod(url);

//设置get请求超时为5秒

getMethod.getParams().setParameter(HttpMethodParams.SO_TIMEOUT, 5000);

//设置请求重试处理,用的是默认的重试处理:请求三次

getMethod.getParams().setParameter(HttpMethodParams.RETRY_HANDLER, new DefaultHttpMethodRetryHandler());

String response = "";

//3.执行HTTP GET 请求

try {

int statusCode = httpClient.executeMethod(getMethod);

//4.判断访问的状态码

if (statusCode != HttpStatus.SC_OK) {

System.err.println("请求出错:" + getMethod.getStatusLine());

}

//5.处理HTTP响应内容

//HTTP响应头部信息,这里简单打印

Header[] headers = getMethod.getResponseHeaders();

for(Header h : headers) {

System.out.println(h.getName() + "---------------" + h.getValue());

}

//读取HTTP响应内容,这里简单打印网页内容

//读取为字节数组

byte[] responseBody = getMethod.getResponseBody();

response = new String(responseBody, charset);

System.out.println("-----------response:" + response);

//读取为InputStream,在网页内容数据量大时候推荐使用

//InputStream response = getMethod.getResponseBodyAsStream();

} catch (HttpException e) {

//发生致命的异常,可能是协议不对或者返回的内容有问题

System.out.println("请检查输入的URL!");

e.printStackTrace();

} catch (IOException e) {

//发生网络异常

System.out.println("发生网络异常!");

} finally {

//6.释放连接

getMethod.releaseConnection();

}

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", json.getString("commentId"));

String res = "";

try {

int code = httpClient.executeMethod(postMethod);

if (code == 200){

res = postMethod.getResponseBodyAsString();

System.out.println(res);

}

} catch (IOException e) {

e.printStackTrace();

}

return res;

}

public static void main(String[] args) {

System.out.println(doGet("http://tcc.taobao.com/cc/json/mobile_tel_segment.htm?tel=13026194071", "GBK"));

System.out.println("-----------分割线------------");

System.out.println("-----------分割线------------");

System.out.println("-----------分割线------------");

JSONObject jsonObject = new JSONObject();

jsonObject.put("commentId", "13026194071");

System.out.println(doPost("http://tcc.taobao.com/cc/json/mobile_tel_segment.htm?tel=13026194071", jsonObject));

}

}

3、建议

代码复杂,还得操心资源回收等。代码很复杂,冗余代码多,不建议直接使用。

二、okhttp

1、简介

OkHttp是一个高效的HTTP客户端,允许所有同一个主机地址的请求共享同一个socket连接;连接池减少请求延时;透明的GZIP压缩减少响应数据的大小;缓存响应内容,避免一些完全重复的请求

当网络出现问题的时候OkHttp依然坚守自己的职责,它会自动恢复一般的连接问题,如果你的服务有多个IP地址,当第一个IP请求失败时,OkHttp会交替尝试你配置的其他IP,OkHttp使用现代TLS技术(SNI, ALPN)初始化新的连接,当握手失败时会回退到TLS 1.0。

2、pom依赖

com.squareup.okhttp3

okhttp

3.10.0

它的请求/响应 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];

}

};

}

@Bean

public SSLSocketFactory sslSocketFactory() {

try {

//信任任何链接

SSLContext sslContext = SSLContext.getInstance("TLS");

sslContext.init(null, new TrustManager[]{x509TrustManager()}, new SecureRandom());

return sslContext.getSocketFactory();

} 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

.parseInt(ConfigManager.get("httpclient.max_idle_connection"));

private static final long KEEP_ALIVE_DURATION = Long

.parseLong(ConfigManager.get("httpclient.keep_alive_duration"));

private static final long CONNECT_TIMEOUT = Long.parseLong(ConfigManager.get("httpclient.connectTimeout"));

private static final long READ_TIMEOUT = Long.parseLong(ConfigManager.get("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 = RequestBody.create(JSON, json);

Request request = new Request.Builder()

.url(url)

.post(body)

.build();

try {

Response response = OkHttpClient.getInstance().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状态码为" + response.code());

} catch (Exception e) {

log.error("syncPost() url:{} have a ecxeption {}", url, e);

throw new RuntimeException("syncPost() have a ecxeption {}" + e.getMessage());

}

}

public static String syncGet(String url, Map headParamsMap) throws IOException {

Request request;

final Request.Builder builder = new Request.Builder().url(url);

try {

if (!CollectionUtils.isEmpty(headParamsMap)) {

final Iterator> iterator = headParamsMap.entrySet()

.iterator();

while (iterator.hasNext()) {

final Map.Entry entry = iterator.next();

builder.addHeader(entry.getKey(), (String) entry.getValue());

}

}

request = builder.build();

Response response = OkHttpClient.getInstance().newCall(request).execute();

String result = response.body().string();

log.info("syncGet response = {},responseBody= {}", response, result);

if (!response.isSuccessful()) {

throw new IOException("三方接口返回http状态码为" + response.code());

}

return result;

} catch (Exception e) {

log.error("remote interface url:{} hahttp://ve a ecxeption {}", url, e);

throw new RuntimeException("三方接口返回异常");

}

}

}

三、RestTemplate

1、pom依赖

org.springframework.boot

spring-boot-starter-web

2、get请求(不带参的即把参数取消即可)

// 1-getForObject()

User user1 = this.restTemplate.getForObject(uri, User.class);

// 2-getForEntity()

ResponseEntity responseEntity1 = this.restTemplate.getForEntity(uri, User.class);

HttpStatus statusCode = responseEntity1.getStatusCode();

HttpHeaders header = responseEntity1.getHeaders();

User user2 = responseEntity1.getBody();

// 3-exchange()

RequestEntity requestEntity = RequestEntity.get(new URI(uri)).build();

ResponseEntity responseEntity2 = this.restTemplate.exchange(requestEntity, User.class);

User user3 = responseEntity2.getBody();

方式一:

Notice notice = restTemplate.getForObject("http://fantj-/notice/list/{1}/{2}"

, Notice.class,1,5);

方式二:

Map map = new HashMap();

map.put("start","1");

map.put("page","5");

Notice notice = restTemplate.getForObject("http://fantj-/notice/list/"

, Notice.class,map);

3、post请求

// 1-postForObject()

User user1 = this.restTemplate.postForObject(uri, user, User.class);

// 2-postForEntity()

ResponseEntity responseEntity1 = this.restTemplate.postForEntity(uri, user, User.class);

// 3-exchange()

RequestEntity requestEntity = RequestEntity.post(new URI(uri)).body(user);

ResponseEntity responseEntity2 = this.restTemplate.exchange(requestEntity, User.class);

方式一:

String url = "http://demo/api/book/";

HttpHeaders headers = new HttpHeaders();

MediaType type = MediaType.parseMediaType("application/json; charset=UTF-8");

headers.setContentType(type);

String requestJson = "{...}";

HttpEntity entity = new HttpEntity(requestJson,headers);

String result = restTemplate.postForObject(url, entity, String.class);

System.out.println(result);

方式二:

@Test

public void rtPostObject(){

RestTemplate restTemplate = new RestTemplate();

String url = "http://47.xxx.xxx.96/register/checkEmail";

HttpHeaders headers = new HttpHeaders();

headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);

MultiValueMap map= new LinkedMultiValueMap<>();

map.add("email", "844072586@qq.com");

HttpEntity> request = new HttpEntity<>(map, headers);

ResponseEntity response = restTemplate.postForEntity( url, request , String.class );

System.out.println(response.getBody());

}

使用RestTemplate需注意:

使用RestTemplate发送请求,当请求体是String时,应这样配置:

RestTemplate restTemplate = new RestTemplate(factory);

restTemplate

.getMessageConverters()

.set(1, new StringHttpMessageConverter(StandardCharsets.UTF_8));

如果没有自定义StringHttpMessageConverter,默认的StringHttpMessageConverter使用的字符集是ISO_8859_1,当请求体包含中文时,会乱码。

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:移动应用开发(移动应用开发实验报告)
下一篇:企业app开发注意问题(app开发注意事项)
相关文章

 发表评论

暂时没有评论,来抢沙发吧~