深入了解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聲明實現ResponseHandler接口,其handleResponse方法針對statusCode大于等于300的拋出HttpResponseException,對于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轉為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方法通過entity.getContent()獲取InputStream,之后將InputStream讀取到CharArrayBuffer,最后關閉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的時候也會執(zhí)行EntityUtils.consume(entity),最后執(zhí)行response.close()
小結
HttpClient提供了ResponseHandler接口,它有一個實現類是BasicResponseHandler,將entity的content轉為string;相應的CloseableHttpClient也提供了支持ResponseHandler參數的execute方法,它先執(zhí)行無handler的execute方法,然后try catch執(zhí)行responseHandler.handleResponse,然后執(zhí)行EntityUtils.consume(entity),在ClientProtocolException的時候也會執(zhí)行EntityUtils.consume(entity),最后執(zhí)行response.close()。
以上就是HttpClient的ResponseHandler的詳細內容,更多關于HttpClient ResponseHandler的資料請關注腳本之家其它相關文章!
相關文章
Spring?Boot深入學習數據訪問之Spring?Data?JPA與Hibernate的應用
Spring?Data?JPA是Spring?Data的子項目,在使用Spring?Data?JPA之前,先了解一下Hibernate,因為Spring?Data?JPA是由Hibernate默認實現的2022-10-10SpringBoot整合EasyCaptcha實現圖形驗證碼功能
這篇文章主要介紹了SpringBoot整合EasyCaptcha實現圖形驗證碼功能,本文通過實例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2024-02-02SpringBoot使用Swagger生成多模塊的API文檔
這篇文章將以?Spring?Boot?多模塊項目為例,為大家詳細介紹一下如何使用?Swagger?生成多模塊的?API?文檔,感興趣的小伙伴可以了解一下2025-02-02