【问题标题】:PUT: PathVariable and RequestParam don't work togetherPUT:PathVariable 和 RequestParam 不能一起工作
【发布时间】:2019-08-17 00:52:16
【问题描述】:

我正在使用 Spring Boot 2.1.3-RELEASE。在我的 RestController 中,我尝试使用一个 PathVariable 和一个 RequestParam(application/x-www-form-urlencoded)设置一个 PUT 方法。 但是,当我调用它时,响应是一个错误的请求,因为所需的 RequestParam 不存在。

我尝试将 PutMapping 更改为 RequestMapping,交换参数位置并使用语法 @RequestParam(value="param2", required=false) 但没有任何变化。

奇怪地使用 PostMapping 工作。也删除 PathVariable 作品。

这里是 RestController 代码:

@PutMapping(value="/myurl/{param1}", consumes=MediaType.APPLICATION_FORM_URLENCODED_VALUE)
public String myMethod( @PathVariable("param1") Integer param1, @RequestParam("param2") String param2);

我是这样调用方法的:

curl -X PUT \
  http://localhost:8080/myurl/42 \
  -H 'Accept: application/json' \
  -H 'Content-Type: application/x-www-form-urlencoded' \
  -d 'param2=myparam2value'

回复是:

{ “时间戳”:15536​​13278534, “状态”:400, "error": "错误请求", "message": "必需的字符串参数 'param2' 不存在", “路径”:“/myurl/42” }

我希望 PUT 像 POST 一样工作,但似乎不是。

很遗憾,我无法将参数作为 QueryParam 发送,因此我应该保持相同的请求调用,因为我正在重构一个完全以这种方式工作的现有端点。

谢谢


编辑

我发现这是由使用 HandlerInterceptorAdapter(通过 WebMvcConfigurer)引起的。 不知为何,在

org.springframework.web.util.ContentCachingRequestWrapper.getParameterValues

org.apache.coyote.Request.parameters 没有内容并抛出异常,因此它仅适用于 POST 而不适用于 PUT(GET 的处理方式不同)。

如果有人可以建议考虑到删除拦截器使其工作,是否可以将其报告为错误,我将不胜感激。

问候

【问题讨论】:

  • some.endpoint/api/v1/users{id}?selector={foo} -- id -> PathParam 和 foo -> RequestParam。我的猜测是您将“RequestParam”与“HTTP 请求正文”混为一谈。如果您的 'param2' 是请求的正文,请删除 @RequestParam 注释。
  • 你可以试试这个: curl -X PUT \ localhost:8080/myurl/42?param2=myparam2value \ -H 'Accept: application/json' \ -H 'Content-Type: application/x-www-form-urlencoded' \
  • 参数进入请求正文,而不是在参数中。
  • 谢谢@Logan Wlv。不幸的是,我需要保持相同的调用约定,因为我正在重构现有的端点。

标签: java rest spring-boot put


【解决方案1】:

-G--data-urlencode 一起使用:

curl -G -X PUT \
  http://localhost:8080/myurl/42 \
  -H 'Accept: application/json' \
  -H 'Content-Type: application/x-www-form-urlencoded' \
  --data-urlencode 'param2=myparam2value'

来自documentation

-G, --get

使用此选项时,此选项将使所有使用 -d--data--data-binary--data-urlencode 指定的数据用于 HTTP GET 请求,而不是 POST 请求用过的。数据将附加到带有? 分隔符的 URL。 [...]

--data-urlencode <data>

(HTTP) 这将发布数据,与其他 -d--data 选项类似,只是它执行 URL 编码。 [...]

【讨论】:

  • 您能解释一下为什么他的示例使用@PostMapping 吗?
  • 您只需要阅读 -G 选项的文档:使用时,此选项将使所有使用 -d、--data、--data-binary 或 指定的数据--data-urlencode 在 HTTP GET 请求中使用,而不是在其他情况下使用的 POST 请求。 数据将附加到带有“?”的 URL分隔符.
  • 感谢您的回复。不幸的是,我正在重构一个遗留端点,所以我无法更改调用。在我看来,这对我来说似乎是一个 Spring Boot 错误。
猜你喜欢
  • 2015-08-18
  • 1970-01-01
  • 2014-01-07
  • 2016-11-23
  • 2019-02-18
  • 2015-05-16
  • 2017-10-14
  • 2012-06-01
  • 2011-11-05
相关资源
最近更新 更多