/** * Returns the response body as string.<br> * Disconnects the internal HttpURLConnection silently. * * @return response body * @throws SystemException */ public String asString() throws SystemException { if (null == responseAsString) { BufferedReader br; try { InputStream stream = asStream(); if (null == stream) { return null; } br = new BufferedReader(new InputStreamReader(stream, "UTF-8")); StringBuffer buf = new StringBuffer(); String line; while (null != (line = br.readLine())) { buf.append(line).append("\r\n"); } this.responseAsString = buf.toString(); if (Configuration.isDalvik()) { this.responseAsString = unescape(responseAsString); } log(responseAsString); stream.close(); con.disconnect(); streamConsumed = true; } catch (NullPointerException npe) { // don't remember in which case npe can be thrown throw new SystemException(npe.getMessage(), npe); } catch (IOException ioe) { throw new SystemException(ioe.getMessage(), ioe); } } return responseAsString; }
/** * HTTP响应类 * * @author Zhoujun */ public class Response { private static final boolean DEBUG = Configuration.getDebug(); private static ThreadLocal<DocumentBuilder> builders = new ThreadLocal<DocumentBuilder>() { @Override protected DocumentBuilder initialValue() { try { return DocumentBuilderFactory.newInstance().newDocumentBuilder(); } catch (ParserConfigurationException ex) { throw new ExceptionInInitializerError(ex); } } }; private int statusCode; private Document responseAsDocument = null; private String responseAsString = null; private InputStream is; private HttpURLConnection con; private boolean streamConsumed = false; public Response() {} public Response(HttpURLConnection con) throws IOException { this.con = con; this.statusCode = con.getResponseCode(); if (null == (is = con.getErrorStream())) { is = con.getInputStream(); } if (null != is && "gzip".equals(con.getContentEncoding())) { // the response is gzipped is = new GZIPInputStream(is); } } // for test purpose /*package*/ Response(String content) { this.responseAsString = content; } public int getStatusCode() { return statusCode; } public String getResponseHeader(String name) { if (con != null) return con.getHeaderField(name); else return null; } /** * Returns the response stream.<br> * This method cannot be called after calling asString() or asDcoument()<br> * It is suggested to call disconnect() after consuming the stream. * * <p>Disconnects the internal HttpURLConnection silently. * * @return response body stream * @throws SystemException * @see #disconnect() */ public InputStream asStream() { if (streamConsumed) { throw new IllegalStateException("Stream has already been consumed."); } return is; } /** * Returns the response body as string.<br> * Disconnects the internal HttpURLConnection silently. * * @return response body * @throws SystemException */ public String asString() throws SystemException { if (null == responseAsString) { BufferedReader br; try { InputStream stream = asStream(); if (null == stream) { return null; } br = new BufferedReader(new InputStreamReader(stream, "UTF-8")); StringBuffer buf = new StringBuffer(); String line; while (null != (line = br.readLine())) { buf.append(line).append("\r\n"); } this.responseAsString = buf.toString(); if (Configuration.isDalvik()) { this.responseAsString = unescape(responseAsString); } log(responseAsString); stream.close(); con.disconnect(); streamConsumed = true; } catch (NullPointerException npe) { // don't remember in which case npe can be thrown throw new SystemException(npe.getMessage(), npe); } catch (IOException ioe) { throw new SystemException(ioe.getMessage(), ioe); } } return responseAsString; } /** * Returns the response body as org.w3c.dom.Document.<br> * Disconnects the internal HttpURLConnection silently. * * @return response body as org.w3c.dom.Document * @throws SystemException */ public Document asDocument() throws SystemException { if (null == responseAsDocument) { try { // it should be faster to read the inputstream directly. // but makes it difficult to troubleshoot this.responseAsDocument = builders.get().parse(new ByteArrayInputStream(asString().getBytes("UTF-8"))); } catch (SAXException saxe) { throw new SystemException( "The response body was not well-formed:\n" + responseAsString, saxe); } catch (IOException ioe) { throw new SystemException("There's something with the connection.", ioe); } } return responseAsDocument; } /** * Returns the response body as sinat4j.org.json.JSONObject.<br> * Disconnects the internal HttpURLConnection silently. * * @return response body as sinat4j.org.json.JSONObject * @throws SystemException */ public JSONObject asJSONObject() throws SystemException { try { return new JSONObject(asString()); } catch (JSONException jsone) { throw new SystemException(jsone.getMessage() + ":" + this.responseAsString, jsone); } } /** * Returns the response body as sinat4j.org.json.JSONArray.<br> * Disconnects the internal HttpURLConnection silently. * * @return response body as sinat4j.org.json.JSONArray * @throws SystemException */ public JSONArray asJSONArray() throws SystemException { try { return new JSONArray(asString()); } catch (Exception jsone) { throw new SystemException(jsone.getMessage() + ":" + this.responseAsString, jsone); } } public InputStreamReader asReader() { try { return new InputStreamReader(is, "UTF-8"); } catch (java.io.UnsupportedEncodingException uee) { return new InputStreamReader(is); } } public void disconnect() { con.disconnect(); } private static Pattern escaped = Pattern.compile("&#([0-9]{3,5});"); /** * Unescape UTF-8 escaped characters to string. * * @author aizhimin * @param original The string to be unescaped. * @return The unescaped string */ public static String unescape(String original) { Matcher mm = escaped.matcher(original); StringBuffer unescaped = new StringBuffer(); while (mm.find()) { mm.appendReplacement(unescaped, Character.toString((char) Integer.parseInt(mm.group(1), 10))); } mm.appendTail(unescaped); return unescaped.toString(); } @Override public String toString() { if (null != responseAsString) { return responseAsString; } return "Response{" + "statusCode=" + statusCode + ", response=" + responseAsDocument + ", responseString='" + responseAsString + '\'' + ", is=" + is + ", con=" + con + '}'; } private void log(String message) { if (DEBUG) { System.out.println("[" + new java.util.Date() + "]" + message); } } public String getResponseAsString() { return responseAsString; } public void setResponseAsString(String responseAsString) { this.responseAsString = responseAsString; } public void setStatusCode(int statusCode) { this.statusCode = statusCode; } }