深入了解HttpClient的ResponseHandler接口
序
本文主要研究一下HttpClient的ResponseHandler
ResponseHandler
org/apache/http/client/ResponseHandler.java
public interface ResponseHandler<T> {
/**
* Processes an {@link HttpResponse} and returns some value
* corresponding to that response.
*
* @param response The response to process
* @return A value determined by the response
*
* @throws ClientProtocolException in case of an http protocol error
* @throws IOException in case of a problem or the connection was aborted
*/
T handleResponse(HttpResponse response) throws ClientProtocolException, IOException;
}ResponseHandler定義了handleResponse方法,用于解析HttpResponse到泛型T
AbstractResponseHandler
org/apache/http/impl/client/AbstractResponseHandler.java
@Contract(threading = ThreadingBehavior.IMMUTABLE)
public abstract class AbstractResponseHandler<T> implements ResponseHandler<T> {
/**
* Read the entity from the response body and pass it to the entity handler
* method if the response was successful (a 2xx status code). If no response
* body exists, this returns null. If the response was unsuccessful (>= 300
* status code), throws an {@link HttpResponseException}.
*/
@Override
public T handleResponse(final HttpResponse response)
throws HttpResponseException, IOException {
final StatusLine statusLine = response.getStatusLine();
final HttpEntity entity = response.getEntity();
if (statusLine.getStatusCode() >= 300) {
EntityUtils.consume(entity);
throw new HttpResponseException(statusLine.getStatusCode(),
statusLine.getReasonPhrase());
}
return entity == null ? null : handleEntity(entity);
}
/**
* Handle the response entity and transform it into the actual response
* object.
*/
public abstract T handleEntity(HttpEntity entity) throws IOException;
}AbstractResponseHandler聲明實(shí)現(xiàn)ResponseHandler接口,其handleResponse方法針對(duì)statusCode大于等于300的拋出HttpResponseException,對(duì)于entity不為null的執(zhí)行handleEntity方法
BasicResponseHandler
org/apache/http/impl/client/BasicResponseHandler.java
@Contract(threading = ThreadingBehavior.IMMUTABLE)
public class BasicResponseHandler extends AbstractResponseHandler<String> {
/**
* Returns the entity as a body as a String.
*/
@Override
public String handleEntity(final HttpEntity entity) throws IOException {
return EntityUtils.toString(entity);
}
@Override
public String handleResponse(
final HttpResponse response) throws HttpResponseException, IOException {
return super.handleResponse(response);
}
}BasicResponseHandler繼承了AbstractResponseHandler,它將entity轉(zhuǎn)為String,使用的是EntityUtils.toString(entity)方法
EntityUtils.toString
org/apache/http/util/EntityUtils.java
public static String toString(final HttpEntity entity) throws IOException, ParseException {
Args.notNull(entity, "Entity");
return toString(entity, ContentType.get(entity));
}
private static String toString(
final HttpEntity entity,
final ContentType contentType) throws IOException {
final InputStream inStream = entity.getContent();
if (inStream == null) {
return null;
}
try {
Args.check(entity.getContentLength() <= Integer.MAX_VALUE,
"HTTP entity too large to be buffered in memory");
int capacity = (int)entity.getContentLength();
if (capacity < 0) {
capacity = DEFAULT_BUFFER_SIZE;
}
Charset charset = null;
if (contentType != null) {
charset = contentType.getCharset();
if (charset == null) {
final ContentType defaultContentType = ContentType.getByMimeType(contentType.getMimeType());
charset = defaultContentType != null ? defaultContentType.getCharset() : null;
}
}
if (charset == null) {
charset = HTTP.DEF_CONTENT_CHARSET;
}
final Reader reader = new InputStreamReader(inStream, charset);
final CharArrayBuffer buffer = new CharArrayBuffer(capacity);
final char[] tmp = new char[1024];
int l;
while((l = reader.read(tmp)) != -1) {
buffer.append(tmp, 0, l);
}
return buffer.toString();
} finally {
inStream.close();
}
}EntityUtils.toString方法通過(guò)entity.getContent()獲取InputStream,之后將InputStream讀取到CharArrayBuffer,最后關(guān)閉InputStream
execute
org/apache/http/impl/client/CloseableHttpClient.java
@Override
public <T> T execute(final HttpHost target, final HttpRequest request,
final ResponseHandler<? extends T> responseHandler, final HttpContext context)
throws IOException, ClientProtocolException {
Args.notNull(responseHandler, "Response handler");
final CloseableHttpResponse response = execute(target, request, context);
try {
final T result = responseHandler.handleResponse(response);
final HttpEntity entity = response.getEntity();
EntityUtils.consume(entity);
return result;
} catch (final ClientProtocolException t) {
// Try to salvage the underlying connection in case of a protocol exception
final HttpEntity entity = response.getEntity();
try {
EntityUtils.consume(entity);
} catch (final Exception t2) {
// Log this exception. The original exception is more
// important and will be thrown to the caller.
this.log.warn("Error consuming content after an exception.", t2);
}
throw t;
} finally {
response.close();
}
}CloseableHttpClient的execute方法先執(zhí)行execute,然后try catch執(zhí)行responseHandler.handleResponse,然后執(zhí)行EntityUtils.consume(entity),在ClientProtocolException的時(shí)候也會(huì)執(zhí)行EntityUtils.consume(entity),最后執(zhí)行response.close()
小結(jié)
HttpClient提供了ResponseHandler接口,它有一個(gè)實(shí)現(xiàn)類(lèi)是BasicResponseHandler,將entity的content轉(zhuǎn)為string;相應(yīng)的CloseableHttpClient也提供了支持ResponseHandler參數(shù)的execute方法,它先執(zhí)行無(wú)handler的execute方法,然后try catch執(zhí)行responseHandler.handleResponse,然后執(zhí)行EntityUtils.consume(entity),在ClientProtocolException的時(shí)候也會(huì)執(zhí)行EntityUtils.consume(entity),最后執(zhí)行response.close()。
以上就是HttpClient的ResponseHandler的詳細(xì)內(nèi)容,更多關(guān)于HttpClient ResponseHandler的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
- 使用Backoff策略提高HttpClient連接管理的效率
- 提升網(wǎng)絡(luò)請(qǐng)求穩(wěn)定性HttpClient的重試機(jī)制深入理解
- NoHttpResponseException異常解決優(yōu)化HttpClient配置以避免連接問(wèn)題
- 簡(jiǎn)化API提升開(kāi)發(fā)效率RestTemplate與HttpClient?OkHttp關(guān)系詳解
- HttpClient的KeepAlive接口方法源碼解析
- RestTemplate對(duì)HttpClient的適配源碼解讀
- HttpClient HttpRoutePlanner接口確定請(qǐng)求目標(biāo)路由
相關(guān)文章
SpringBoot實(shí)現(xiàn)滑塊驗(yàn)證碼驗(yàn)證登陸校驗(yàn)功能詳解
驗(yàn)證碼作為一種自然人的機(jī)器人的判別工具,被廣泛的用于各種防止程序做自動(dòng)化的場(chǎng)景中。傳統(tǒng)的字符型驗(yàn)證安全性已經(jīng)名存實(shí)亡的情況下,各種新型的驗(yàn)證碼如雨后春筍般涌現(xiàn),今天給大家分享一篇SpringBoot實(shí)現(xiàn)滑塊驗(yàn)證碼2022-09-09
Java動(dòng)態(tài)代理機(jī)制的實(shí)例詳解
這篇文章主要介紹了 Java動(dòng)態(tài)代理機(jī)制的實(shí)例詳解的相關(guān)資料,希望通過(guò)本文大家能夠掌握動(dòng)態(tài)代理機(jī)制,需要的朋友可以參考下2017-09-09
Java之Pattern.compile函數(shù)用法詳解
這篇文章主要介紹了Java之Pattern.compile函數(shù)用法詳解,本篇文章通過(guò)簡(jiǎn)要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下2021-08-08
Spring?Boot深入學(xué)習(xí)數(shù)據(jù)訪(fǎng)問(wèn)之Spring?Data?JPA與Hibernate的應(yīng)用
Spring?Data?JPA是Spring?Data的子項(xiàng)目,在使用Spring?Data?JPA之前,先了解一下Hibernate,因?yàn)镾pring?Data?JPA是由Hibernate默認(rèn)實(shí)現(xiàn)的2022-10-10
SpringBoot整合EasyCaptcha實(shí)現(xiàn)圖形驗(yàn)證碼功能
這篇文章主要介紹了SpringBoot整合EasyCaptcha實(shí)現(xiàn)圖形驗(yàn)證碼功能,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2024-02-02
SpringBoot文件上傳同時(shí)接收復(fù)雜參數(shù)的過(guò)程詳解
這篇文章主要介紹了SpringBoot文件上傳同時(shí),接收復(fù)雜參數(shù),本文通過(guò)示例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-12-12
SpringBoot使用Swagger生成多模塊的API文檔
這篇文章將以?Spring?Boot?多模塊項(xiàng)目為例,為大家詳細(xì)介紹一下如何使用?Swagger?生成多模塊的?API?文檔,感興趣的小伙伴可以了解一下2025-02-02
spring配置定時(shí)任務(wù)的幾種方式總結(jié)
這篇文章主要介紹了spring配置定時(shí)任務(wù)的幾種方式總結(jié),具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-12-12

