2015-07-22 1 views
2

В Java Play (2.3.9) приложение пытается получить абсолютно правильный URL:Java Play WS.get неправильно обрабатывает URL-адрес?

WS.url("http://foo.dfg?q=" + URLEncoder.encode("text with = sign", "utf-8")); 

получить это: java.lang.RuntimeException: java.net.MalformedURLException: параметр QueryString не должно быть больше, чем 2 = в части

рытье кода показал, что есть код глубоко внутри NingWSRequestHolder:

if (reference.getQuery() != null) { 
    this.setQueryString(reference.getQuery()); //getQuery returns already decoded query 
} 

public WSRequestHolder setQueryString(String query) { 
    String[] params = query.split("&"); 
    for (String param : params) { 
     String[] keyValue = param.split("="); //param == "q=text with = sign" here 
     if (keyValue.length > 2) { 
      throw new RuntimeException(new MalformedURLException("QueryString parameter should not have more than 2 = per part")); 
     } else if (keyValue.length >= 2) { 
      this.setQueryParameter(keyValue[0], keyValue[1]); 
     } else if (keyValue.length == 1 && param.charAt(0) != '=') { 
      this.setQueryParameter(keyValue[0], null); 
     } else { 
      throw new RuntimeException(new MalformedURLException("QueryString part should not start with an = and not be empty")); 
     } 
    } 
    return this; 
} 

не должны выстраиваться

String[] keyValue = param.split("="); 

чтения:

String[] keyValue = param.split("=", 2); 

Am я что-то отсутствует или это ошибка?

+0

Мне действительно нужно это, пары кодирования нескольких ключевых значений по одному параметру, чтобы обойти 22 параметра из Playframework (Scala Tuple22) – raoulsson

ответ

2

Edit:

Я знаю двух вариантов, как построить правильный URL:

WS.url("http://foo.dfg").setQueryString(yourQueryString); 

и

WS.url("http://foo.dfg"). 
    setQueryParameter(param1, value1). 
    setQueryParameter(param2, value2); 

ли вы получите тот же результат/исключение с обоими вызовы?

Кроме того, имейте в виду записку here:

также могут быть использованы классы URLEncoder и раскодирования URL-адресов, но только для HTML формы кодирования [...]


Ваш строка запроса q=a=b=c=d - это уже имеет более двух =.

Строка запроса, например page=2, вернет массив длиной 2 и, следовательно, будет отмечен как правильно.

Как видно из here, значение по умолчанию limit равно нулю. Zero означает, что шаблон будет применяться столько раз, сколько возможно. Вот почему вы получаете более двух разделенных частей.

Правильный способ обеспечить строку запроса выглядит следующим образом:

param1=value1&param2=value2&param3=value3, и я считаю, что это, как вы должны переформатировать строку. Обратите внимание, что в этом случае у вас есть несколько частей, но каждый из них состоит только из одного ключа и значения (таким образом, только один = между ними)

+1

Это не то, что мне нужно. Мне нужно передать строку, которая потенциально может содержать знак равенства. Прежде чем я закодирую этот текст с помощью URLEncoder.encode. Таким образом, URL-адрес выглядит как «http: // domain/path? Q = text_with_% 3D_sign», который совершенно легален.Как только он добирается до setQueryString, этот параметр уже сбежал: q = text_with _ = _ sign ant и приводит к RTE –

+0

Я обновил свой ответ с дополнительной информацией. Возможно, это даст вам несколько советов ... – Anton

+0

Thanx, Anton, похоже, что параметры параметров запроса отдельно от url действительно решают проблему, хотя это несколько запутывает. Если метод «get» принимает url как строку, почему абсолютно правильный url приводит к RTE? –