Java tutorial
/* * Copyright (C) 2011 The Android Open Source Project, * * 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 org.kymjs.kjframe.http; import java.io.IOException; import java.io.InputStream; import java.net.MalformedURLException; import java.net.SocketTimeoutException; import java.util.Date; import java.util.HashMap; import java.util.Map; import org.apache.http.Header; import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; import org.apache.http.HttpStatus; import org.apache.http.StatusLine; import org.apache.http.conn.ConnectTimeoutException; import org.apache.http.impl.cookie.DateUtils; import org.kymjs.kjframe.utils.KJLoger; /** * RequestHttpStack?NetworkRespond */ public class Network { protected static final boolean DEBUG = HttpConfig.DEBUG; protected final HttpStack mHttpStack; public Network(HttpStack httpStack) { mHttpStack = httpStack; } /** * * * @param request * * @return ?null? * @throws KJHttpException */ public NetworkResponse performRequest(Request<?> request) throws KJHttpException { while (true) { HttpResponse httpResponse = null; byte[] responseContents = null; Map<String, String> responseHeaders = new HashMap<String, String>(); try { // Http?Cachetag Map<String, String> headers = new HashMap<String, String>(); addCacheHeaders(headers, request.getCacheEntry()); httpResponse = mHttpStack.performRequest(request, headers); StatusLine statusLine = httpResponse.getStatusLine(); int statusCode = statusLine.getStatusCode(); responseHeaders = convertHeaders(httpResponse.getAllHeaders()); if (statusCode == HttpStatus.SC_NOT_MODIFIED) { // 304 return new NetworkResponse(HttpStatus.SC_NOT_MODIFIED, request.getCacheEntry() == null ? null : request.getCacheEntry().data, responseHeaders, true); } if (httpResponse.getEntity() != null) { if (request instanceof FileRequest) { responseContents = ((FileRequest) request).handleResponse(httpResponse); } else { responseContents = entityToBytes(httpResponse.getEntity()); } } else { responseContents = new byte[0]; } if (statusCode < 200 || statusCode > 299) { throw new IOException(); } return new NetworkResponse(statusCode, responseContents, responseHeaders, false); } catch (SocketTimeoutException e) { throw new KJHttpException(new SocketTimeoutException("socket timeout")); } catch (ConnectTimeoutException e) { throw new KJHttpException(new SocketTimeoutException("socket timeout")); } catch (MalformedURLException e) { throw new RuntimeException("Bad URL " + request.getUrl(), e); } catch (IOException e) { int statusCode = 0; NetworkResponse networkResponse = null; if (httpResponse != null) { statusCode = httpResponse.getStatusLine().getStatusCode(); } else { throw new KJHttpException("NoConnection error", e); } KJLoger.debug("Unexpected response code %d for %s", statusCode, request.getUrl()); if (responseContents != null) { networkResponse = new NetworkResponse(statusCode, responseContents, responseHeaders, false); if (statusCode == HttpStatus.SC_UNAUTHORIZED || statusCode == HttpStatus.SC_FORBIDDEN) { throw new KJHttpException("auth error"); } else { throw new KJHttpException("server error, Only throw ServerError for 5xx status codes.", networkResponse); } } else { throw new KJHttpException(networkResponse); } } } } /** * Respondeader?Cachetag * * @param headers * @param entry */ private void addCacheHeaders(Map<String, String> headers, Cache.Entry entry) { if (entry == null) { return; } if (entry.etag != null) { headers.put("If-None-Match", entry.etag); } if (entry.serverDate > 0) { Date refTime = new Date(entry.serverDate); headers.put("If-Modified-Since", DateUtils.formatDate(refTime)); } } /** * HttpEntry?byte[] * * @param entity * @return * @throws IOException * @throws KJHttpException */ private byte[] entityToBytes(HttpEntity entity) throws IOException, KJHttpException { PoolingByteArrayOutputStream bytes = new PoolingByteArrayOutputStream(ByteArrayPool.get(), (int) entity.getContentLength()); byte[] buffer = null; try { InputStream in = entity.getContent(); if (in == null) { throw new KJHttpException("server error"); } buffer = ByteArrayPool.get().getBuf(1024); int count; while ((count = in.read(buffer)) != -1) { bytes.write(buffer, 0, count); } return bytes.toByteArray(); } finally { try { entity.consumeContent(); } catch (IOException e) { KJLoger.debug("Error occured when calling consumingContent"); } ByteArrayPool.get().returnBuf(buffer); bytes.close(); } } /** * ?RespondHeaderMap */ private static Map<String, String> convertHeaders(Header[] headers) { Map<String, String> result = new HashMap<String, String>(); for (int i = 0; i < headers.length; i++) { result.put(headers[i].getName(), headers[i].getValue()); } return result; } }