Java tutorial
/* * Copyright (c) 2013. wyouflf (wyouflf@gmail.com) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.dongfang.net.http; import java.io.File; import java.io.IOException; import java.net.URI; import java.net.UnknownHostException; import java.util.UUID; import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; import org.apache.http.StatusLine; import org.apache.http.client.HttpRequestRetryHandler; import org.apache.http.client.methods.HttpRequestBase; import org.apache.http.impl.client.AbstractHttpClient; import org.apache.http.protocol.HttpContext; import android.os.SystemClock; import android.text.TextUtils; import com.dongfang.net.http.client.HttpGetCache; import com.dongfang.net.http.client.HttpRequest; import com.dongfang.net.http.client.HttpRequest.HttpMethod; import com.dongfang.net.http.client.callback.DefaultHttpRedirectHandler; import com.dongfang.net.http.client.callback.FileDownloadHandler; import com.dongfang.net.http.client.callback.HttpRedirectHandler; import com.dongfang.net.http.client.callback.RequestCallBackHandler; import com.dongfang.net.http.client.callback.StringDownloadHandler; import com.dongfang.utils.HttpException; import com.dongfang.utils.OtherUtils; import com.dongfang.utils.ULog; import com.dongfang.utils.core.CompatibleAsyncTask; import com.dongfang.yzsj.bean.LoginBean; import com.dongfang.yzsj.params.ComParams; import com.dongfang.yzsj.utils.User; public class HttpHandler<T> extends CompatibleAsyncTask<Object, Object, Void> implements RequestCallBackHandler { private final AbstractHttpClient client; private final HttpContext context; private final StringDownloadHandler mStringDownloadHandler = new StringDownloadHandler(); private final FileDownloadHandler mFileDownloadHandler = new FileDownloadHandler(); private HttpRedirectHandler httpRedirectHandler; public void setHttpRedirectHandler(HttpRedirectHandler httpRedirectHandler) { if (httpRedirectHandler != null) { this.httpRedirectHandler = httpRedirectHandler; } } private String requestUrl; private HttpRequestBase request; private boolean isUploading = true; private final RequestCallBack<T> callback; private int retriedTimes = 0; private String fileSavePath = null; private boolean isDownloadingFile = false; private boolean autoResume = false; // Whether the downloading could continue from the point of interruption. private boolean autoRename = false; // Whether rename the file by response header info when the download completely. private String charset; // The default charset of response header info. public HttpHandler(AbstractHttpClient client, HttpContext context, String charset, RequestCallBack<T> callback) { this.client = client; this.context = context; this.callback = callback; this.charset = charset; } private long expiry = HttpGetCache.getDefaultExpiryTime(); public void setExpiry(long expiry) { this.expiry = expiry; } // @SuppressWarnings("unchecked") private ResponseInfo<T> sendRequest(HttpRequestBase request) throws HttpException { if (autoResume && isDownloadingFile) { File downloadFile = new File(fileSavePath); long fileLen = 0; if (downloadFile.isFile() && downloadFile.exists()) { fileLen = downloadFile.length(); } if (fileLen > 0) { request.setHeader("RANGE", "bytes=" + fileLen + "-"); } } boolean retry = true; HttpRequestRetryHandler retryHandler = client.getHttpRequestRetryHandler(); while (retry) { IOException exception = null; try { // ?? // if (request.getMethod().equals(HttpRequest.HttpMethod.GET.toString())) { // String result = HttpUtils.sHttpGetCache.get(requestUrl); // if (result != null) { // return new ResponseInfo<T>(null, (T) result, true); // } // } ResponseInfo<T> responseInfo = null; if (!isCancelled()) { HttpResponse response = client.execute(request, context); responseInfo = handleResponse(response); } return responseInfo; } catch (UnknownHostException e) { exception = e; retry = retryHandler.retryRequest(exception, ++retriedTimes, context); } catch (IOException e) { exception = e; retry = retryHandler.retryRequest(exception, ++retriedTimes, context); } catch (NullPointerException e) { exception = new IOException(e.getMessage()); exception.initCause(e); retry = retryHandler.retryRequest(exception, ++retriedTimes, context); } catch (HttpException e) { throw e; } catch (Throwable e) { exception = new IOException(e.getMessage()); exception.initCause(e); retry = retryHandler.retryRequest(exception, ++retriedTimes, context); } if (!retry && exception != null) { throw new HttpException(exception); } } return null; } @Override protected Void doInBackground(Object... params) { if (params == null || params.length < 1) return null; if (params.length > 3) { fileSavePath = String.valueOf(params[1]); isDownloadingFile = fileSavePath != null; autoResume = (Boolean) params[2]; autoRename = (Boolean) params[3]; } try { // init request & requestUrl request = (HttpRequestBase) params[0]; requestUrl = request.getURI().toString(); if (callback != null) { callback.setRequestUrl(requestUrl); } this.publishProgress(UPDATE_START); lastUpdateTime = SystemClock.uptimeMillis(); ResponseInfo<T> responseInfo = sendRequest(request); if (responseInfo != null) { this.publishProgress(UPDATE_SUCCESS, responseInfo); return null; } } catch (HttpException e) { this.publishProgress(UPDATE_FAILURE, e, e.getMessage()); } return null; } private final static int UPDATE_START = 1; private final static int UPDATE_LOADING = 2; private final static int UPDATE_FAILURE = 3; private final static int UPDATE_SUCCESS = 4; @Override @SuppressWarnings("unchecked") protected void onProgressUpdate(Object... values) { if (mStopped || values == null || values.length < 1 || callback == null) return; switch ((Integer) values[0]) { case UPDATE_START: callback.onStart(); break; case UPDATE_LOADING: if (values.length != 3) return; callback.onLoading(Long.valueOf(String.valueOf(values[1])), Long.valueOf(String.valueOf(values[2])), isUploading); break; case UPDATE_FAILURE: if (values.length != 3) return; callback.onFailure((HttpException) values[1], (String) values[2]); break; case UPDATE_SUCCESS: if (values.length != 2) return; callback.onSuccess((ResponseInfo<T>) values[1]); break; default: break; } } @SuppressWarnings("unchecked") private ResponseInfo<T> handleResponse(HttpResponse response) throws HttpException, IOException { if (response == null) { throw new HttpException("response is null"); } if (isCancelled()) return null; StatusLine status = response.getStatusLine(); int statusCode = status.getStatusCode(); if (statusCode < 300) { Object result = null; HttpEntity entity = response.getEntity(); if (entity != null) { isUploading = false; if (isDownloadingFile) { autoResume = autoResume && OtherUtils.isSupportRange(response); String responseFileName = autoRename ? OtherUtils.getFileNameFromHttpResponse(response) : null; result = mFileDownloadHandler.handleEntity(entity, this, fileSavePath, autoResume, responseFileName); } else { // Set charset from response header info if it's exist. String responseCharset = OtherUtils.getCharsetFromHttpResponse(response); charset = TextUtils.isEmpty(responseCharset) ? charset : responseCharset; result = mStringDownloadHandler.handleEntity(entity, this, charset); ULog.d(result.toString()); // -------- token ?ip??token ,by dongfang, 2013-10-16 17:38:40---------------------- if (isNewToken(result.toString())) { String newUrl = requestUrl.replace(User.SHAREDPREFERENCES_ACCESS_TOKEN_OLD, User.SHAREDPREFERENCES_ACCESS_TOKEN_NEW); request.setURI(URI.create(newUrl)); return handleResponse(client.execute(request, context)); } // --------------------------------------------------------------------------------------------------- // ?? by dongfang, 2013-10-16 17:38:40 // HttpUtils.sHttpGetCache.put(_getRequestUrl, (String) responseBody, expiry); // --------------------------------------------------------------------------------------------------- } } return new ResponseInfo<T>(response, (T) result, false); } else if (statusCode == 301 || statusCode == 302) { if (httpRedirectHandler == null) { httpRedirectHandler = new DefaultHttpRedirectHandler(); } HttpRequestBase request = httpRedirectHandler.getDirectRequest(response); if (request != null) { return this.sendRequest(request); } } else if (statusCode == 416) { throw new HttpException(statusCode, "maybe the file has downloaded completely"); } else { throw new HttpException(statusCode, status.getReasonPhrase()); } return null; } private boolean mStopped = false; /** * stop request task. */ @Override public void stop() { this.mStopped = true; if (!request.isAborted()) { try { request.abort(); } catch (Throwable e) { } } if (!this.isCancelled()) { try { this.cancel(true); } catch (Throwable e) { } } if (callback != null) { callback.onStopped(); } } @Override public boolean isStopped() { return mStopped; } private long lastUpdateTime; @Override public boolean updateProgress(long total, long current, boolean forceUpdateUI) { if (callback != null && !mStopped) { if (forceUpdateUI) { this.publishProgress(UPDATE_LOADING, total, current); } else { long currTime = SystemClock.uptimeMillis(); if (currTime - lastUpdateTime >= callback.getRate()) { lastUpdateTime = currTime; this.publishProgress(UPDATE_LOADING, total, current); } } } return !mStopped; } /** token??token */ private boolean isNewToken(String result) { try { LoginBean bean = new com.google.gson.Gson().fromJson(result, LoginBean.class); // ULog.d(bean.toString()); if (!bean.isResult() && !bean.isSuccess()) { String url_token = ComParams.HTTP_GET_TOKEN_BY_UUID + UUID.randomUUID().toString().replace("-", ""); HttpRequest request = new HttpRequest(HttpMethod.GET, url_token); HttpResponse response = client.execute(request, context); String responseBody = handleResponse(response).result.toString(); ULog.d(responseBody); LoginBean newbean = new com.google.gson.Gson().fromJson(responseBody, LoginBean.class); if (null != newbean && newbean.isSuccess() && !TextUtils.isEmpty(newbean.getToken())) { // ?token User.SHAREDPREFERENCES_ACCESS_TOKEN_NEW = newbean.getToken(); return true; } } } catch (Throwable t) { // t.printStackTrace(); } return false; } }