【问题标题】:Java Play WS.get does not process url properly?Java Play WS.get 不能正确处理 url?
【发布时间】:2015-07-22 09:14:51
【问题描述】:

在 java Play (2.3.9) 应用程序中尝试获取绝对正确的 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);

是我遗漏了什么还是一个错误?

【问题讨论】:

  • 我实际上需要这个,在一个参数上编码多个键值对,以规避 Playframework (Scala Tuple22) 的 22 参数限制

标签: java playframework-2.3


【解决方案1】:

编辑:

我知道如何构建正确的 URL 有两种选择:

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

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

两次调用是否得到相同的结果/异常?

另外,请记住注释here

也可以使用 URLEncoder 和 URLDecoder 类,但仅用于 HTML 表单编码 [...]


您的查询字符串是q=a=b=c=d - 这已经有两个以上的=

page=2 这样的查询字符串会返回一个长度为2 的数组,因此会被标记为正确

here 可以看出,默认的limit 参数为零。零表示将尽可能多次应用该模式。这就是为什么你会得到两个以上的拆分部分。

提供查询字符串的正确方法如下:

param1=value1&param2=value2&param3=value3 我相信这就是你应该重新格式化你的字符串的方式。请注意,在这种情况下,您有多个部分,但每个部分仅包含一个键和值(因此两者之间只有一个 =

【讨论】:

  • 这不是我需要的。我需要传递一个可能包含等号的字符串。在我使用 URLEncoder.encode 编码此文本之前。所以网址看起来像“domain/path?q=text_with_%3D_sign”,这是完全合法的。一旦它到达 setQueryString 参数已经转义: q=text_with_=_sign ant 它导致 RTE
  • 我用更多信息更新了我的答案。也许这会给你一些提示......
  • Thanx,Anton,看起来像将查询参数与 url 分开设置确实解决了这个问题,尽管它有点令人困惑。如果方法“get”接受 url 作为字符串,为什么绝对正确的 url 会导致 RTE?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-05-08
  • 1970-01-01
相关资源
最近更新 更多