httpclientutil.java
字号:
/* Sesame - Storage and Querying architecture for RDF and RDF Schema * Copyright (C) 2001-2005 Aduna * * Contact: * Aduna * Prinses Julianaplein 14 b * 3817 CS Amersfoort * The Netherlands * tel. +33 (0)33 465 99 87 * fax. +33 (0)33 465 99 87 * * http://aduna.biz/ * http://www.openrdf.org/ * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */package org.openrdf.util.http;import java.io.IOException;import java.io.InputStream;import java.io.OutputStream;import java.io.OutputStreamWriter;import java.io.UnsupportedEncodingException;import java.io.Writer;import java.net.HttpURLConnection;import java.net.URLConnection;import java.util.ArrayList;import java.util.Iterator;import java.util.List;import java.util.Map;import java.util.Set;import java.util.zip.GZIPInputStream;/** * Utility methods for HTTP clients. **/public class HttpClientUtil { private static final String CRLF = "\r\n";/*---------------------+| Methods |+---------------------*/ /** * Prepares an HttpURLConnection for a POST request that sends the * supplied parameters. * * @param connection The connection to prepare for the request. * @param parameters The key-value pairs to send in the POST * request. * * @exception IOException If an I/O error occurs. **/ public static void preparePostRequest(HttpURLConnection connection, Map parameters) throws IOException { // Create x-www-url-encoded parameter string String postData = buildQueryString(parameters); // Set up request connection.setRequestMethod("POST"); connection.setDoInput(true); connection.setDoOutput(true); connection.setUseCaches(false); // Write the form data to the connection OutputStream postStream = connection.getOutputStream(); Writer postWriter = new OutputStreamWriter(postStream); postWriter.write(postData); postWriter.flush(); postWriter.close(); } public static void prepareMultipartPostRequest(HttpURLConnection connection, Map parameters, String encoding) throws UnsupportedEncodingException, IOException { String boundary = "---8qP3mZ1yyysss---"; byte[] postData = buildMultipartFormData(parameters, boundary, encoding); // Build the form data as a multipart/form-data byte array. connection.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + boundary); connection.setRequestProperty("Content-Length", String.valueOf(postData.length)); // Set up request connection.setRequestMethod("POST"); connection.setDoInput(true); connection.setDoOutput(true); connection.setUseCaches(false); // Write the form data to the connection OutputStream postStream = connection.getOutputStream(); postStream.write(postData); postStream.flush(); postStream.close(); } /** * Builds a multipart/form-data encoded byte array of the specified parameters, * that complies to <a href="http://www.ietf.org/rfc/rfc1867.txt">RFC 1867</a>. * Note that the request sent to the server should have a header of the following * form set: <tt>Content-type: multipart/form-data, boundary=boundary-parameter</tt>. * E.g.: * <pre> * HttpURLConnection connection = (HttpURLConnection)url.openConnection(); * connection.setRequestProperty("Content-type", "multipart/form-data, boundary=AaB03x"); * </pre> * * @param parameters A map of String keys to values that are either <tt>FilePart</tt>s, in * which case its contents will be uploaded; byte arrays, which will be uploaded as-is; or * any other Object, in which case the value of the object's <tt>toString()</tt> method * will be used. * @param boundary A boundary to use as separator between the encoded parts of the data. * @param encoding The character encoding for the data, e.g. "UTF-8". * @return A byte array in multipart/form-data format. **/ public static byte[] buildMultipartFormData(Map parameters, String boundary, String encoding) throws UnsupportedEncodingException { List parts = new ArrayList(parameters.size()); int partLengthSum = 0; Iterator iter = parameters.entrySet().iterator(); while (iter.hasNext()) { Map.Entry entry = (Map.Entry)iter.next(); String key = (String)entry.getKey(); Object value = entry.getValue(); byte[] partHeader, partContents; if (value instanceof FilePart) { FilePart fp = (FilePart)value; partHeader = ("Content-Disposition: form-data; name=\"" + key + "\"; filename=\"" + fp.getName() + "\"" + CRLF + "Content-Type: " + fp.getContentType() + CRLF + CRLF).getBytes(); partContents = fp.getBytes(); } else { partHeader = ("Content-Disposition: form-data; name=\"" + key + "\"" + CRLF + CRLF).getBytes(); if (value instanceof byte[]) { partContents = (byte[])value; } else { partContents = value.toString().getBytes(encoding); } } byte[] part = new byte[partHeader.length + partContents.length]; System.arraycopy(partHeader, 0, part, 0, partHeader.length); System.arraycopy(partContents, 0, part, partHeader.length, partContents.length); parts.add(part); partLengthSum += part.length; } byte[] startBoundary = (CRLF + "--" + boundary + CRLF).getBytes(); byte[] endBoundary = (CRLF + "--" + boundary + "--" + CRLF).getBytes(); int totalLength = parts.size() * startBoundary.length + endBoundary.length + partLengthSum; byte[] result = new byte[totalLength]; int idx = 0; for (int i = 0; i < parts.size(); i++) { byte[] part = (byte[])parts.get(i); System.arraycopy(startBoundary, 0, result, idx, startBoundary.length); idx += startBoundary.length; System.arraycopy(part, 0, result, idx, part.length); idx += part.length; } System.arraycopy(endBoundary, 0, result, idx, endBoundary.length); return result; } /** * Builds a query string from the provided key-value-pairs. All * spaces are substituted by '+' characters, and all non US-ASCII * characters are escaped to hexadecimal notation (%xx). **/ public static String buildQueryString(Map keyValuePairs) { StringBuffer result = new StringBuffer(20*keyValuePairs.size()); Set entrySet = keyValuePairs.entrySet(); Iterator iter = entrySet.iterator(); while (iter.hasNext()) { // Iterate over all key-value pairs Map.Entry keyValuePair = (Map.Entry)iter.next(); String key = (String)keyValuePair.getKey(); String value = (String)keyValuePair.getValue(); // Escape both key and value and combine them with an '=' _formUrlEncode(key, result); result.append('='); _formUrlEncode(value, result); // If there are more key-value pairs, append an '&' if (iter.hasNext()) { result.append('&'); } } return result.toString(); } /** * Encodes a string according to RFC 1738 : Uniform Resource locators (URL). * According to this spec, any characters outside the range 0x20 - 0x7E must * be escaped because they are not printable characters. Within the range * a number of characters are deemed unsafe or are marked as reserved. In * short: According to the spec only the alphanumerics and the special * characters from <tt>$-_.+!*'(),</tt> can be left unencoded. To be save * this method will encode all characters that are not alphanumerics. **/ private static void _formUrlEncode(String s, StringBuffer buf) { for (int i = 0; i < s.length(); i++) { char c = s.charAt(i); int cInt = (int)c; // Only characters in the range 48 - 57 (numbers), 65 - 90 (upper // case letters), 97 - 122 (lower case letters) can be left // unencoded. The rest needs to be escaped. if (cInt >= 48 && cInt <= 57 || cInt >= 65 && cInt <= 90 || cInt >= 97 && cInt <= 122) { // alphanumeric character buf.append(c); } else { // Escape all non-alphanumerics buf.append('%'); String hexVal = Integer.toHexString(cInt); // Ensure use of two characters if (hexVal.length() == 1) { buf.append('0'); } buf.append(hexVal); } } } /** * Sets a request property on the supplied connection indicating that a * server can respond with gzip-encoded data if it wants to. * * @see #getInputStream **/ public static void setAcceptGZIPEncoding(URLConnection conn) { conn.setRequestProperty("Accept-Encoding", "gzip"); } /** * Gets the InputStream for reading the response from a server. This method * handles any encoding-related decoding of the data, e.g. gzip. * * @see #setAcceptGZIPEncoding **/ public static InputStream getInputStream(URLConnection conn) throws IOException { InputStream responseStream = conn.getInputStream(); String contentEncoding = conn.getContentEncoding(); if ("gzip".equalsIgnoreCase(contentEncoding)) { responseStream = new GZIPInputStream(responseStream); } return responseStream; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -