/******************************************************************************
* CREATETIME : 2016年7月24日 下午3:31:25
******************************************************************************/
package ins.platform.utils;

import java.net.URI;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.charset.Charset;
import java.util.BitSet;
import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;

/**
 * URL编码解码工具类
 * @author ★LiuPing
 * @CreateTime 2016年7月24日
 */
public class URLEncodedUtils {

private static final Charset DEFAULT_CHARSET = Charset.forName("UTF-8");
    private static final String PARAMETER_SEPARATOR = "&";
    private static final String NAME_VALUE_SEPARATOR = "=";

/**
     * Returns a String that is suitable for use as an <code>application/x-www-form-urlencoded</code> list of parameters in an HTTP PUT or HTTP POST.
     * @param parameters The parameters to include.
     * @param encoding UTF-8.
     */
    public static String format(final Map<String,String> paramMap) {
        return format(paramMap,DEFAULT_CHARSET);
    }

/**
     * Returns a String that is suitable for use as an <code>application/x-www-form-urlencoded</code> list of parameters in an HTTP PUT or HTTP POST.
     * @param parameters The parameters to include.
     * @param encoding The encoding to use.
     */
    public static String format(final Map<String,String> paramMap,final Charset charset) {
        final StringBuilder result = new StringBuilder();
        for(final String name:paramMap.keySet()){
            final String encodedName = encodeFormFields(name,charset);
            final String encodedValue = encodeFormFields(paramMap.get(name),charset);
            if(result.length()>0){
                result.append(PARAMETER_SEPARATOR);
            }
            result.append(encodedName);
            if(encodedValue!=null){
                result.append(NAME_VALUE_SEPARATOR);
                result.append(encodedValue);
            }
        }
        return result.toString();
    }

/**
     * Returns a list of {@link NameValuePair NameValuePairs} as built from the URI's query portion. For example, a URI of http://example.org/path/to/file?a=1&b=2&c=3 would return a list of three
     * NameValuePairs, one for a=1, one for b=2, and one for c=3.
     * <p>
     * This is typically useful while parsing an HTTP PUT.
     * @param uri uri to parse
     * @param encoding encoding to use while parsing the query
     */
    public static Map<String,String> parse(final URI uri,final Charset charset) {
        final String query = uri.getRawQuery();
        Map<String,String> result = new HashMap<String,String>();
        if(query!=null&&query.length()>0){
            Scanner scanner = new Scanner(query);
            parse(result,scanner,charset);
        }
        return result;
    }

/**
     * Decode/unescape www-url-form-encoded content.
     * @param content the content to decode, will decode '+' as space
     * @param charset the charset to use
     * @return
     */
    public static String decodeField(final String content) {
        if(content==null){
            return null;
        }
        return urldecode(content,DEFAULT_CHARSET,true);
    }

public static String encodeField(final String content) {
        if(content==null){
            return null;
        }
        return urlencode(content,DEFAULT_CHARSET,URLENCODER,true);
    }

/**
     * Unreserved characters, i.e. alphanumeric, plus: {@code _ - ! . ~ ' ( ) *}
     * <p>
     * This list is the same as the {@code unreserved} list in <a href="http://www.ietf.org/rfc/rfc2396.txt">RFC 2396</a>
     */
    private static final BitSet UNRESERVED = new BitSet(256);

/**
     * Safe characters for x-www-form-urlencoded data, as per java.net.URLEncoder and browser behaviour, i.e. alphanumeric plus {@code "-", "_", ".", "*"}
     */
    private static final BitSet URLENCODER = new BitSet(256);

static{
        // unreserved chars
        // alpha characters
        for(int i = 'a'; i<='z'; i++ ){
            UNRESERVED.set(i);
        }
        for(int i = 'A'; i<='Z'; i++ ){
            UNRESERVED.set(i);
        }
        // numeric characters
        for(int i = '0'; i<='9'; i++ ){
            UNRESERVED.set(i);
        }
        UNRESERVED.set('_'); // these are the charactes of the "mark" list
        UNRESERVED.set('-');
        UNRESERVED.set('.');
        UNRESERVED.set('*');
        URLENCODER.or(UNRESERVED); // skip remaining unreserved characters
        UNRESERVED.set('!');
        UNRESERVED.set('~');
        UNRESERVED.set('\'');
        UNRESERVED.set('(');
        UNRESERVED.set(')');

}

private static final int RADIX = 16;

/**
     * Adds all parameters within the Scanner to the list of <code>parameters</code>, as encoded by <code>encoding</code>. For example, a scanner containing the string <code>a=1&b=2&c=3</code> would
     * add the {@link NameValuePair NameValuePairs} a=1, b=2, and c=3 to the list of parameters.
     * @param parameters List to add parameters to.
     * @param scanner Input that contains the parameters to parse.
     * @param charset Encoding to use when decoding the parameters.
     */
    private static void parse(final Map<String,String> parameters,final Scanner scanner,final Charset charset) {
        scanner.useDelimiter(PARAMETER_SEPARATOR);
        while(scanner.hasNext()){
            String name = null;
            String value = null;
            String token = scanner.next();
            int i = token.indexOf(NAME_VALUE_SEPARATOR);
            if(i!= -1){
                name = decodeFormFields(token.substring(0,i).trim(),charset);
                value = decodeFormFields(token.substring(i+1).trim(),charset);
            }else{
                name = decodeFormFields(token.trim(),charset);
            }
            parameters.put(name,value);
        }
    }

/**
     * Emcode/escape a portion of a URL, to use with the query part ensure {@code plusAsBlank} is true.
     * @param content the portion to decode
     * @param charset the charset to use
     * @param blankAsPlus if {@code true}, then convert space to '+' (e.g. for www-url-form-encoded content), otherwise leave as is.
     * @return
     */
    private static String urlencode(final String content,final Charset charset,final BitSet safechars,final boolean blankAsPlus) {
        if(content==null){
            return null;
        }
        StringBuilder buf = new StringBuilder();
        ByteBuffer bb = charset.encode(content);
        while(bb.hasRemaining()){
            int b = bb.get()&0xff;
            if(safechars.get(b)){
                buf.append((char)b);
            }else if(blankAsPlus&&b==' '){
                buf.append('+');
            }else{
                buf.append("%");
                char hex1 = Character.toUpperCase(Character.forDigit(( b>>4 )&0xF,RADIX));
                char hex2 = Character.toUpperCase(Character.forDigit(b&0xF,RADIX));
                buf.append(hex1);
                buf.append(hex2);
            }
        }
        return buf.toString();
    }

/**
     * Decode/unescape a portion of a URL, to use with the query part ensure {@code plusAsBlank} is true.
     * @param content the portion to decode
     * @param charset the charset to use
     * @param plusAsBlank if {@code true}, then convert '+' to space (e.g. for www-url-form-encoded content), otherwise leave as is.
     * @return
     */
    private static String urldecode(final String content,final Charset charset,final boolean plusAsBlank) {
        if(content==null){
            return null;
        }
        ByteBuffer bb = ByteBuffer.allocate(content.length());
        CharBuffer cb = CharBuffer.wrap(content);
        while(cb.hasRemaining()){
            char c = cb.get();
            if(c=='%'&&cb.remaining()>=2){
                char uc = cb.get();
                char lc = cb.get();
                int u = Character.digit(uc,16);
                int l = Character.digit(lc,16);
                if(u!= -1&&l!= -1){
                    bb.put((byte)( ( u<<4 )+l ));
                }else{
                    bb.put((byte)'%');
                    bb.put((byte)uc);
                    bb.put((byte)lc);
                }
            }else if(plusAsBlank&&c=='+'){
                bb.put((byte)' ');
            }else{
                bb.put((byte)c);
            }
        }
        bb.flip();
        return charset.decode(bb).toString();
    }

/**
     * Decode/unescape www-url-form-encoded content.
     * @param content the content to decode, will decode '+' as space
     * @param charset the charset to use
     * @return
     */
    private static String decodeFormFields(final String content,final Charset charset) {
        if(content==null){
            return null;
        }
        return urldecode(content,charset!=null ? charset : DEFAULT_CHARSET,true);
    }

/**
     * Encode/escape www-url-form-encoded content.
     * <p>
     * Uses the {@link #URLENCODER} set of characters, rather than the {@link #UNRSERVED} set; this is for compatibilty with previous releases, URLEncoder.encode() and most browsers.
     * @param content the content to encode, will convert space to '+'
     * @param charset the charset to use
     * @return
     */
    private static String encodeFormFields(final String content,final Charset charset) {
        if(content==null){
            return null;
        }
        return urlencode(content,charset!=null ? charset : DEFAULT_CHARSET,URLENCODER,true);
    }

}

URL编码解码工具类相关推荐

  1. 条形码和二维码编码解码工具类源码

    有一个好的工具,会让你的开发事半功倍.再将讲这个工具类之前,我先给小白补充一点条形码和二维码(以下基础知识选自,我本科阶段的一本教材:<物联网导论>(刘云浩 编著).有对物联网感兴趣的,可 ...

  2. Http URL中文编码解码工具类

    从网上获取的 中文转码工具 package com.test;import java.io.UnsupportedEncodingException; import java.net.URLEncod ...

  3. Java(35):Java Base64编码和解码工具类

    Java Base64编码和解码工具类 Base64Util工具类: package com.ciphergateway.utils; import java.io.UnsupportedEncodi ...

  4. 分享万能java字符串编码转换工具类

    代码下载地址:http://www.zuidaima.com/share/1795356301560832.htm 原文:分享万能java字符串编码转换工具类 package com.zuidaima ...

  5. java url加密解密,java URL 编码解码,该如何解决

    java URL 编码解码 我写了两个接口 一个是对字符串加密 的,一个是解密的  .加密的可以通过调用接口生成加密字符串如下: Oc0PEwKrLzHqT25hYLhWP5wlk5HROPJoWC3 ...

  6. 小工具发布(2008-01-25更新,HTML、URL编解码工具)

    (2008-01-25)HTML.URL编解码工具 [介绍文章][访问该工具]

  7. 编码解码--url编码解码

    url编码解码,又叫百分号编码,是统一资源定位(URL)编码方式.URL地址(常说网址)规定了常用地数字,字母可以直接使用,另外一批作为特殊用户字符也可以直接用(/,:@等),剩下的其它所有字符必须通 ...

  8. URL编码/解码详解

    URL编码/解码详解 当 URL 路径或者查询参数中,带有中文或者特殊字符的时候,就需要对 URL 进行编码(采用十六进制编码格式).URL 编码的原则是使用安全字符去表示那些不安全的字符. 安全字符 ...

  9. URL编码解码以及常见压缩算法和加密

    1) 将客户端在进行网址请求的时候,如果网址中使用了非ASCII码形式的内.比如百度可以使用中文搜索但是sougou搜索那么就需要进行编码 2)URLEncoding:在编码的时候保留所有的英文字母. ...

最新文章

  1. python能进行切片操作的数据类型可以是_Python新手学习基础之数据类型——字符串的切片截取...
  2. 初次就这么给了你(Django-rest-framework)
  3. 想玩转工业界机器学习?先学Spark吧
  4. python包导入详细教程脚本之家_python包导入详细教程脚本之家_Python使用import导入本地脚本及导入模块的技巧总结......
  5. 升级EXCHANGE2010到2013(C)
  6. 如何设置电脑自动锁屏_MIUI第415期:新增智能显示锁屏通知、状态栏数字电量外显...
  7. win10 安装SQL Server 2005--以及---安装SQL2005之后卸载,重新安装时提示“安装默认报表服务器的必备组件检查失败”的方法
  8. [精华]世界500强面试题----[完整版]
  9. 非平稳时间序列突变检测 -- Bernaola Galvan分割算法
  10. magisk小问题解答
  11. Wind的实时行情API使用
  12. Kubernetes的Serializer解析
  13. Robo 3T使用教程--MongoDB篇(极简)
  14. python输出最大的素数_Python:求X的最大素数
  15. python非参数检验
  16. 车载电子瞬态浪涌保护用瞬态抑制TVS二极管,如何正确选型?
  17. BDB(C) Getting Started - Introduction to Berkeley DB
  18. 在线教育网站的一些瞎折腾……
  19. 虹科技术 | 终端入侵防御 | 在重大攻击中发现新的Babuk勒索软件
  20. 【BZOJ3893】【Usaco2014 Dec】Cow Jog 乱搞

热门文章

  1. php开发c盘多大,win10占用c盘多大空间
  2. 计算机管理声音视屏不见,为什么视频没声音_电脑看视频没声音怎么恢复-win7之家...
  3. 网络调试助手 TCPsever无法连接
  4. JavaScript基础(详细总结)
  5. 当Ubuntu开机出现“piix4_smbus:host smbus controller not enab”时的解决方法
  6. 选择题标准化考试系统c语言,C语言设计:单项选择题标准化考试系统
  7. 服务器管理口虚拟kvm切换服务器,1个本地/1个远程用户控管 8端口KVM over IP切换器远程电脑管理方案兼具虚拟媒体功能 (1920 x 1200)...
  8. Channel的定义、写入、读取、关闭与遍历
  9. 人一旦开窍后,会产生哪些改变?
  10. 【算法】P问题 NP问题 NPC问题 NPH问题的定义与理解