【问题标题】:HttpServletRequest - Get query string parameters, no form dataHttpServletRequest - 获取查询字符串参数,无表单数据
【发布时间】:2011-10-14 09:38:07
【问题描述】:

HttpServletRequest中,getParameterMap返回一个所有查询字符串参数和post数据参数的Map。

有没有办法获取仅查询字符串参数的映射?我试图避免使用 getQueryString 并解析出值。

【问题讨论】:

  • 你可以同时拥有...你可以在 POST 请求中拥有查询字符串参数。在这种情况下,它们都由“getParameterMap”返回
  • 哦,好的。为什么一个人都需要,只是好奇?
  • 因为在结果页面上,我希望查询字符串出现在 url / 查询字符串中。我们有一个跟踪系统,可以在查询字符串中查找特定参数。
  • req.getParameterMap().containsKey("username");

标签: java servlets query-string


【解决方案1】:

与 cularis 所说的相反,参数映射中可能两者兼有。

我看到的最好方法是代理 parameterMap 并为每个参数检索检查 queryString 是否包含“&?=".

请注意,正如 Qerub 指出的那样,在进行此检查之前,参数名称需要进行 URL 编码。

这样可以节省您的解析,并且仍然只为您提供 URL 参数。

【讨论】:

  • 请注意,parameterName 需要进行 URL 编码才能进行此检查。
  • 查询字符串从不包含?。这是 URI 和查询字符串之间的分隔符。
  • 嗨@DoubleMalt,我有同样的要求,但无法获得您提供的解决方案。能否提供示例代码?
  • @VishalZanzrukia:什么代码不起作用?
  • 我喜欢这个想法,但查询字符串中并不总是有“=”字符。如果参数值为空,则查询字符串中只有 。我个人认为用“&”和“=”分割会是一个更好的解决方案。
【解决方案2】:

恐怕没有办法将查询字符串参数与post参数分开解析。顺便说一句,缺少此类 API 可能意味着您可能应该检查您的设计。为什么在发送 POST 时使用查询字符串?如果您真的想将更多数据发送到 URL,请使用类似 REST 的约定,例如而不是发送

http://mycompany.com/myapp/myservlet?first=11&second=22

说:

http://mycompany.com/myapp/myservlet/11/22

【讨论】:

  • 我在 POST 中使用查询字符串参数,因为我想维护通过 POST 传递给原始表单的所有查询字符串。这主要用于跟踪目的......我不确定在这种情况下类似 REST 的约定是否有效,因为我很确定跟踪库会在查询字符串中查找特定参数。
  • 有什么特别的理由建议您对查询字符串参数使用类似 REST 的约定?不确定我是否了解优势是什么?
  • "顺便说一句,缺少此类 API 可能意味着您可能应该检查您的设计。"在这种情况下,这意味着 Oracle 应该检查他们的设计 :)
【解决方案3】:

servlet API 缺少这个特性,因为它是在许多人认为查询字符串和消息体只是发送参数的两种不同方式的时候创建的,没有意识到参数的用途根本不同。

查询字符串参数 ?foo=bar 是 URL 的一部分,因为它们涉及识别资源(可能是许多资源的集合),例如“所有 42 岁的人”:

GET /persons?age=42

POST 或 PUT 中的消息体参数用于表达对目标资源的修改。 Fx 为“头发”属性设置值:

PUT /persons?age=42

头发=灰色

所以同时使用查询参数和正文参数绝对是 RESTful,分开使用,以便您可以将它们用于不同的目的。 Java servlet API 中肯定缺少该功能。

【讨论】:

    【解决方案4】:

    你可以使用request.getQueryString(),如果查询字符串是这样的

    username=james&password=pwd
    

    要获取名称,您可以这样做

    request.getParameter("username"); 
    

    【讨论】:

    • 这是用于非 Java 服务器页面的。
    • 第二个会破坏请求流,我认为问题是如何获取用户名并保留输入流以供以后处理
    • @PavelNiedoba 你可以扩展请求流成为被宠坏的评论吗?这是为什么呢?
    【解决方案5】:

    正如其他答案所述,无法使用 servlet api 获取查询字符串参数。

    所以,我认为获取查询参数的最佳方法是自己解析查询字符串。 (迭代参数并检查查询字符串是否包含参数更复杂)

    我写了下面的代码来获取查询字符串参数。使用支持 CSV 分隔查询参数值的 apache StringUtils 和 ArrayUtils。

    示例:username=james&username=smith&password=pwd1,pwd2 将返回

    password : [pwd1, pwd2](长度 = 2)

    username : [james, smith](长度 = 2)

    public static Map<String, String[]> getQueryParameters(HttpServletRequest request) throws UnsupportedEncodingException {
        Map<String, String[]> queryParameters = new HashMap<>();
        String queryString = request.getQueryString();
        if (StringUtils.isNotEmpty(queryString)) {
            queryString = URLDecoder.decode(queryString, StandardCharsets.UTF_8.toString());
            String[] parameters = queryString.split("&");
            for (String parameter : parameters) {
                String[] keyValuePair = parameter.split("=");
                String[] values = queryParameters.get(keyValuePair[0]);
                //length is one if no value is available.
                values = keyValuePair.length == 1 ? ArrayUtils.add(values, "") :
                        ArrayUtils.addAll(values, keyValuePair[1].split(",")); //handles CSV separated query param values.
                queryParameters.put(keyValuePair[0], values);
            }
        }
        return queryParameters;
    }
    

    【讨论】:

    • 我认为这比接受的答案要好得多,不知道为什么要避免解析查询字符串,因为创建代理不是更好的解决方案
    • 我只是想知道,如果任何查询参数的值中包含&amp; 字符,它是否会给你正确的结果
    • @amdg - 该字符将被 URL 编码,因此该代码很好。如果它没有被编码,字符串将是不可解析的。
    • 考虑同时使用URLDecoder.decode(keyValuePair[0])(或[1]):docs.oracle.com/javase/6/docs/api/java/net/URLDecoder.html
    • 此处不考虑使用 csv 分隔值的查询参数。例如:username=james&amp;username=smith&amp;password=pwd1,pwd2 将有一个映射,其中包含 2 个用户名值(正确)但只有 1 个密码值(不正确)
    【解决方案6】:

    Java 8

    return Collections.list(httpServletRequest.getParameterNames())
                      .stream()
                      .collect(Collectors.toMap(parameterName -> parameterName, httpServletRequest::getParameterValues));
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-12-31
      • 1970-01-01
      • 1970-01-01
      • 2017-12-09
      • 2021-12-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多