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.discovery.darchrow.net; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.io.UnsupportedEncodingException; import java.net.MalformedURLException; import java.net.URI; import java.net.URISyntaxException; import java.net.URL; import java.net.URLDecoder; import java.net.URLEncoder; import java.util.ArrayList; import java.util.HashMap; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.discovery.darchrow.io.IOWriteUtil; import com.discovery.darchrow.lang.ArrayUtil; import com.discovery.darchrow.lang.CharsetType; import com.discovery.darchrow.lang.StringUtil; import com.discovery.darchrow.slf4j.Slf4jUtil; import com.discovery.darchrow.util.CollectionsUtil; import com.discovery.darchrow.util.Validator; /** * ?{@link java.net.URI}(Uniform Resource Locator) {@link java.net.URL}(Uniform Resource Identifier) . * * <h3>{@link java.net.URI} {@link java.net.URL}:</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>{@link java.net.URL URL}<br> * (Uniform Resource Locator)</td> * <td>???<br> * ???URI?URL???locate? <br> * See RFC 1738: Uniform Resource Locators (URL)</td> * </tr> * <tr valign="top" style="background-color:#eeeeff"> * <td>{@link java.net.URI URI}<br> * (Uniform Resource Identifier)</td> * <td> * There are two types of URIs: URLs and URNs. <br> * See RFC 1630: Universal Resource Identifiers in WWW: A Unifying Syntax for the Expression of Names and Addresses of Objects on the * Network as used in the WWW.</td> * </tr> * </table> * * URI??????URI;URL???????schema * </blockquote> * * * @author feilong * @version 1.0.0 2010-6-11 ?02:06:43 * @see java.net.URI * @see java.net.URL * @see URIComponents * @since 1.0.0 */ public final class URIUtil { /** The Constant LOGGER. */ private static final Logger LOGGER = LoggerFactory.getLogger(URIUtil.class); /** Don't let anyone instantiate this class. */ private URIUtil() { //AssertionError?. ?????. ???. //see Effective Java 2nd throw new AssertionError("No " + getClass().getName() + " instances for you!"); } /** * . * <p> * ??? . * </p> * * @param urlString * ?<br> * url ?? * @param directoryName * * @throws IOException * the IO exception * @see IOWriteUtil#write(InputStream, String, String) */ public static void download(String urlString, String directoryName) throws IOException { if (Validator.isNullOrEmpty(urlString)) { throw new NullPointerException("urlString can't be null/empty!"); } if (Validator.isNullOrEmpty(directoryName)) { throw new NullPointerException("directoryName can't be null/empty!"); } LOGGER.info("begin download,urlString:[{}],directoryName:[{}]", urlString, directoryName); URL url = new URL(urlString); InputStream inputStream = url.openStream(); File file = new File(urlString); String fileName = file.getName(); IOWriteUtil.write(inputStream, directoryName, fileName); LOGGER.info("end download,url:[{}],directoryName:[{}]", urlString, directoryName); } /** * urlcharset {@link URI}. <br> * {@link URI#create(String)}<br> * * <p> * url????, {@link URI#create(String)}<br> * url???, {@link #getEncodedUrlByArrayMap(String, Map, String)}url,? {@link URI#create(String)} * </p> * * @param url * url * @param charsetType * ??null empty,?,?<br> * ??,??,ie?chrome ? url , ? * @return if isNullOrEmpty(url),return null;<br> * if Exception,return null * @see <a * href="http://stackoverflow.com/questions/15004593/java-request-getquerystring-value-different-between-chrome-and-ie-browser">java-request-getquerystring-value-different-between-chrome-and-ie-browser</a> * @see URI#create(String) * @see #getEncodedUrlByArrayMap(String, Map, String) */ public static URI create(String url, String charsetType) { try { String encodeUrl = encodeUrl(url, charsetType); URI uri = URI.create(encodeUrl); return uri; } catch (Exception e) { LOGGER.error("Exception:", e); throw new URIParseException(e); } } /** * urlcharset {@link URI} <br> * {@link URI#create(String)}<br> * * <p> * url????, {@link URI#create(String)}<br> * url???, {@link #getEncodedUrlByArrayMap(String, Map, String)}url,? {@link URI#create(String)} * </p> * . * * @param url * url * @param charsetType * ??null empty,?,?<br> * ??,??,ie?chrome ? url , ? * @return the string * @see <a * href="http://stackoverflow.com/questions/15004593/java-request-getquerystring-value-different-between-chrome-and-ie-browser">java-request-getquerystring-value-different-between-chrome-and-ie-browser</a> * @see URI#create(String) * @see #getEncodedUrlByArrayMap(String, Map, String) */ public static String encodeUrl(String url, String charsetType) { if (Validator.isNullOrEmpty(url)) { throw new NullPointerException("the url is null or empty!"); } if (Validator.isNullOrEmpty(charsetType)) { throw new NullPointerException("the charsetType is null or empty!"); } LOGGER.debug("in url:[{}],charsetType:{}", url, charsetType); // ?? ? // cmens/t-b-f-a-c-s-f-p400-600,0-200,200-400,600-up-gCold Gear-eBase Layer-i1-o.htm if (StringUtil.isContain(url, URIComponents.QUESTIONMARK)) { // ??? String before = getBeforePath(url); String query = StringUtil.substring(url, URIComponents.QUESTIONMARK, 1); Map<String, String[]> map = parseQueryToArrayMap(query, charsetType); String encodeUrl = getEncodedUrlByArrayMap(before, map, charsetType); if (LOGGER.isDebugEnabled()) { LOGGER.debug("after url:{}", encodeUrl); } return encodeUrl; } else { // ?? ??? return url; } // ?URI?URISyntaxException???create(String uri) // new URI(str) } /** * call {@link java.net.URI#URI(String)}. * <p> * StringURI???RFC 2396java.net.URISyntaxException. * </p> * * @param path * the path * @return {@link java.net.URI#URI(String)} * @see java.net.URI#URI(String) */ public static URI getURI(String path) { try { // StringURI???RFC 2396java.net.URISyntaxException. URI uri = new URI(path); return uri; } catch (URISyntaxException e) { LOGGER.error(Slf4jUtil.formatMessage("path:[{}]", path), e); throw new URIParseException(e); } } /** * ?path??. * * @param path * ? * @return ??, <b>true </b>,? <b>false </b> */ public static boolean isAbsolutePath(String path) { URI uri = getURI(path); if (null == uri) { return false; } return uri.isAbsolute(); } /** * url(charsetType null,,?,url). * * @param beforeUrl * ???, ?, ?? keyAndValueMap * @param keyAndValueMap * ?Map? Map * @param charsetType * ??null empty,?,?<br> * ??,??,ie?chrome ? url , ? * @return the encoded url1 */ public static String getEncodedUrlByValueMap(String beforeUrl, Map<String, String> keyAndValueMap, String charsetType) { Map<String, String[]> keyAndArrayMap = new HashMap<String, String[]>(); if (Validator.isNotNullOrEmpty(keyAndValueMap)) { for (Map.Entry<String, String> entry : keyAndValueMap.entrySet()) { String key = entry.getKey(); String value = entry.getValue(); keyAndArrayMap.put(key, new String[] { value }); } } return getEncodedUrlByArrayMap(beforeUrl, keyAndArrayMap, charsetType); } /** * url(charsetType null,,?,url). * * @param beforeUrl * ???, ?, ?? keyAndArrayMap * @param keyAndArrayMap * ?map value? request.getParameterMap * @param charsetType * ??null empty,?,?<br> * ??,??,ie?chrome ? url , ? * @return if isNullOrEmpty(keyAndArrayMap) return beforeUrl; * @see #combineQueryString(Map, String) */ public static String getEncodedUrlByArrayMap(String beforeUrl, Map<String, String[]> keyAndArrayMap, String charsetType) { if (Validator.isNullOrEmpty(keyAndArrayMap)) { return beforeUrl; } // map ? ? Map<String, String[]> appendMap = new HashMap<String, String[]>(); appendMap.putAll(keyAndArrayMap); // ? action before ?? // "action": "https://202.6.215.230:8081/purchasing/purchase.do?action=loginRequest", // "fullEncodedUrl": // "https://202.6.215.230:8081/purchasing/purchase.do?action=loginRequest?miscFee=0&descp=&klikPayCode=03BELAV220&callback=%2Fpatment1url&totalAmount=60000.00&payType=01&transactionNo=20140323024019&signature=1278794012&transactionDate=23%2F03%2F2014+02%3A40%3A19¤cy=IDR", // ******************************************* String beforePath = beforeUrl; // ?? if (StringUtil.isContain(beforeUrl, URIComponents.QUESTIONMARK)) { // ??? beforePath = getBeforePath(beforeUrl); String query = StringUtil.substring(beforeUrl, URIComponents.QUESTIONMARK, 1); Map<String, String[]> map = parseQueryToArrayMap(query, null); appendMap.putAll(map); } StringBuilder builder = new StringBuilder(""); builder.append(beforePath); builder.append(URIComponents.QUESTIONMARK); // ******************************************* String queryString = combineQueryString(appendMap, charsetType); builder.append(queryString); return builder.toString(); } /** * map ?? queryString. * * @param appendMap * request.getParamMap * @param charsetType * {@link CharsetType} ??null empty,?,?<br> * ??,??,ie?chrome ? url , ? * @return if isNullOrEmpty(appendMap) ,return "" * @see CharsetType */ public static String combineQueryString(Map<String, String[]> appendMap, String charsetType) { if (Validator.isNullOrEmpty(appendMap)) { return ""; } StringBuilder sb = new StringBuilder(); int i = 0; int size = appendMap.size(); for (Map.Entry<String, String[]> entry : appendMap.entrySet()) { String key = entry.getKey(); String[] paramValues = entry.getValue(); // ************************************************************** if (Validator.isNotNullOrEmpty(charsetType)) { // decode ? encode // ? key = encode(decode(key, charsetType), charsetType); } // ************************************************************** if (Validator.isNullOrEmpty(paramValues)) { LOGGER.warn("the param key:[{}] value is null", key); sb.append(key); sb.append("="); sb.append(""); } else { List<String> paramValueList = null; // value isNotNullOrEmpty if (Validator.isNotNullOrEmpty(charsetType)) { paramValueList = new ArrayList<String>(); for (String value : paramValues) { if (Validator.isNotNullOrEmpty(value)) { // ?queryString()? // chrome query encoded ??? // ie ???? // ??encoded, decode ? encode // ? decode(query, charsetType) ,? = paramValueList.add(encode(decode(value.toString(), charsetType), charsetType)); } else { paramValueList.add(""); } } } else { paramValueList = ArrayUtil.toList(paramValues); } for (int j = 0, z = paramValueList.size(); j < z; ++j) { String value = paramValueList.get(j); sb.append(key); sb.append("="); sb.append(value); // ?& ? if (j != z - 1) { sb.append(URIComponents.AMPERSAND); } } } // ?& ? if (i != size - 1) { sb.append(URIComponents.AMPERSAND); } ++i; } return sb.toString(); } /** * {@code a=1&b=2}????map (charsetType ?nullempty keyvalue). * * @param query * the query * @param charsetType * ??null empty,?,?<br> * ??,??,ie?chrome ? url , ? * @return the {@code map<string, string>} * @see #parseQueryToArrayMap(String, String) */ public static Map<String, String> parseQueryToValueMap(String query, String charsetType) { Map<String, String> returnMap = new HashMap<String, String>(); Map<String, String[]> map = parseQueryToArrayMap(query, charsetType); if (Validator.isNotNullOrEmpty(map)) { for (Map.Entry<String, String[]> entry : map.entrySet()) { String key = entry.getKey(); String[] value = entry.getValue(); returnMap.put(key, value[0]); } } return returnMap; } /** * {@code a=1&b=2}????map (charsetType ?nullempty keyvalue). * * @param query * {@code a=1&b=2}?,?{@code a=1&a=1}? map * @param charsetType * ??null empty,?,?<br> * ??,??,ie?chrome ? url , ? * @return map value? {@link LinkedHashMap#LinkedHashMap(int, float)} * <ul> * <li>Validator.isNullOrEmpty(bianma) </li> * <li>?, decode ? encode</li> * </ul> */ public static Map<String, String[]> parseQueryToArrayMap(String query, String charsetType) { if (Validator.isNotNullOrEmpty(query)) { String[] nameAndValueArray = query.split(URIComponents.AMPERSAND); if (Validator.isNotNullOrEmpty(nameAndValueArray)) { Map<String, String[]> map = new LinkedHashMap<String, String[]>(); for (int i = 0, j = nameAndValueArray.length; i < j; ++i) { String nameAndValue = nameAndValueArray[i]; String[] tempArray = nameAndValue.split("=", 2); if (tempArray != null && tempArray.length == 2) { String key = tempArray[0]; String value = tempArray[1]; if (Validator.isNullOrEmpty(charsetType)) { // ? } else { // ?queryString()? // chrome query encoded ??? // ie ???? // ??encoded, decode ? encode // ? decode(query, charsetType) ,? = // decode ? encode // ? key = encode(decode(key, charsetType), charsetType); value = encode(decode(value, charsetType), charsetType); } String[] valuesArrayInMap = map.get(key); List<String> list = null; if (Validator.isNullOrEmpty(valuesArrayInMap)) { list = new ArrayList<String>(); } else { list = ArrayUtil.toList(valuesArrayInMap); } list.add(value); map.put(key, CollectionsUtil.toArray(list)); } } return map; } } return null; } /** * ????(???). * * @param url * the url * @return if isNullOrEmpty(url),renturn "" * @deprecated will rename ??? */ //TODO will rename @Deprecated public static String getBeforePath(String url) { if (Validator.isNullOrEmpty(url)) { return ""; } String before = ""; // url??? int index = url.indexOf(URIComponents.QUESTIONMARK); if (index == -1) { before = url; } else { before = url.substring(0, index); } return before; } /** * ???url, spec ? URL. URL URL spec ?<br> * ?,{@link #getUnionUrl(URL, String)} * <p> * : URIUtil.getUnionUrl("E:\\test", "sanguo")-------------{@code >}file:/E:/test/sanguo * * @param context * ?? * @param spec * the <code>String</code> to parse as a URL. * @return ???url */ public static String getUnionUrl(String context, String spec) { URL parentUrl = getURL(context); return getUnionUrl(parentUrl, spec); } /** * ???url, spec ? URL. URL URL spec ?<br> * ?,method * * <pre> * {@code * : URIUtil.getUnionUrl("E:\\test", "sanguo")------------->file:/E:/test/sanguo * URL url = new URL("http://www.exiaoshuo.com/jinyiyexing/"); * result = URIUtil.getUnionUrl(url, "/jinyiyexing/1173348/"); * http://www.exiaoshuo.com/jinyiyexing/1173348/ * } * </pre> * * @param context * ?? * @param spec * the <code>String</code> to parse as a URL. * @return ???url */ public static String getUnionUrl(URL context, String spec) { try { URL unionUrl = new URL(context, spec); return unionUrl.toString(); } catch (MalformedURLException e) { LOGGER.error("MalformedURLException:", e); throw new URIParseException(e); } } /** * ?url. * * @param filePathName * * @return url * @see java.io.File#toURI() * @see java.net.URI#toURL() */ public static URL getURL(String filePathName) { if (Validator.isNullOrEmpty(filePathName)) { throw new NullPointerException("filePathName can't be null/empty!"); } File file = new File(filePathName); try { // file.toURL() ?,? URL ? return file.toURI().toURL(); } catch (MalformedURLException e) { LOGGER.error("MalformedURLException:", e); throw new URIParseException(e); } } // [start] encode/decode /** * iso-8859??. * * @param str * * @param bianma * ? * @return ?<br> * if isNullOrEmpty(str) return "" * @deprecated */ @Deprecated public static String decodeLuanMaISO8859(String str, String bianma) { if (Validator.isNullOrEmpty(str)) { return ""; } //StringUtil.toBytes(value, charsetName) try { return new String(str.trim().getBytes(CharsetType.ISO_8859_1), bianma); } catch (UnsupportedEncodingException e) { LOGGER.error(e.getClass().getName(), e); } return ""; } //************************************************************************************** /** * ?,?? <br> * * <ul> * <li>? "a" "z"?"A" "Z" "0" "9" ????.</li> * <li> "."?"-"?"*" "_" ????.</li> * <li> " " ?? "+".</li> * <li>???.<br> * ??? 3 "%xy" xy ????.<br> * ??? UTF-8.<br> * ????.</li> * </ul> * * @param value * the value * @param charsetType * charsetType {@link CharsetType} * @return {@link java.net.URLEncoder#encode(String, String)}<br> * if isNullOrEmpty(charsetType), value<br> * @see URLEncoder#encode(String, String) * @see CharsetType */ public static String encode(String value, String charsetType) { if (Validator.isNullOrEmpty(charsetType)) { return value; } try { return URLEncoder.encode(value, charsetType); } catch (UnsupportedEncodingException e) { LOGGER.error("UnsupportedEncodingException:", e); throw new URIParseException(e); } } /** * ?,?? <br> * Decodes a <code>application/x-www-form-urlencoded</code> string using a specific encoding scheme. The supplied encoding is used to * determine what characters are represented by any consecutive sequences of the form "<code>%<i>xy</i></code>". * * <p> * Not doing so may introduce incompatibilites.<br> * <em><strong>Note:</strong> * <a href="http://www.w3.org/TR/html40/appendix/notes.html#non-ascii-chars">World Wide Web Consortium Recommendation</a>UTF-8. ????.</em> * </p> * * @param value * ?? * @param charsetType * charsetType {@link CharsetType} * @return the newly {@link java.net.URLDecoder#decode(String, String)} ??<br> * if isNullOrEmpty(charsetType) , value<br> * @see URLEncoder#encode(java.lang.String, java.lang.String) * @see CharsetType */ public static String decode(String value, String charsetType) { if (Validator.isNullOrEmpty(charsetType)) { return value; } try { return URLDecoder.decode(value, charsetType); } catch (UnsupportedEncodingException e) { LOGGER.error("UnsupportedEncodingException:", e); throw new URIParseException(e); } } /** * queryString. * * <h3>:</h3> * <blockquote> * * <pre class="code"> * URIUtil.getQueryString({@code "http://127.0.0.1/cmens/t-b-f-a-c-s-f-p-g-e-i-o.htm?a=1&a=2"}) * </pre> * * : {@code a=1&a=2} * </blockquote> * * @param uriString * the uri * @return ? <code>uriString</code> isNullOrEmpty, {@link StringUtils#EMPTY};<br> * ? <code>uriString</code> ???, {@link StringUtils#EMPTY};<br> * ????? * @since 1.4.0 */ public static String getQueryString(String uriString) { if (Validator.isNullOrEmpty(uriString)) { return StringUtils.EMPTY; } // url??? XXX int index = uriString.indexOf(URIComponents.QUESTIONMARK); return index == StringUtils.INDEX_NOT_FOUND ? StringUtils.EMPTY : StringUtil.substring(uriString, index + 1); } /** * ??queryStringpath,????( <span style="color:red">???</span>). * * @param uriString * the uri * @return isNullOrEmpty(url), {@link StringUtils#EMPTY} * @since 1.4.0 */ public static String getFullPathWithoutQueryString(String uriString) { if (Validator.isNullOrEmpty(uriString)) { return StringUtils.EMPTY; } // url??? XXX int index = uriString.indexOf(URIComponents.QUESTIONMARK); return index == StringUtils.INDEX_NOT_FOUND ? uriString : uriString.substring(0, index); } // [end] //********************************************************************************* /** * url16?,url. * * @param specialCharacter * * @return url? * @deprecated ?? */ @Deprecated public static String specialCharToHexString(String specialCharacter) { Map<String, String> specialCharacterMap = new HashMap<String, String>(); specialCharacterMap.put("+", "%2B");// URL +? specialCharacterMap.put(" ", "%20");// URL?+?? specialCharacterMap.put("/", "%2F");// ? specialCharacterMap.put(URIComponents.QUESTIONMARK, "%3F");// URL ? specialCharacterMap.put("%", "%25");// specialCharacterMap.put("#", "%23");// specialCharacterMap.put("&", "%26");// URL ? specialCharacterMap.put("=", "%3D");// URL ? if (specialCharacterMap.containsKey(specialCharacter)) { return specialCharacterMap.get(specialCharacter); } // ? url return specialCharacter; } }