javaurldecode

how to decode x-www-form-urlencoded form data in java which has an unescaped % as data


I have a situation where I receive x-www-form-urlencoded form data and I need to decode it.

how to decode x-www-form-urlencoded form data in java which has an unescaped % as data. e.g. "APL%205%%20off" which actually shall be decoded as "APL 5% off" However, I tried a few code snippets in java as well as a few online decoders and all throw an exception or say invalid.

I need the understanding on how this can be achieved? If anyone can share the knowledge would be greatly appreciated.


Solution

  • '%' in urlEncode encoding is '%25', so decoding 'APL%205%%20off' will cause issues. Normally, it should be encoded as 'APL%205%25%20off' to decode and get the expected result "APL 5% off". If you must decode this string, you can try the following code:

    public static String decodeFormData(String formData) {
            try {
                return URLDecoder.decode(formData, StandardCharsets.UTF_8.toString());
            } catch (Exception e) {
                // Manually handle decoding for malformed input
                StringBuilder decoded = new StringBuilder();
                for (int i = 0; i < formData.length(); i++) {
                    char c = formData.charAt(i);
                    if (c == '%' && i + 2 < formData.length()) {
                        String hex = formData.substring(i + 1, i + 3);
                        try {
                            int charCode = Integer.parseInt(hex, 16);
                            decoded.append((char) charCode);
                            i += 2;
                        } catch (NumberFormatException ignored) {
                            decoded.append(c);
                        }
                    } else {
                        decoded.append(c);
                    }
                }
                return decoded.toString();
            }
        }
    
        public static void main(String[] args) {
            String formData = "APL%205%%20off";
            String decoded = decodeFormData(formData);
            System.out.println(decoded); // Output: APL 5% off
        }
    

    or try this

    private static String decodeUrl(String url) {
            String decodeUrl = "";
            try {
                String transformUrl = url.replaceAll("%(?![0-9a-fA-F]{2})", "%25");
                decodeUrl = URLDecoder.decode(transformUrl, "UTF-8");
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                return decodeUrl;
            }
        }