java - Spring REST Controller 在具有空格或逗号等特殊字符时理解字符串数组

标签 java arrays spring rest spring-mvc

我正在尝试编写一个 Spring REST Controller ,获取一个字符串数组作为 HTTP GET 请求的输入参数。

当在 GET 请求中,在数组的某些字符串中,我使用逗号 ,、空格 或正斜杠 等特殊字符时,就会出现问题>/无论我是否对 URL HTTP GET 请求的查询部分进行 URL 编码

这意味着字符串“1/4 cup ricotta, yogurt”(编辑需要被视为包含在输入的字符串元素中的唯一成分)数组)采用以下格式之一:

http://127.0.0.1:8080/[...]/parseThis?[...]&ingredients=1/4 cup ricotta, yogurt

此格式(请注意空格编码为 + 加号,而不是十六进制代码):

http://127.0.0.1:8080/[...]/parseThis?[...]&ingredients=1%2F4+cup+ricotta%2C+yogurt

或者这种格式(请注意编码为十六进制代码 %20 的空格):

http://127.0.0.1:8080/[...]/parseThis?[...]&ingredients=1%2F4%20cup%20ricotta%2C%20yogurt

未正确渲染。

  • 系统无法将输入字符串识别为数组的单个元素。
  • 在第二种和第三种情况下,系统以逗号分割输入字符串,并返回一个包含 2 个元素而不是 1 个元素的数组。我在这里期待 1 个元素。

Controller 的相关代码是:

@RequestMapping(
        value = "/parseThis",
        params = {
                "language",
                "ingredients"

        }, method = RequestMethod.GET, headers = HttpHeaders.ACCEPT + "=" + MediaType.APPLICATION_JSON_VALUE)
@ResponseBody
public HttpEntity<CustomOutputObject> parseThis(
        @RequestParam String language,
        @RequestParam String[] ingredients){

    try {

        CustomOutputObject responseFullData = parsingService.parseThis(ingredients, language);

        return new ResponseEntity<>(responseFullData, HttpStatus.OK);

    } catch (Exception e) {
        // TODO
    }

}

我需要对此 Spring Controller 执行 HTTP GET 请求,这是一项要求(因此此处不能使用 HTTP POST)。

编辑1:

如果我将 HttpServletRequest request 添加到 Controller 中方法的签名中,那么我将添加一条日志语句,例如 log.debug("The query string is: '"+ request. getQueryString() + "'"); 然后我在日志中看到一行类似 The query string is: '&language=en&ingredients=1%2F4+cup+ricotta%2C+yogurt' (所以仍然是 URL 编码)。

编辑2:

另一方面,如果我将 WebRequest request 添加到方法的签名中,则日志为 log.debug("The query string is: '"+ request.getParameter( "ingredients") + "'"); 然后我在日志中得到一个字符串 The query string is: '1/4 cup ricotta, yogurt' (所以 URL 已解码) .

我使用 Apache Tomcat 作为服务器。

我需要在 Spring/webapp 配置文件中添加/查看任何过滤器或其他内容吗?

编辑3:

主要问题在于逗号的解释:

@ResponseBody
@RequestMapping(value="test", method=RequestMethod.GET)
public String renderTest(@RequestParam("test") String[] test) {
    return test.length + ": " + Arrays.toString(test);
    // /app/test?test=foo,bar => 2: [foo, bar]
    // /app/test?test=foo,bar&test=baz => 2: [foo,bar, baz]
}

这种行为可以预防吗?

最佳答案

请求参数方法参数的路径经过参数值提取,然后参数值转换>。现在发生的事情是:

提取:

参数为extracted as a single String value 。这可能是为了允许简单的属性作为简单的字符串值传递,以便以后进行值转换。

转化:

Spring使用ConversionService用于值(value)转换。默认设置 StringToArrayConverter is used ,不幸的是,它将字符串处理为逗号分隔列表。

做什么:

您对 Spring 处理单值请求参数的方式感到非常困惑。所以我会手动进行绑定(bind):

// Method annotations
public HttpEntity<CustomOutputObject> handlerMethod(WebRequest request) {
    String[] ingredients = request.getParameterValues("ingredients");
    // Do other stuff 
}
<小时/>

您还可以查看Spring guys have to say about this ..和related SO question .

关于java - Spring REST Controller 在具有空格或逗号等特殊字符时理解字符串数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24559288/

相关文章:

java - 我需要能够通过另一个类中的按钮更改java中框架的标题

java - 我们可以在List中插入多种类型的元素吗?

c - 如何求二维数组中元素出现的频率?

c++ - 使用相应的数组对数组进行排序

java - org.springframework.beans.factory.xml.XmlBeanDefinitionStoreException :

java - Spring 3.2 和 Jersey 2.4 的 Autowiring 问题

java - 如何在 Windows 中将 jar 添加到 jconsole 类路径?

java - 构造函数中的ArrayList

java - 带有同步关键字的 Spring @Transactional 不起作用

Java Spring REST API CORS 不适用于通过 jQuery 和 Chrome 的 DELETE 请求