标签:des android style blog http io ar os 使用
package com.loopj.android.http; import org.apache.http.Header; import org.apache.http.HttpResponse; import java.io.IOException; import java.net.URI; /** * Interface to standardize implementations */ public interface ResponseHandlerInterface { /** * Returns data whether request completed successfully * * @param response HttpResponse object with data * @throws java.io.IOException if retrieving data from response fails */ void sendResponseMessage(HttpResponse response) throws IOException; /** * Notifies callback, that request started execution */ void sendStartMessage(); /** * Notifies callback, that request was completed and is being removed from thread pool */ void sendFinishMessage(); /** * Notifies callback, that request (mainly uploading) has progressed * * @param bytesWritten number of written bytes * @param bytesTotal number of total bytes to be written */ void sendProgressMessage(int bytesWritten, int bytesTotal); /** * Notifies callback, that request was cancelled */ void sendCancelMessage(); /** * Notifies callback, that request was handled successfully * * @param statusCode HTTP status code * @param headers returned headers * @param responseBody returned data */ void sendSuccessMessage(int statusCode, Header[] headers, byte[] responseBody); /** * Returns if request was completed with error code or failure of implementation * * @param statusCode returned HTTP status code * @param headers returned headers * @param responseBody returned data * @param error cause of request failure */ void sendFailureMessage(int statusCode, Header[] headers, byte[] responseBody, Throwable error); /** * Notifies callback of retrying request * * @param retryNo number of retry within one request */ void sendRetryMessage(int retryNo); /** * Returns URI which was used to request * * @return uri of origin request */ public URI getRequestURI(); /** * Returns Header[] which were used to request * * @return headers from origin request */ public Header[] getRequestHeaders(); /** * Helper for handlers to receive Request URI info * * @param requestURI claimed request URI */ public void setRequestURI(URI requestURI); /** * Helper for handlers to receive Request Header[] info * * @param requestHeaders Headers, claimed to be from original request */ public void setRequestHeaders(Header[] requestHeaders); /** * Can set, whether the handler should be asynchronous or synchronous * * @param useSynchronousMode whether data should be handled on background Thread on UI Thread */ void setUseSynchronousMode(boolean useSynchronousMode); /** * Returns whether the handler is asynchronous or synchronous * * @return boolean if the ResponseHandler is running in synchronous mode */ boolean getUseSynchronousMode(); /** * This method is called once by the system when the response is about to be * processed by the system. The library makes sure that a single response * is pre-processed only once. * * Please note: pre-processing does NOT run on the main thread, and thus * any UI activities that you must perform should be properly dispatched to * the app's UI thread. * * @param instance An instance of this response object * @param response The response to pre-processed */ void onPreProcessResponse(ResponseHandlerInterface instance, HttpResponse response); /** * This method is called once by the system when the request has been fully * sent, handled and finished. The library makes sure that a single response * is post-processed only once. * * Please note: post-processing does NOT run on the main thread, and thus * any UI activities that you must perform should be properly dispatched to * the app's UI thread. * * @param instance An instance of this response object * @param response The response to post-process */ void onPostProcessResponse(ResponseHandlerInterface instance, HttpResponse response); }
protected static final int SUCCESS_MESSAGE = 0; protected static final int FAILURE_MESSAGE = 1; protected static final int START_MESSAGE = 2; protected static final int FINISH_MESSAGE = 3; protected static final int PROGRESS_MESSAGE = 4; protected static final int RETRY_MESSAGE = 5; protected static final int CANCEL_MESSAGE = 6;
/** * Avoid leaks by using a non-anonymous handler class. */ private static class ResponderHandler extends Handler { private final AsyncHttpResponseHandler mResponder; ResponderHandler(AsyncHttpResponseHandler mResponder, Looper looper) { super(looper); this.mResponder = mResponder; } @Override public void handleMessage(Message msg) { mResponder.handleMessage(msg); } }
// Methods which emulate android's Handler and Message methods protected void handleMessage(Message message) { Object[] response; switch (message.what) { case SUCCESS_MESSAGE: response = (Object[]) message.obj; if (response != null && response.length >= 3) { onSuccess((Integer) response[0], (Header[]) response[1], (byte[]) response[2]); } else { Log.e(LOG_TAG, "SUCCESS_MESSAGE didn't got enough params"); } break; case FAILURE_MESSAGE: response = (Object[]) message.obj; if (response != null && response.length >= 4) { onFailure((Integer) response[0], (Header[]) response[1], (byte[]) response[2], (Throwable) response[3]); } else { Log.e(LOG_TAG, "FAILURE_MESSAGE didn't got enough params"); } break; case START_MESSAGE: onStart(); break; case FINISH_MESSAGE: onFinish(); break; case PROGRESS_MESSAGE: response = (Object[]) message.obj; if (response != null && response.length >= 2) { try { onProgress((Integer) response[0], (Integer) response[1]); } catch (Throwable t) { Log.e(LOG_TAG, "custom onProgress contains an error", t); } } else { Log.e(LOG_TAG, "PROGRESS_MESSAGE didn't got enough params"); } break; case RETRY_MESSAGE: response = (Object[]) message.obj; if (response != null && response.length == 1) { onRetry((Integer) response[0]); } else { Log.e(LOG_TAG, "RETRY_MESSAGE didn't get enough params"); } break; case CANCEL_MESSAGE: onCancel(); break; } }
@Override final public void sendStartMessage() { sendMessage(obtainMessage(START_MESSAGE, null)); } /** * Fired when the request is started, override to handle in your own code */ public void onStart() { // default log warning is not necessary, because this method is just optional notification }
@Override final public void sendFinishMessage() { sendMessage(obtainMessage(FINISH_MESSAGE, null)); } /** * Fired in all cases when the request is finished, after both success and failure, override to * handle in your own code */ public void onFinish() { // default log warning is not necessary, because this method is just optional notification }
@Override final public void sendSuccessMessage(int statusCode, Header[] headers, byte[] responseBytes) { sendMessage(obtainMessage(SUCCESS_MESSAGE, new Object[]{statusCode, headers, responseBytes})); } /** * Fired when a request returns successfully, override to handle in your own code * * @param statusCode the status code of the response * @param headers return headers, if any * @param responseBody the body of the HTTP response from the server */ public abstract void onSuccess(int statusCode, Header[] headers, byte[] responseBody);
@Override final public void sendFailureMessage(int statusCode, Header[] headers, byte[] responseBody, Throwable throwable) { sendMessage(obtainMessage(FAILURE_MESSAGE, new Object[]{statusCode, headers, responseBody, throwable})); } /** * Fired when a request fails to complete, override to handle in your own code * * @param statusCode return HTTP status code * @param headers return headers, if any * @param responseBody the response body, if any * @param error the underlying cause of the failure */ public abstract void onFailure(int statusCode, Header[] headers, byte[] responseBody, Throwable error);
@Override final public void sendProgressMessage(int bytesWritten, int bytesTotal) { sendMessage(obtainMessage(PROGRESS_MESSAGE, new Object[]{bytesWritten, bytesTotal})); } /** * Fired when the request progress, override to handle in your own code * * @param bytesWritten offset from start of file * @param totalSize total size of file */ public void onProgress(int bytesWritten, int totalSize) { Log.v(LOG_TAG, String.format("Progress %d from %d (%2.0f%%)", bytesWritten, totalSize, (totalSize > 0) ? (bytesWritten * 1.0 / totalSize) * 100 : -1)); }
@Override final public void sendRetryMessage(int retryNo) { sendMessage(obtainMessage(RETRY_MESSAGE, new Object[]{retryNo})); } /** * Fired when a retry occurs, override to handle in your own code * * @param retryNo number of retry */ public void onRetry(int retryNo) { Log.d(LOG_TAG, String.format("Request retry no. %d", retryNo)); }
@Override final public void sendCancelMessage() { sendMessage(obtainMessage(CANCEL_MESSAGE, null)); } public void onCancel() { Log.d(LOG_TAG, "Request got cancelled"); }
/** * Creates a new AsyncHttpResponseHandler */ public AsyncHttpResponseHandler() { this(null); } /** * Creates a new AsyncHttpResponseHandler with a user-supplied looper. If * the passed looper is null, the looper attached to the current thread will * be used. * * @param looper The looper to work with */ public AsyncHttpResponseHandler(Looper looper) { this.looper = looper == null ? Looper.myLooper() : looper; // Use asynchronous mode by default. setUseSynchronousMode(false); }
@Override public void setUseSynchronousMode(boolean sync) { // A looper must be prepared before setting asynchronous mode. if (!sync && looper == null) { sync = true; Log.w(LOG_TAG, "Current thread has not called Looper.prepare(). Forcing synchronous mode."); } // If using asynchronous mode. if (!sync && handler == null) { // Create a handler on current thread to submit tasks handler = new ResponderHandler(this, looper); } else if (sync && handler != null) { // TODO: Consider adding a flag to remove all queued messages. handler = null; } useSynchronousMode = sync; }
/** * Helper method to send runnable into local handler loop * * @param runnable runnable instance, can be null */ protected void postRunnable(Runnable runnable) { if (runnable != null) { if (getUseSynchronousMode() || handler == null) { // This response handler is synchronous, run on current thread runnable.run(); } else { // Otherwise, run on provided handler AssertUtils.asserts(handler != null, "handler should not be null!"); handler.post(runnable); } } } /** * Helper method to create Message instance from handler * * @param responseMessageId constant to identify Handler message * @param responseMessageData object to be passed to message receiver * @return Message instance, should not be null */ protected Message obtainMessage(int responseMessageId, Object responseMessageData) { return Message.obtain(handler, responseMessageId, responseMessageData); }
public static final String UTF8_BOM = "\uFEFF"; /** * Attempts to encode response bytes as string of set encoding * * @param charset charset to create string with * @param stringBytes response bytes * @return String of set encoding or null */ public static String getResponseString(byte[] stringBytes, String charset) { try { String toReturn = (stringBytes == null) ? null : new String(stringBytes, charset); if (toReturn != null && toReturn.startsWith(UTF8_BOM)) { return toReturn.substring(1); } return toReturn; } catch (UnsupportedEncodingException e) { Log.e(LOG_TAG, "Encoding response into string failed", e); return null; } }
public abstract class TextHttpResponseHandler extends AsyncHttpResponseHandler { private static final String LOG_TAG = "TextHttpResponseHandler"; /** * Creates new instance with default UTF-8 encoding */ public TextHttpResponseHandler() { this(DEFAULT_CHARSET); } /** * Creates new instance with given string encoding * * @param encoding String encoding, see {@link #setCharset(String)} */ public TextHttpResponseHandler(String encoding) { super(); setCharset(encoding); } /** * Called when request fails * * @param statusCode http response status line * @param headers response headers if any * @param responseString string response of given charset * @param throwable throwable returned when processing request */ public abstract void onFailure(int statusCode, Header[] headers, String responseString, Throwable throwable); /** * Called when request succeeds * * @param statusCode http response status line * @param headers response headers if any * @param responseString string response of given charset */ public abstract void onSuccess(int statusCode, Header[] headers, String responseString); @Override public void onSuccess(int statusCode, Header[] headers, byte[] responseBytes) { onSuccess(statusCode, headers, getResponseString(responseBytes, getCharset())); } @Override public void onFailure(int statusCode, Header[] headers, byte[] responseBytes, Throwable throwable) { onFailure(statusCode, headers, getResponseString(responseBytes, getCharset()), throwable); } /** * Attempts to encode response bytes as string of set encoding * * @param charset charset to create string with * @param stringBytes response bytes * @return String of set encoding or null */ public static String getResponseString(byte[] stringBytes, String charset) { try { String toReturn = (stringBytes == null) ? null : new String(stringBytes, charset); if (toReturn != null && toReturn.startsWith(UTF8_BOM)) { return toReturn.substring(1); } return toReturn; } catch (UnsupportedEncodingException e) { Log.e(LOG_TAG, "Encoding response into string failed", e); return null; } } }
/** * Returns Object of type {@link JSONObject}, {@link JSONArray}, String, Boolean, Integer, Long, * Double or {@link JSONObject#NULL}, see {@link org.json.JSONTokener#nextValue()} * * @param responseBody response bytes to be assembled in String and parsed as JSON * @return Object parsedResponse * @throws org.json.JSONException exception if thrown while parsing JSON */ protected Object parseResponse(byte[] responseBody) throws JSONException { if (null == responseBody) return null; Object result = null; //trim the string to prevent start with blank, and test if the string is valid JSON, because the parser don't do this :(. If JSON is not valid this will return null String jsonString = getResponseString(responseBody, getCharset()); if (jsonString != null) { jsonString = jsonString.trim(); if (jsonString.startsWith(UTF8_BOM)) { jsonString = jsonString.substring(1); } if (jsonString.startsWith("{") || jsonString.startsWith("[")) { result = new JSONTokener(jsonString).nextValue(); } } if (result == null) { result = jsonString; } return result; }
public class JsonHttpResponseHandler extends TextHttpResponseHandler { private static final String LOG_TAG = "JsonHttpResponseHandler"; /** * Creates new JsonHttpResponseHandler, with JSON String encoding UTF-8 */ public JsonHttpResponseHandler() { super(DEFAULT_CHARSET); } /** * Creates new JsonHttpRespnseHandler with given JSON String encoding * * @param encoding String encoding to be used when parsing JSON */ public JsonHttpResponseHandler(String encoding) { super(encoding); } /** * Returns when request succeeds * * @param statusCode http response status line * @param headers response headers if any * @param response parsed response if any */ public void onSuccess(int statusCode, Header[] headers, JSONObject response) { Log.w(LOG_TAG, "onSuccess(int, Header[], JSONObject) was not overriden, but callback was received"); } /** * Returns when request succeeds * * @param statusCode http response status line * @param headers response headers if any * @param response parsed response if any */ public void onSuccess(int statusCode, Header[] headers, JSONArray response) { Log.w(LOG_TAG, "onSuccess(int, Header[], JSONArray) was not overriden, but callback was received"); } /** * Returns when request failed * * @param statusCode http response status line * @param headers response headers if any * @param throwable throwable describing the way request failed * @param errorResponse parsed response if any */ public void onFailure(int statusCode, Header[] headers, Throwable throwable, JSONObject errorResponse) { Log.w(LOG_TAG, "onFailure(int, Header[], Throwable, JSONObject) was not overriden, but callback was received", throwable); } /** * Returns when request failed * * @param statusCode http response status line * @param headers response headers if any * @param throwable throwable describing the way request failed * @param errorResponse parsed response if any */ public void onFailure(int statusCode, Header[] headers, Throwable throwable, JSONArray errorResponse) { Log.w(LOG_TAG, "onFailure(int, Header[], Throwable, JSONArray) was not overriden, but callback was received", throwable); } @Override public void onFailure(int statusCode, Header[] headers, String responseString, Throwable throwable) { Log.w(LOG_TAG, "onFailure(int, Header[], String, Throwable) was not overriden, but callback was received", throwable); } @Override public void onSuccess(int statusCode, Header[] headers, String responseString) { Log.w(LOG_TAG, "onSuccess(int, Header[], String) was not overriden, but callback was received"); } @Override public final void onSuccess(final int statusCode, final Header[] headers, final byte[] responseBytes) { if (statusCode != HttpStatus.SC_NO_CONTENT) { Runnable parser = new Runnable() { @Override public void run() { try { final Object jsonResponse = parseResponse(responseBytes); postRunnable(new Runnable() { @Override public void run() { if (jsonResponse instanceof JSONObject) { onSuccess(statusCode, headers, (JSONObject) jsonResponse); } else if (jsonResponse instanceof JSONArray) { onSuccess(statusCode, headers, (JSONArray) jsonResponse); } else if (jsonResponse instanceof String) { onFailure(statusCode, headers, (String) jsonResponse, new JSONException("Response cannot be parsed as JSON data")); } else { onFailure(statusCode, headers, new JSONException("Unexpected response type " + jsonResponse.getClass().getName()), (JSONObject) null); } } }); } catch (final JSONException ex) { postRunnable(new Runnable() { @Override public void run() { onFailure(statusCode, headers, ex, (JSONObject) null); } }); } } }; if (!getUseSynchronousMode()) { new Thread(parser).start(); } else { // In synchronous mode everything should be run on one thread parser.run(); } } else { onSuccess(statusCode, headers, new JSONObject()); } } @Override public final void onFailure(final int statusCode, final Header[] headers, final byte[] responseBytes, final Throwable throwable) { if (responseBytes != null) { Runnable parser = new Runnable() { @Override public void run() { try { final Object jsonResponse = parseResponse(responseBytes); postRunnable(new Runnable() { @Override public void run() { if (jsonResponse instanceof JSONObject) { onFailure(statusCode, headers, throwable, (JSONObject) jsonResponse); } else if (jsonResponse instanceof JSONArray) { onFailure(statusCode, headers, throwable, (JSONArray) jsonResponse); } else if (jsonResponse instanceof String) { onFailure(statusCode, headers, (String) jsonResponse, throwable); } else { onFailure(statusCode, headers, new JSONException("Unexpected response type " + jsonResponse.getClass().getName()), (JSONObject) null); } } }); } catch (final JSONException ex) { postRunnable(new Runnable() { @Override public void run() { onFailure(statusCode, headers, ex, (JSONObject) null); } }); } } }; if (!getUseSynchronousMode()) { new Thread(parser).start(); } else { // In synchronous mode everything should be run on one thread parser.run(); } } else { Log.v(LOG_TAG, "response body is null, calling onFailure(Throwable, JSONObject)"); onFailure(statusCode, headers, throwable, (JSONObject) null); } } /** * Returns Object of type {@link JSONObject}, {@link JSONArray}, String, Boolean, Integer, Long, * Double or {@link JSONObject#NULL}, see {@link org.json.JSONTokener#nextValue()} * * @param responseBody response bytes to be assembled in String and parsed as JSON * @return Object parsedResponse * @throws org.json.JSONException exception if thrown while parsing JSON */ protected Object parseResponse(byte[] responseBody) throws JSONException { if (null == responseBody) return null; Object result = null; //trim the string to prevent start with blank, and test if the string is valid JSON, because the parser don't do this :(. If JSON is not valid this will return null String jsonString = getResponseString(responseBody, getCharset()); if (jsonString != null) { jsonString = jsonString.trim(); if (jsonString.startsWith(UTF8_BOM)) { jsonString = jsonString.substring(1); } if (jsonString.startsWith("{") || jsonString.startsWith("[")) { result = new JSONTokener(jsonString).nextValue(); } } if (result == null) { result = jsonString; } return result; } }
public abstract class BaseJsonHttpResponseHandler<JSON_TYPE> extends TextHttpResponseHandler { private static final String LOG_TAG = "BaseJsonHttpResponseHandler"; /** * Creates a new JsonHttpResponseHandler with default charset "UTF-8" */ public BaseJsonHttpResponseHandler() { this(DEFAULT_CHARSET); } /** * Creates a new JsonHttpResponseHandler with given string encoding * * @param encoding result string encoding, see <a href="http://docs.oracle.com/javase/7/docs/api/java/nio/charset/Charset.html">Charset</a> */ public BaseJsonHttpResponseHandler(String encoding) { super(encoding); } /** * Base abstract method, handling defined generic type * * @param statusCode HTTP status line * @param headers response headers * @param rawJsonResponse string of response, can be null * @param response response returned by {@link #parseResponse(String, boolean)} */ public abstract void onSuccess(int statusCode, Header[] headers, String rawJsonResponse, JSON_TYPE response); /** * Base abstract method, handling defined generic type * * @param statusCode HTTP status line * @param headers response headers * @param throwable error thrown while processing request * @param rawJsonData raw string data returned if any * @param errorResponse response returned by {@link #parseResponse(String, boolean)} */ public abstract void onFailure(int statusCode, Header[] headers, Throwable throwable, String rawJsonData, JSON_TYPE errorResponse); @Override public final void onSuccess(final int statusCode, final Header[] headers, final String responseString) { if (statusCode != HttpStatus.SC_NO_CONTENT) { Runnable parser = new Runnable() { @Override public void run() { try { final JSON_TYPE jsonResponse = parseResponse(responseString, false); postRunnable(new Runnable() { @Override public void run() { onSuccess(statusCode, headers, responseString, jsonResponse); } }); } catch (final Throwable t) { Log.d(LOG_TAG, "parseResponse thrown an problem", t); postRunnable(new Runnable() { @Override public void run() { onFailure(statusCode, headers, t, responseString, null); } }); } } }; if (!getUseSynchronousMode()) { new Thread(parser).start(); } else { // In synchronous mode everything should be run on one thread parser.run(); } } else { onSuccess(statusCode, headers, null, null); } } @Override public final void onFailure(final int statusCode, final Header[] headers, final String responseString, final Throwable throwable) { if (responseString != null) { Runnable parser = new Runnable() { @Override public void run() { try { final JSON_TYPE jsonResponse = parseResponse(responseString, true); postRunnable(new Runnable() { @Override public void run() { onFailure(statusCode, headers, throwable, responseString, jsonResponse); } }); } catch (Throwable t) { Log.d(LOG_TAG, "parseResponse thrown an problem", t); postRunnable(new Runnable() { @Override public void run() { onFailure(statusCode, headers, throwable, responseString, null); } }); } } }; if (!getUseSynchronousMode()) { new Thread(parser).start(); } else { // In synchronous mode everything should be run on one thread parser.run(); } } else { onFailure(statusCode, headers, throwable, null, null); } } /** * Should return deserialized instance of generic type, may return object for more vague * handling * * @param rawJsonData response string, may be null * @param isFailure indicating if this method is called from onFailure or not * @return object of generic type or possibly null if you choose so * @throws Throwable allows you to throw anything from within deserializing JSON response */ protected abstract JSON_TYPE parseResponse(String rawJsonData, boolean isFailure) throws Throwable; }
/** * 针对Gson进行的特例化 * * @author asce1885 * @date 2014-03-03 * * @param <T> */ public abstract class GsonHttpResponseHandler<T> extends BaseJsonHttpResponseHandler<T> { private Class<T> clazz; public GsonHttpResponseHandler(Class<T> clazz) { this.clazz = clazz; } @Override protected T parseResponse(String rawJsonData, boolean isFailure) throws Throwable { if (!isFailure && !TextUtils.isEmpty(rawJsonData)) { return GSONUtils.parseJson(clazz, rawJsonData); } return null; } } /** * 封装Gson函数库 * * @author asce1885 * @date 2014-03-03 * */ public class GSONUtils { private static final String TAG = GSONUtils.class.getSimpleName(); public static Gson gson = new Gson(); public static <T> T parseJson(Class<T> cls, String json) { try { return gson.fromJson(json, cls); } catch(JsonSyntaxException e) { LogUtils.e(TAG, e.getMessage()); } return null; } public static String toJson(Object src) { try { return gson.toJson(src); } catch(JsonSyntaxException e) { LogUtils.e(TAG, e.getMessage()); } return null; } }
public abstract class BinaryHttpResponseHandler extends AsyncHttpResponseHandler { private static final String LOG_TAG = "BinaryHttpResponseHandler"; private String[] mAllowedContentTypes = new String[]{ RequestParams.APPLICATION_OCTET_STREAM, "image/jpeg", "image/png", "image/gif" }; /** * Method can be overriden to return allowed content types, can be sometimes better than passing * data in constructor * * @return array of content-types or Pattern string templates (eg. '.*' to match every response) */ public String[] getAllowedContentTypes() { return mAllowedContentTypes; } /** * Creates a new BinaryHttpResponseHandler */ public BinaryHttpResponseHandler() { super(); } /** * Creates a new BinaryHttpResponseHandler, and overrides the default allowed content types with * passed String array (hopefully) of content types. * * @param allowedContentTypes content types array, eg. 'image/jpeg' or pattern '.*' */ public BinaryHttpResponseHandler(String[] allowedContentTypes) { super(); if (allowedContentTypes != null) { mAllowedContentTypes = allowedContentTypes; } else { Log.e(LOG_TAG, "Constructor passed allowedContentTypes was null !"); } } @Override public abstract void onSuccess(int statusCode, Header[] headers, byte[] binaryData); @Override public abstract void onFailure(int statusCode, Header[] headers, byte[] binaryData, Throwable error); @Override public final void sendResponseMessage(HttpResponse response) throws IOException { StatusLine status = response.getStatusLine(); Header[] contentTypeHeaders = response.getHeaders(AsyncHttpClient.HEADER_CONTENT_TYPE); if (contentTypeHeaders.length != 1) { //malformed/ambiguous HTTP Header, ABORT! sendFailureMessage( status.getStatusCode(), response.getAllHeaders(), null, new HttpResponseException( status.getStatusCode(), "None, or more than one, Content-Type Header found!" ) ); return; } Header contentTypeHeader = contentTypeHeaders[0]; boolean foundAllowedContentType = false; for (String anAllowedContentType : getAllowedContentTypes()) { try { if (Pattern.matches(anAllowedContentType, contentTypeHeader.getValue())) { foundAllowedContentType = true; } } catch (PatternSyntaxException e) { Log.e("BinaryHttpResponseHandler", "Given pattern is not valid: " + anAllowedContentType, e); } } if (!foundAllowedContentType) { //Content-Type not in allowed list, ABORT! sendFailureMessage( status.getStatusCode(), response.getAllHeaders(), null, new HttpResponseException( status.getStatusCode(), "Content-Type not allowed!" ) ); return; } super.sendResponseMessage(response); } }
@Override public void sendResponseMessage(HttpResponse response) throws IOException { // do not process if request has been cancelled if (!Thread.currentThread().isInterrupted()) { StatusLine status = response.getStatusLine(); byte[] responseBody; responseBody = getResponseData(response.getEntity()); // additional cancellation check as getResponseData() can take non-zero time to process if (!Thread.currentThread().isInterrupted()) { if (status.getStatusCode() >= 300) { sendFailureMessage(status.getStatusCode(), response.getAllHeaders(), responseBody, new HttpResponseException(status.getStatusCode(), status.getReasonPhrase())); } else { sendSuccessMessage(status.getStatusCode(), response.getAllHeaders(), responseBody); } } } }
/** * Obtains new FileAsyncHttpResponseHandler and stores response in passed file * * @param file File to store response within, must not be null */ public FileAsyncHttpResponseHandler(File file) { this(file, false); } /** * Obtains new FileAsyncHttpResponseHandler and stores response in passed file * * @param file File to store response within, must not be null * @param append whether data should be appended to existing file */ public FileAsyncHttpResponseHandler(File file, boolean append) { super(); AssertUtils.asserts(file != null, "File passed into FileAsyncHttpResponseHandler constructor must not be null"); this.mFile = file; this.append = append; } /** * Obtains new FileAsyncHttpResponseHandler against context with target being temporary file * * @param context Context, must not be null */ public FileAsyncHttpResponseHandler(Context context) { super(); this.mFile = getTemporaryFile(context); this.append = false; } /** * Used when there is no file to be used when calling constructor * * @param context Context, must not be null * @return temporary file or null if creating file failed */ protected File getTemporaryFile(Context context) { AssertUtils.asserts(context != null, "Tried creating temporary file without having Context"); try { // not effective in release mode assert context != null; return File.createTempFile("temp_", "_handled", context.getCacheDir()); } catch (IOException e) { Log.e(LOG_TAG, "Cannot create temporary file", e); } return null; }
@Override protected byte[] getResponseData(HttpEntity entity) throws IOException { if (entity != null) { InputStream instream = entity.getContent(); long contentLength = entity.getContentLength(); FileOutputStream buffer = new FileOutputStream(getTargetFile(), this.append); if (instream != null) { try { byte[] tmp = new byte[BUFFER_SIZE]; int l, count = 0; // do not send messages if request has been cancelled while ((l = instream.read(tmp)) != -1 && !Thread.currentThread().isInterrupted()) { count += l; buffer.write(tmp, 0, l); sendProgressMessage(count, (int) contentLength); } } finally { AsyncHttpClient.silentCloseInputStream(instream); buffer.flush(); AsyncHttpClient.silentCloseOutputStream(buffer); } } } return null; }
public abstract class RangeFileAsyncHttpResponseHandler extends FileAsyncHttpResponseHandler { private static final String LOG_TAG = "RangeFileAsyncHttpResponseHandler"; private long current = 0; private boolean append = false; /** * Obtains new RangeFileAsyncHttpResponseHandler and stores response in passed file * * @param file File to store response within, must not be null */ public RangeFileAsyncHttpResponseHandler(File file) { super(file); } @Override public void sendResponseMessage(HttpResponse response) throws IOException { if (!Thread.currentThread().isInterrupted()) { StatusLine status = response.getStatusLine(); if (status.getStatusCode() == HttpStatus.SC_REQUESTED_RANGE_NOT_SATISFIABLE) { //already finished if (!Thread.currentThread().isInterrupted()) sendSuccessMessage(status.getStatusCode(), response.getAllHeaders(), null); } else if (status.getStatusCode() >= 300) { if (!Thread.currentThread().isInterrupted()) sendFailureMessage(status.getStatusCode(), response.getAllHeaders(), null, new HttpResponseException(status.getStatusCode(), status.getReasonPhrase())); } else { if (!Thread.currentThread().isInterrupted()) { Header header = response.getFirstHeader(AsyncHttpClient.HEADER_CONTENT_RANGE); if (header == null) { append = false; current = 0; } else { Log.v(LOG_TAG, AsyncHttpClient.HEADER_CONTENT_RANGE + ": " + header.getValue()); } sendSuccessMessage(status.getStatusCode(), response.getAllHeaders(), getResponseData(response.getEntity())); } } } } @Override protected byte[] getResponseData(HttpEntity entity) throws IOException { if (entity != null) { InputStream instream = entity.getContent(); long contentLength = entity.getContentLength() + current; FileOutputStream buffer = new FileOutputStream(getTargetFile(), append); if (instream != null) { try { byte[] tmp = new byte[BUFFER_SIZE]; int l; while (current < contentLength && (l = instream.read(tmp)) != -1 && !Thread.currentThread().isInterrupted()) { current += l; buffer.write(tmp, 0, l); sendProgressMessage((int) current, (int) contentLength); } } finally { instream.close(); buffer.flush(); buffer.close(); } } } return null; } public void updateRequestHeaders(HttpUriRequest uriRequest) { if (mFile.exists() && mFile.canWrite()) current = mFile.length(); if (current > 0) { append = true; uriRequest.setHeader("Range", "bytes=" + current + "-"); } } }
public abstract class SaxAsyncHttpResponseHandler<T extends DefaultHandler> extends AsyncHttpResponseHandler { /** * Generic Type of handler */ private T handler = null; private final static String LOG_TAG = "SaxAsyncHttpResponseHandler"; /** * Constructs new SaxAsyncHttpResponseHandler with given handler instance * * @param t instance of Handler extending DefaultHandler * @see org.xml.sax.helpers.DefaultHandler */ public SaxAsyncHttpResponseHandler(T t) { super(); if (t == null) { throw new Error("null instance of <T extends DefaultHandler> passed to constructor"); } this.handler = t; } /** * Deconstructs response into given content handler * * @param entity returned HttpEntity * @return deconstructed response * @throws java.io.IOException * @see org.apache.http.HttpEntity */ @Override protected byte[] getResponseData(HttpEntity entity) throws IOException { if (entity != null) { InputStream instream = entity.getContent(); InputStreamReader inputStreamReader = null; if (instream != null) { try { SAXParserFactory sfactory = SAXParserFactory.newInstance(); SAXParser sparser = sfactory.newSAXParser(); XMLReader rssReader = sparser.getXMLReader(); rssReader.setContentHandler(handler); inputStreamReader = new InputStreamReader(instream, DEFAULT_CHARSET); rssReader.parse(new InputSource(inputStreamReader)); } catch (SAXException e) { Log.e(LOG_TAG, "getResponseData exception", e); } catch (ParserConfigurationException e) { Log.e(LOG_TAG, "getResponseData exception", e); } finally { AsyncHttpClient.silentCloseInputStream(instream); if (inputStreamReader != null) { try { inputStreamReader.close(); } catch (IOException e) { /*ignore*/ } } } } } return null; } /** * Default onSuccess method for this AsyncHttpResponseHandler to override * * @param statusCode returned HTTP status code * @param headers returned HTTP headers * @param t instance of Handler extending DefaultHandler */ public abstract void onSuccess(int statusCode, Header[] headers, T t); @Override public void onSuccess(int statusCode, Header[] headers, byte[] responseBody) { onSuccess(statusCode, headers, handler); } /** * Default onFailure method for this AsyncHttpResponseHandler to override * * @param statusCode returned HTTP status code * @param headers returned HTTP headers * @param t instance of Handler extending DefaultHandler */ public abstract void onFailure(int statusCode, Header[] headers, T t); @Override public void onFailure(int statusCode, Header[] headers, byte[] responseBody, Throwable error) { onSuccess(statusCode, headers, handler); } }
【Java&Android开源库代码剖析】のandroid-async-http の网络响应ResponseHandlerInter
标签:des android style blog http io ar os 使用
原文地址:http://blog.csdn.net/asce1885/article/details/41012063