Decoding URI query string in Java

后端 未结 5 465
离开以前
离开以前 2020-12-05 09:50

I need to decode a URI that contains a query string; expected input/output behavior is something like the following:

abstract class URIParser
{       
    /*         


        
相关标签:
5条回答
  • 2020-12-05 10:33

    See class URLDecoder

    0 讨论(0)
  • 2020-12-05 10:37

    Use

    URLDecoder.decode(proxyRequestParam.replace("+", "%2B"), "UTF-8")
              .replace("%2B", "+")
    

    to simulate decodeURIComponent. Java's URLDecoder decodes the plus sign to a space, which is not what you want, therefore you need the replace statements.

    Warning: the .replace("%2B", "+") at the end will corrupt your data if the original (pre-x-www-form-urlencoded) contained that string, as @xehpuk pointed out.

    0 讨论(0)
  • 2020-12-05 10:41
    var reqParam =  URLDecoder.decode(reqParam, "UTF-8")
    
    0 讨论(0)
  • 2020-12-05 10:46

    Regarding the issue with the + sign :

    I made a helper class that wraps the URLDecoder function based on the answer of @janb

    import android.net.Uri;
    import android.support.annotation.Nullable;
    import android.text.TextUtils;
    
    import java.io.UnsupportedEncodingException;
    import java.net.URLDecoder;
    import java.text.SimpleDateFormat;
    import java.util.Date;
    import java.util.Locale;
    
    public class DateDecoder {
    
        private static final String KEY_DATE = "datekey";
    
        private static final SimpleDateFormat SIMPLE_DATE_FORMAT =
                new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZZZZZ", Locale.US);
    
    
        public static void main(String[] args) throws UnsupportedEncodingException {
            try {
                Uri uri = Uri.parse("http://asdf.com?something=12345&" +
                        KEY_DATE +"=2016-12-24T12:00:00+01:00");
    
                System.out.println("parsed date: " + DateDecoder.createDate(uri)); // parsed date: Sat Dec 24 12:00:00 GMT+01:00 2016
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    
        @Nullable
        public static Date createDate(@Nullable Uri data) {
            if (data != null) {
                try {
                    String withPlus = decodeButKeepPlus(KEY_DATE, data.getEncodedQuery());
                    if (!TextUtils.isEmpty(withPlus)) {
                        return SIMPLE_DATE_FORMAT.parse(withPlus);
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
            return null;
        }
    
        /**
         * copied from android.net.Uri.java
         */
        @Nullable
        public static String decodeButKeepPlus(String encodedKey, String completeEncodedQuery)
                throws UnsupportedEncodingException {
    
            final int length = completeEncodedQuery.length();
            int start = 0;
            do {
                int nextAmpersand = completeEncodedQuery.indexOf('&', start);
                int end = nextAmpersand != -1 ? nextAmpersand : length;
    
                int separator = completeEncodedQuery.indexOf('=', start);
                if (separator > end || separator == -1) {
                    separator = end;
                }
    
                if (separator - start == encodedKey.length()
                        && completeEncodedQuery.regionMatches(start, encodedKey, 0, encodedKey.length())) {
                    if (separator == end) {
                        return "";
                    } else {
                        String encodedValue = completeEncodedQuery.substring(separator + 1, end);
                        if (!TextUtils.isEmpty(encodedValue)) {
                            return URLDecoder.decode(encodedValue.replace("+", "%2B"), "UTF-8").replace("%2B", "+");
                        }
                    }
                }
    
                // Move start to end of name.
                if (nextAmpersand != -1) {
                    start = nextAmpersand + 1;
                } else {
                    break;
                }
            } while (true);
            return null;
        }
    
    }
    
    0 讨论(0)
  • 2020-12-05 10:48
    new java.net.URI(proxyRequestParam).getPath()
    

    The string encoded by js encodeURIComponent should just be a path, without schema and other things. However it still a valid input for java.net.URI. So java.net.URI will do everything for us and then the path of it is what we want.

    0 讨论(0)
提交回复
热议问题