我可以将@requestParam注释用于发布请求吗?



我有此控制器方法:

@PostMapping(
        value = "/createleave",
        params = {"start","end","hours","username"})
public void createLeave(@RequestParam(value = "start") String start,
                        @RequestParam(value = "end") String end,
                        @RequestParam(value = "hours") String hours,
                        @RequestParam(value = "username") String username){
    System.out.println("Entering createLeave " + start + " " + end + " " + hours + " " + username);
    LeaveQuery newLeaveQuery = new LeaveQuery();
    Account account = accountRepository.findByUsername(username);
    newLeaveQuery.setAccount(account);
    newLeaveQuery.setStartDate(new Date(Long.parseLong(start)));
    newLeaveQuery.setEndDate(new Date(Long.parseLong(end)));
    newLeaveQuery.setTotalHours(Integer.parseInt(hours));
    leaveQueryRepository.save(newLeaveQuery);
}

但是,当我向此端点发送帖子请求时,我会得到以下

"{"timestamp":1511444885321,"status":400,"error":"Bad Request","exception":"org.springframework.web.bind.UnsatisfiedServletRequestParameterException","message":"Parameter conditions "start, end, hours, username" not met for actual request parameters: ","path":"/api/createleave"}"

当我从 @PostMapping注释中删除params参数时,我会遇到更一般的错误,它将说它找不到第一个必需的参数(start),而它确实与参数结束,小时和用户名一起发送在一起。

如何获得param in方法spring mvc?

我在这篇文章中读到@RequestParam只能用于获取方法,但是如果我删除@RequestParam并坚持使用@PostMapping注释的参数,则仍然无法正常工作。我知道我可以使用@RequestBody,但我不想仅针对这4个参数上课。谁能告诉我如何完成这项工作?

谢谢

编辑:我正在这里阅读https://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/web/web/bind/annotation/ranotation/requestmapping.html#params-参数并不是我认为的。它似乎被用作条件。如果一组参数匹配一个值,则将激活端点控制器方法。

好吧, @sync的答案从根本上是错误的,而不是问的问题。

  1. 首先,我在很多情况下都使用@RequestParam,期望获得或发布HTTP消息,我想说的是,它的工作正常;
  2. 发布消息的有效载荷数据(正文)实际上是文本数据,它可以完全合法地是paramname = paramvalue键值映射(S)(S)
  3. docs.spring.io,春季文档的官方资料,显然指出:

在Spring MVC中,"请求参数"映射到查询参数,表单数据,以及多部分请求中的零件。

因此,答案是肯定的,您可以使用@RequestParam班级方法的参数使用CC_9注释,只要该方法是A handler方法(由@RequestMapping请求映射),而您却不期待对象,这是完全合法的,没有错。

您要求的是从根本上错了。发布请求在正文有效载荷中发送数据,该数据通过@RequestBody映射。@RequestParam用于通过/url?start=foo等URL参数映射数据。您要做的就是使用@RequestParam来完成@RequestBody的工作。

REST控制器的替代解决方案

  • 介绍DTO课程。这是最喜欢和干净的方法。
  • 如果您真的想避免创建类,则可以使用@RequestBody Map<String, String> payload。确保将'Content-Type': 'application/json'包括在您的请求标题中。
  • 如果您真的想使用@RequestParam,请改用Get请求,然后通过URL参数发送数据。

MVC控制器的替代解决方案

  • 介绍DTO类并与注释@ModelAttribute一起使用。
  • 如果将表单数据转换为JSON,则可以使用@RequestBody Map<String, String> payload。为此,请查看此答案。

不可能将数据编码的数据直接映射到Map<String, String>

您应该使用@RequestBody而不是使用@RequestParam您应该提供整个物体作为一个请求的主体 @RequestParam是从URL

获取数据

您可以做类似的事情 public saveUser(@RequestBody User user) { do something with user }

,它将被映射为用户对象,例如

public void createLeave(@RequestParam Map<String, String> requestParams)

上面的代码不起作用。

正确的语法是:

public void createLeave(@RequestBody Map<String, String> requestParams)

将将请求映射到地图

@PostMapping("/createleave")
public void createLeave(@RequestParam Map<String, String> requestParams){
    String start = requestParams.get("start");
    String end= requestParams.get("end");
    String hours= requestParams.get("hours");
    String username = requestParams.get("username");
    System.out.println("Entering createLeave " + start + " " + end + " " + hours + " " + username);
}

这是用于多部分/form-data enctype post request。

最新更新