我正在尝试编写一个 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/