简体   繁体   中英

Java URLDecoder throws exception when used with a string containing a %

I have a problem with the URLDecoder of Java. I am escaping a String in JavaScript, and send it to a java servlet. Then I decode the escaped String with the following line:

URLDecoder.decode(request.getParameter("text"), "UTF-8");

This works fine for every special characters I have tried, the only one making problems is the '%'. Everytime I use this character in the string, I get the following exception:

java.lang.IllegalArgumentException: URLDecoder: Incomplete trailing escape (%) pattern
    java.net.URLDecoder.decode(URLDecoder.java:187)
    at.fhv.students.rotter.ajax.count.CountServlet.doGet(CountServlet.java:31)
    javax.servlet.http.HttpServlet.service(HttpServlet.java:621)
    javax.servlet.http.HttpServlet.service(HttpServlet.java:722)

Is this a known bug? Or is it really my mistake?

It is not a bug. You send a wrong encoded String. The % -sign has to be encoded as %25

If you call request.getParameter(), I think you get a decoded String.

We had a similar issue in our angular application where we were encoding % sign once in client side code. When we received the value in servlet it was already decoded due to request.getParameter() . Since we already had URL decoder in our sever side code, decoding the % sign twice was causing a "URLDecoder: Incomplete trailing escape (%) pattern" exception. We figured out that we we should not encode and decode % as a value at all to get face this issue.

In order to get parameter I have written

String requestURL=request.getQueryString(); 

so that It will give us parameters. From that we can use String.substring() to get prefered parameter in case of fix length or single parameter. Then

String decodeValue = URLDecoder.decode(value,"UTF-8"); 

will get preferred string encoded % sign too.

Even I faced similar issue and it was solved. Following is the example code you can simply run to reproduce and resolve this issue.

public class TestPercentage {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        String transResult = "Se si utilizza DHCP%2C i valori validi sono S%C3%AC o No.%24%23%24%23%24%23%25NICyUSEWINS%25%24%23%24%23%24%23Se si utilizza WINS%2C i valori validi sono S%C3%AC o No.%24%23%24%23%24%23%25NODEFULL%25%24%23%24%23%24%23Nome completo del computer%24%23%24%23%24%23%25NODENAME%25%24%23%24%23%24%23I primi 8 caratteri del nome effettivo del computer%24%23%24%23%24%23%25NWCONTEXT%25%24%23%24%23%24%23Nome contesto NetWare%24%23%24%23%24%23%25NWSERVER%25%";
        String decode = null;
        try {
            decode = URLDecoder.decode(transResult, "UTF-8");
        } catch (UnsupportedEncodingException ue) {
            System.out.println("UnsupportedEncodingException ! = " + ue);
        } catch (IllegalArgumentException ile) {
            System.out.println("IllegalArgumentException ! = " + ile);
            if (transResult.endsWith("%")) {
                transResult = transResult.substring(0, transResult.lastIndexOf("%"));
                System.out.println("transResult2 = " + transResult);
                try {
                decode = URLDecoder.decode(transResult, "UTF-8");
                } catch (UnsupportedEncodingException ue2) {
                    System.out.println("UnsupportedEncodingException 2 = " + ue2);
                } catch (IllegalArgumentException ile2) {
                    System.out.println("IllegalArgumentException ! = " + ile2);
                }
            }
        }
        System.out.println("decode = " + decode);
    }

}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM