uricomponent.java
来自「resetful样式的ws样例,一种面向资源的webservices服务」· Java 代码 · 共 482 行 · 第 1/2 页
JAVA
482 行
tables[Type.PATH.ordinal()] = creatingEncodingTable(l); l.add("?"); tables[Type.QUERY.ordinal()] = creatingEncodingTable(l); tables[Type.FRAGMENT.ordinal()] = tables[Type.QUERY.ordinal()]; return tables; } private static boolean[] creatingEncodingTable(List<String> allowed) { boolean[] table = new boolean[0x80]; for (String range : allowed) { if (range.length() == 1) table[range.charAt(0)] = true; else if (range.length() == 3 && range.charAt(1) == '-') for (int i = range.charAt(0); i <= range.charAt(2); i++) table[i] = true; } return table; } private static final Charset UTF_8_CHARSET = Charset.forName("UTF-8"); /** * Decodes characters of a string that are percent-encoded octets using * UTF-8 decoding (if needed). * <p> * It is assumed that the string is valid according to an (unspecified) URI * component type. If a sequence of contiguous percent-encoded octets is * not a valid UTF-8 character then the octets are replaced with '\uFFFD'. * <p> * If the URI component is of type HOST then any "%" found between "[]" is * left alone. It is an IPv6 literal with a scope_id. * <p> * @param s the string to be decoded. * @param t the URI component type, may be null. * @return the decoded string. * @throws IllegalArgumentException if a malformed percent-encoded octet is * detected */ public static String decode(String s, Type t) { if (s == null) throw new IllegalArgumentException(); final int n = s.length(); if (n == 0) return s; // If there are no percent-escaped octets if (s.indexOf('%') < 0) return s; // Malformed percent-escaped octet at the end if (n < 2) // TODO localize throw new IllegalArgumentException("Malformed percent-encoded octet at index 1"); // Malformed percent-escaped octet at the end if (s.charAt(n - 2) == '%') // TODO localize throw new IllegalArgumentException("Malformed percent-encoded octet at index " + (n - 2)); return (t != Type.HOST) ? decode(s, n) : decodeHost(s, n); } /** * Decode the query component of a URI. * * @param u the URI. * @param decode true of the query parameters of the query component * should be in decoded form. * @return the multivalued map of query parameters. */ public static MultivaluedMap<String, String> decodeQuery(URI u, boolean decode) { return decodeQuery(u.getRawQuery(), decode); } /** * Decode the query component of a URI. * <p> * TODO the implementation is not very efficient. * * @param q the query component in encoded form. * @param decode true of the query parameters of the query component * should be in decoded form. * @return the multivalued map of query parameters. */ public static MultivaluedMap<String, String> decodeQuery(String q, boolean decode) { MultivaluedMap<String, String> queryParameters = new MultivaluedMapImpl(); if (q == null || q.length() == 0) return queryParameters; for (String s : q.split("&")) { if (s.length() == 0) continue; String[] keyVal = s.split("="); try { String key = (decode) ? URLDecoder.decode(keyVal[0], "UTF-8") : keyVal[0]; if (key.length() == 0) continue; // Query parameter may not have a value, if so default to ""; String val = (keyVal.length == 2) ? (decode) ? URLDecoder.decode(keyVal[1], "UTF-8") : keyVal[1] : ""; queryParameters.add(key, val); } catch (UnsupportedEncodingException ex) { // This should never occur throw new IllegalArgumentException(ex); } } return queryParameters; } private static String decode(String s, int n) { final StringBuilder sb = new StringBuilder(n); ByteBuffer bb = ByteBuffer.allocate(1); for (int i = 0; i < n;) { final char c = s.charAt(i++); if (c != '%') { sb.append(c); } else { bb = decodePercentEncodedOctets(s, i, bb); i = decodeOctets(i, bb, sb); } } return sb.toString(); } private static String decodeHost(String s, int n) { final StringBuilder sb = new StringBuilder(n); ByteBuffer bb = ByteBuffer.allocate(1); boolean betweenBrackets = false; for (int i = 0; i < n;) { final char c = s.charAt(i++); if (c == '[') { betweenBrackets = true; } else if (betweenBrackets && c == ']') { betweenBrackets = false; } if (c != '%' || betweenBrackets) { sb.append(c); } else { bb = decodePercentEncodedOctets(s, i, bb); i = decodeOctets(i, bb, sb); } } return sb.toString(); } /** * Decode a contigious sequence of percent encoded octets. * <p> * Assumes the index, i, starts that the first hex digit of the first * percent-encoded octet. */ private static ByteBuffer decodePercentEncodedOctets(String s, int i, ByteBuffer bb) { bb.clear(); while (true) { // Decode the hex digits bb.put((byte) (decodeHex(s, i++) << 4 | decodeHex(s, i++))); // Finish if at the end of the string if (i == s.length()) break; // Finish if no more percent-encoded octets follow if (s.charAt(i++) != '%') break; // Check if the byte buffer needs to be increased in size if (bb.position() == bb.capacity()) { bb.flip(); // Create a new byte buffer with the maximum number of possible // octets, hence resize should only occur once ByteBuffer bb_new = ByteBuffer.allocate(s.length() / 3); bb_new.put(bb); bb = bb_new; } } bb.flip(); return bb; } /** * Decodes octets to characters using the UTF-8 decoding and appends * the characters to a StringBuffer. * @return the index to the next unchecked character in the string to decode */ private static int decodeOctets(int i, ByteBuffer bb, StringBuilder sb) { // If there is only one octet and is an ASCII character if (bb.limit() == 1 && (bb.get(0) & 0xFF) < 0x80) { // Octet can be appended directly sb.append((char)bb.get(0)); return i + 2; } else { // CharBuffer cb = UTF_8_CHARSET.decode(bb); sb.append(cb.toString()); return i + bb.limit() * 3 - 1; } } private static int decodeHex(String s, int i) { final int v = decodeHex(s.charAt(i)); if (v == -1) // TODO localize throw new IllegalArgumentException("Malformed percent-encoded octet at index " + i + ", invalid hexadecimal digit '" + s.charAt(i) + "'"); return v; } private static final int[] HEX_TABLE = createHexTable(); private static int[] createHexTable() { int[] table = new int[0x80]; Arrays.fill(table, -1); for (char c = '0'; c <= '9'; c++) table[c] = c - '0'; for (char c = 'A'; c <= 'F'; c++) table[c] = c - 'A' + 10; for (char c = 'a'; c <= 'f'; c++) table[c] = c - 'a' + 10; return table; } private static int decodeHex(char c) { return (c < 128) ? HEX_TABLE[c] : -1; } }
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?