package com.titizz.shorturl; import com.google.common.base.CharMatcher; import com.google.common.base.Splitter; import com.google.common.escape.Escaper; import com.google.common.net.UrlEscapers; import com.linkedin.urls.NormalizedUrl; import com.linkedin.urls.Url; import java.net.MalformedURLException; import java.net.URI; import java.net.URISyntaxException; import java.net.URL; import java.util.Iterator; import java.util.regex.Pattern; public class UrlUtils { public static final int MAX_URL_LENGHT = 255; public static final int MIN_URL_LENGHT = 20; /** * 匹配简单的url */ private static Pattern urlPattern = Pattern.compile("^(https?|ftp)://([a-zA-Z0-9-\\.]+)(/?.*)"); private static Splitter urlSplitter = Splitter.on("/").trimResults().omitEmptyStrings().limit(3); private static Splitter querySplitter = Splitter.on("&"); private static Splitter pathSplitter = Splitter.on("/"); private static CharMatcher hostCharMatcher = CharMatcher.JAVA_LETTER_OR_DIGIT.or(CharMatcher.anyOf(".-")); public static Boolean validateUrl(String url) { try { new URI(url); } catch (URISyntaxException e) { return false; } return true; } public static String normalizeUrl(String url) throws MalformedURLException { NormalizedUrl normalizedUrl = Url.create(url).normalize(); return normalizedUrl.getFullUrl(); } private static boolean validateHost(String host) { boolean status = hostCharMatcher.matchesAllOf(host); if (status) { if (host.startsWith("-") || host.endsWith("-") || host.contains("--")) { return false; } if (host.startsWith(".") || host.contains("..")) { return false; } if (host.contains(".-") || host.contains("-.")) { return false; } if (host.endsWith(".")) { host = host.substring(0, host.length() - 1); } return host.contains(".") ? true : false; } return false; } public static String encodeUrl(String url) throws MalformedURLException { URL u = new URL(url); String path = u.getPath(); String query = u.getQuery(); String fragment = u.getRef(); StringBuilder sb = new StringBuilder(); sb.append(u.getProtocol()); sb.append("://"); sb.append(u.getHost()); if (!path.isEmpty()) { path = encodePath(path); sb.append(path); } if (query != null && !query.isEmpty()) { query = encodeQuery(query); sb.append("?"); sb.append(query); } if (fragment != null && !fragment.isEmpty()) { fragment = encodeFragment(fragment); sb.append("#"); sb.append(fragment); } return sb.toString(); } public static String encodePath(String path) { if (path.isEmpty() || path.equals("/")) { return path; } StringBuilder sb = new StringBuilder(); Escaper escaper = UrlEscapers.urlPathSegmentEscaper(); Iterable<String> iterable = pathSplitter.split(path); Iterator<String> iterator = iterable.iterator(); while (iterator.hasNext()) { String part = iterator.next(); if (part.isEmpty()) { sb.append("/"); continue; } part = escaper.escape(part); sb.append(part); if (iterator.hasNext()) { sb.append("/"); } } return sb.toString(); } public static String encodeQuery(String query) { Escaper escaper = UrlEscapers.urlFormParameterEscaper(); StringBuilder sb = new StringBuilder(); Iterable<String> keyValueIterable = querySplitter.split(query); Iterator<String> iterator = keyValueIterable.iterator(); while(iterator.hasNext()) { String keyValue = iterator.next(); if (keyValue.isEmpty()) { if (iterator.hasNext()) { sb.append("&"); } continue; } if (keyValue.equals("=")) { sb.append(keyValue); if (iterator.hasNext()) { sb.append("&"); } continue; } int index = keyValue.indexOf('='); if (index == -1) { keyValue = escaper.escape(keyValue); sb.append(keyValue); if (iterator.hasNext()) { sb.append("&"); } continue; } String key = keyValue.substring(0, index); if (index == 0) { key = ""; } String value = ""; if (index + 1 < keyValue.length()) { value = keyValue.substring(index + 1, keyValue.length()); } if (!key.isEmpty()) { key = escaper.escape(key); sb.append(key); sb.append("="); } if (!value.isEmpty()) { value = escaper.escape(value); sb.append(value); if (iterator.hasNext()) { sb.append("&"); } } } return sb.toString(); } public static String encodeFragment(String fragment) { return UrlEscapers.urlFragmentEscaper().escape(fragment); } }