本文主要是介绍聊聊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}.*/@Overridepublic 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的执行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.*/@Overridepublic String handleEntity(final HttpEntity entity) throws IOException {return EntityUtils.toString(entity);}@Overridepublic 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
@Overridepublic <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 exceptionfinal 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方法先执行execute,然后try catch执行responseHandler.handleResponse,然后执行EntityUtils.consume(entity),在ClientProtocolException的时候也会执行EntityUtils.consume(entity),最后执行response.close()
小结
HttpClient提供了ResponseHandler接口,它有一个实现类是BasicResponseHandler,将entity的content转为string;相应的CloseableHttpClient也提供了支持ResponseHandler参数的execute方法,它先执行无handler的execute方法,然后try catch执行responseHandler.handleResponse,然后执行EntityUtils.consume(entity),在ClientProtocolException的时候也会执行EntityUtils.consume(entity),最后执行response.close()。
这篇关于聊聊HttpClient的ResponseHandler的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!