Java tutorial
/* * Copyright (C) 2008 feilong * * 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.sunchenbin.store.feilong.core.net; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.net.HttpURLConnection; import java.net.InetSocketAddress; import java.net.MalformedURLException; import java.net.Proxy; import java.net.SocketAddress; import java.net.URL; import java.net.URLConnection; import java.util.Map; import org.apache.commons.io.IOUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.sunchenbin.store.feilong.core.io.InputStreamUtil; import com.sunchenbin.store.feilong.core.io.ReaderUtil; import com.sunchenbin.store.feilong.core.io.UncheckedIOException; import com.sunchenbin.store.feilong.core.tools.jsonlib.JsonUtil; import com.sunchenbin.store.feilong.core.util.Validator; /** * {@link java.net.HttpURLConnection}(?? {@link java.net.Proxy}). * * <h3>:</h3> * * <blockquote> * <p> * {@link java.net.HttpURLConnection}HTTP??,socket<br> * <span style="color:red"> ?timeout,,???</span> <br> * JDK1.5- ,??? * </p> * <ul> * <li>System.setProperty("sun.net.client.defaultConnectTimeout", );</li> * <li>System.setProperty("sun.net.client.defaultReadTimeout", );</li> * </ul> * <p> * JDK1.5+,?HttpURLConnectionURLConnection * </p> * <ul> * <li>{@link URLConnection#setConnectTimeout(int)}??</li> * <li>{@link URLConnection#setReadTimeout(int)}????</li> * </ul> * * </blockquote> * * * <h3>?:</h3> * * <blockquote> * <p> * JDK5-URLHttpConnection???,??URL.openConnection()??? * </p> * * <pre> * Properties properties = System.getProperties(); * properties.put("http.proxyHost", "120.0.0.1"); * properties.put("http.proxyPort", "1080"); * </pre> * * ?JDK5+ URL {@link URL#openConnection(Proxy)},???,? * * <pre> * URL url = new URL("http://www.javatang.com"); * <span style="color:green">// ??</span> * SocketAddress add = new InetSocketAddress("120.0.0.1", "1080"); * Proxy proxy = new Proxy(Proxy.Type.SOCKS , add); * <span style="color:green">// </span> * HttpURLConnection conn = (HttpURLConnection)url.openConnection(proxy); .openConnection(p); * </pre> * * </blockquote> * * * <h3> {@link HttpURLConnection#setDoInput(boolean)} && {@link HttpURLConnection#setDoOutput(boolean)}</h3> * * * <blockquote> * * * <table border="1" cellspacing="0" cellpadding="4"> * <tr style="background-color:#ccccff"> * <th align="left"></th> * <th align="left"></th> * </tr> * <tr valign="top"> * <td>httpUrlConnection.setDoOutput(true);</td> * <td>??conn.getOutputStream().write()<br> * get?conn.getOutputStream(),????,false<br> * post????,?httpbody?,??,??<br> * URL?URL,DoOutputtrue?,falsefalse</td> * </tr> * <tr valign="top" style="background-color:#eeeeff"> * <td>httpUrlConnection.setDoInput(true);</td> * <td>??conn.getInputStream().read();<br> * conn.getInputStream()???,true<br> * URL?URL,DoInputtrue?,falsetrue</td> * </tr> * </table> * * <p> * ??? {@link "org.springframework.http.client.SimpleClientHttpRequestFactory#prepareConnection(HttpURLConnection, String)"} * </p> * </blockquote> * * * <h3> {@link HttpURLConnection#connect()} && {@link HttpURLConnection#getOutputStream()}</h3> * * <blockquote> * <p> * getOutputStream??connect(???connect(),?? httpURLConnection.connect(); ?).<br> * URL ?. connected true connect ,.<br> * ??tcp,??http.<br> * postget,httpHttpURLConnectiongetInputStream()?????. * </p> * </blockquote> * * @author feilong * @version 1.0 Sep 26, 2013 11:10:59 AM * @see java.net.HttpURLConnection * @see java.net.URLConnection * @see "org.springframework.http.client.SimpleClientHttpRequestFactory" * @since 1.0.2 */ public final class URLConnectionUtil { /** The Constant LOGGER. */ private static final Logger LOGGER = LoggerFactory.getLogger(URLConnectionUtil.class); /** Don't let anyone instantiate this class. */ private URLConnectionUtil() { //AssertionError?. ?????. ???. //see Effective Java 2nd throw new AssertionError("No " + getClass().getName() + " instances for you!"); } /** * Read line with proxy. * * @param urlString * the url string * @return ?.???? ('\n')? ('\r') ???. * @see #readLine(String, ConnectionConfig) */ public static String readLine(String urlString) { return readLine(urlString, null); } /** * Read line with proxy. * * @param urlString * the url string * @param connectionConfig * the connection config * @return ?.???? ('\n')? ('\r') ???. */ public static String readLine(String urlString, ConnectionConfig connectionConfig) { InputStream inputStream = getInputStream(urlString, connectionConfig); BufferedReader bufferedReader = InputStreamUtil.toBufferedReader(inputStream, connectionConfig.getContentCharset()); return ReaderUtil.readLine(bufferedReader); } //******************************************************************************************** /** * Gets the response body as string. * * @param urlString * the url string * @return the response body as string * @see #getResponseBodyAsString(String, ConnectionConfig) */ public static String getResponseBodyAsString(String urlString) { return getResponseBodyAsString(urlString, null); } /** * response body as string. * * @param urlString * the url string * @param connectionConfig * connectionConfig * @return the response body as string * @see #getInputStream(String, ConnectionConfig) * @see InputStreamUtil#inputStream2String(InputStream, String) */ public static String getResponseBodyAsString(String urlString, ConnectionConfig connectionConfig) { ConnectionConfig useConnectionConfig = null == connectionConfig ? new ConnectionConfig() : connectionConfig; InputStream inputStream = getInputStream(urlString, useConnectionConfig); return InputStreamUtil.inputStream2String(inputStream, useConnectionConfig.getContentCharset()); } /** * input stream. * * @param urlString * the url string * @return the input stream * @see #getInputStream(String, ConnectionConfig) */ public static InputStream getInputStream(String urlString) { return getInputStream(urlString, null); } /** * input stream. * * @param urlString * the url string * @param connectionConfig * the connection config * @return the input stream * @see #getInputStream(HttpRequest, ConnectionConfig) */ public static InputStream getInputStream(String urlString, ConnectionConfig connectionConfig) { HttpRequest httpRequest = new HttpRequest(); httpRequest.setUri(urlString); return getInputStream(httpRequest, connectionConfig); } /** * input stream. * * @param httpRequest * the http request * @param connectionConfig * the connection config * @return the input stream * @since 1.2.0 * @see "org.springframework.core.io.UrlResource#getInputStream()" */ public static InputStream getInputStream(HttpRequest httpRequest, ConnectionConfig connectionConfig) { HttpURLConnection httpURLConnection = getHttpURLConnection(httpRequest, connectionConfig); try { return httpURLConnection.getInputStream(); } catch (IOException e) { //???. disconnect() ????? HttpURLConnection . //? finally ?, ??inputstream // per Java's documentation, this is not necessary, and precludes keepalives. However in practise, // connection errors will not be released quickly enough and can cause a too many open files error. IOUtils.close(httpURLConnection); // Close the HTTP connection (if applicable). throw new UncheckedIOException(e); } } // **************************************************************************************** /** * {@link java.net.HttpURLConnection}. * * @param httpRequest * the http request * @param connectionConfig * the connection config * @return {@link java.net.HttpURLConnection} */ private static HttpURLConnection getHttpURLConnection(HttpRequest httpRequest, ConnectionConfig connectionConfig) { if (Validator.isNullOrEmpty(httpRequest)) { throw new NullPointerException("httpRequest can't be null/empty!"); } ConnectionConfig useConnectionConfig = null == connectionConfig ? new ConnectionConfig() : connectionConfig; try { HttpURLConnection httpURLConnection = openConnection(httpRequest, useConnectionConfig); prepareConnection(httpURLConnection, httpRequest, useConnectionConfig); return httpURLConnection; } catch (MalformedURLException e) { throw new UncheckedIOException(e); } catch (IOException e) { throw new UncheckedIOException(e); } } /** * Prepare connection. * * @param httpURLConnection * the http url connection * @param httpRequest * the http request * @param useConnectionConfig * the use connection config * @throws IOException * the IO exception * @since 1.4.0 * @see "org.springframework.http.client.SimpleClientHttpRequestFactory#prepareConnection(HttpURLConnection, String)" */ private static void prepareConnection(HttpURLConnection httpURLConnection, HttpRequest httpRequest, ConnectionConfig useConnectionConfig) throws IOException { HttpMethodType httpMethodType = httpRequest.getHttpMethodType(); // ?HttpUrlConnectionconnectTimeout httpURLConnection.setConnectTimeout(useConnectionConfig.getConnectTimeout()); httpURLConnection.setReadTimeout(useConnectionConfig.getReadTimeout()); httpURLConnection.setRequestMethod(httpMethodType.getMethod().toUpperCase());//?,? java.net.ProtocolException: Invalid HTTP method: get httpURLConnection.setDoOutput(HttpMethodType.POST == httpMethodType); Map<String, String> headerMap = httpRequest.getHeaderMap(); if (null != headerMap) { for (Map.Entry<String, String> entry : headerMap.entrySet()) { httpURLConnection.setRequestProperty(entry.getKey(), entry.getValue()); } } } /** * Open connection. * * @param httpRequest * the http request * @param connectionConfig * the connection config * @return the http url connection * @throws IOException * the IO exception * @since 1.2.0 */ private static HttpURLConnection openConnection(HttpRequest httpRequest, ConnectionConfig connectionConfig) throws IOException { ConnectionConfig useConnectionConfig = null == connectionConfig ? new ConnectionConfig() : connectionConfig; LOGGER.debug("httpRequest:[{}],useConnectionConfig:[{}]", JsonUtil.format(httpRequest), JsonUtil.format(useConnectionConfig)); URL url = new URL(httpRequest.getUri()); Proxy proxy = getProxy(useConnectionConfig.getProxyAddress(), useConnectionConfig.getProxyPort()); // urlConnection?URL??(http)?URLConnection?HttpURLConnection, // HttpURLConnection, HttpURLConnectionAPI. if (Validator.isNotNullOrEmpty(proxy)) { LOGGER.debug("use proxy:{}", proxy.toString()); return (HttpURLConnection) url.openConnection(proxy); } // ? URL ???? openConnection . return (HttpURLConnection) url.openConnection(); } // ****************************************************************************************** /** * ?. * * @param proxyAddress * the proxy address * @param proxyPort * ?? <br> * A valid port value is between 0 ~ 65535. <br> * A port number of zero will let the system pick up an ephemeral port in a bind operation. * @return the proxy * @see java.net.Proxy.Type.HTTP * @see java.net.InetSocketAddress#InetSocketAddress(String, int) */ private static Proxy getProxy(String proxyAddress, Integer proxyPort) { if (Validator.isNotNullOrEmpty(proxyAddress) && Validator.isNotNullOrEmpty(proxyPort)) { SocketAddress socketAddress = new InetSocketAddress(proxyAddress, proxyPort); return new Proxy(Proxy.Type.HTTP, socketAddress); } return null; } }