我可以对 Post 请求使用 @Requestparam 注释吗?

Can I use @Requestparam annotation for a Post request?

我有这个控制器方法:

@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);
}

然而,当我向此端点发送 post 请求时,我得到以下

"{"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 参数时,我得到了一个更一般的错误,它会说它找不到第一个必需的参数(开始),而它实际上是与参数结束、时间和用户名。

how to get param in method post spring mvc?

我在这篇 post 中读到 @RequestParam 只能用于 get 方法,但是如果我删除 @RequestParam 并坚持使用 [=13 的 params 参数=] 注释它仍然不起作用。我知道我可以使用 @RequestBody 但我不想只为这 4 个参数创建 class。谁能告诉我如何进行这项工作?

谢谢

编辑:我在这里 https://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/web/bind/annotation/RequestMapping.html#params-- 读到参数 params 与我想的不完全一样。它似乎被用作条件。如果一组参数匹配一个值,那么端点控制器方法将被激活。

你的要求根本就是错误的。 POST 请求在 body 负载中发送数据,通过 @RequestBody 映射。 @RequestParam用于通过URL参数映射数据,如/url?start=foo。您要做的是使用 @RequestParam 来完成 @RequestBody.

的工作

REST 控制器的替代解决方案

  • 引入 DTO class。这是最首选和最干净的方法。
  • 如果你真的想避免创建class,你可以使用@RequestBody Map<String, String> payload。请务必在您的请求 header.
  • 中包含 'Content-Type': 'application/json'
  • 如果您真的想使用 @RequestParam,请改用 GET 请求并通过 URL 参数发送您的数据。

MVC 控制器的替代解决方案

  • 引入 DTO class 并使用注解 @ModelAttribute
  • 如果将表单数据转化为JSON,则可以使用@RequestBody Map<String, String> payload。为此,请参阅 this answer

无法将表单数据编码数据直接映射到 Map<String, String>

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

获取数据

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

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

@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);
}

这是针对 multipart/form-data enctype post 请求。

好吧,我认为@Synch 的回答从根本上是错误的,而不是所问的问题。

  1. 首先,我在很多需要 GET 或 POST HTTP 消息的场景中使用 @RequestParam,我想说,它工作得非常好;
  2. POST 消息的数据有效负载(正文),它被称为投票最多的答案(再次由@Synch)实际上是文本数据,它可以完全合法地成为 paramname=paramvalue key-值映射相似(参见 POST Message Body types 此处);
  3. docs.spring.io,Spring 文档 clearly states 的官方来源:

    In Spring MVC, "request parameters" map to query parameters, form data, and parts in multipart requests.

所以,我认为答案是肯定的,您可以将 @RequestParam 注释与 @Controller class 方法的参数一起使用,只要该方法由 @RequestMapping 而且你不期望对象,这是完全合法的,没有任何问题。

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

以上代码无效。

正确的语法是:

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

这会将请求映射到地图