-->

Play framework WS url spaces

2019-07-03 23:12发布

问题:

I have a problem calling WS.url() in play framework 2.3.3 with url containing spaces. All other characters all url encoded automatically but not spaces. When i try to change all spaces to "%20", WS convert it to "%2520" because of "%" character. With spaces i've got java.net.URISyntaxException: Illegal character in query. How can i handle this ?

part of the URL's query String:

 &input=/mnt/mp3/music/folder/01 - 23.mp3

The code looks like this:

Promise<JsonNode> jsonPromise = WS.url(url).setAuth("", "cube", WSAuthScheme.BASIC).get().map(
                new Function<WSResponse, JsonNode>() {
                    public JsonNode apply(WSResponse response) {
                        System.out.println(response.getBody());
                        JsonNode json = response.asJson();
                        return json;
                    }
                }
                );

回答1:

You should "build" your URL based on the way java.net.URL(which Play! uses for it's WS) does it. WS.url() follows the same logic.

The use of URLEncoder/Decoder is recommended only for form data. From JavaDoc:

"Note, the java.net.URI class does perform escaping of its component fields in certain circumstances. The recommended way to manage the encoding and decoding of URLs is to use java.net.URI, and to convert
between these two classes using toURI() and URI.toURL(). The URLEncoder and URLDecoder classes can also be used, but only for HTML form encoding, which is not the same as the encoding scheme defined in RFC2396."

So, the solution is to use THIS:

WS.url(baseURL).setQueryString(yourQueryString);

Where:

  1. baseURL is your scheme + host + path etc.
  2. yourQueryString is... well, your query String, but WITHOUT the ?: input=/mnt/mp3/music/folder/01 - 23.mp3

Or, if you want to use a more flexible, programmatic approach, THIS:

WS.url(baseURL).setQueryParameter(param, value);

Where:

  1. param is the parameter's name in the query String
  2. value is the value of the parameter

If you want multiple parameters with values in your query you need to chain them by adding another .setQueryParameter(...). This implies that this approach is not very accomodating for complex, multi-parameter query Strings.


Cheers!



回答2:

If you check the console you will find that the exception is : java.net.URISyntaxException: Illegal character in path at index ...

That's because play Java api uses java.net.URL (as you can see here in line 47).

You can use java.net.URLEncoder to encode your URL

WS.url("http://" + java.net.URLEncoder.encode("google.com/test me", "UTF-8"))

UPDATE

If you want an RFC 2396 compliant method you can do this :

java.net.URI u = new java.net.URI(null, null, "http://google.com/test me",null);
System.out.println("encoded url " + u.toASCIIString());