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

时间:2017-11-23 14:06:29

标签: java spring spring-mvc spring-web

我有这种控制器方法:

@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),而它实际上是与参数end一起发送的,小时和用户名。

how to get param in method post spring mvc?

我在这篇文章中读到@RequestParam只能用于get方法,但如果我删除@RequestParam并坚持@PostMapping注释的params参数,它仍然没有不行。我知道我可以使用@RequestBody,但我不想只为这4个参数创建一个类。谁能告诉我如何才能使这项工作?

谢谢

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

5 个答案:

答案 0 :(得分:8)

你所要求的是根本错误的。 POST请求在身体有效负载中发送数据,通过@RequestBody映射。 @RequestParam用于通过/url?start=foo等网址参数映射数据。您要做的是使用@RequestParam来完成@RequestBody的工作。

REST控制器的替代解决方案

  • 介绍DTO课程。这是最优选和最干净的方法。
  • 如果您真的想避免创建课程,可以使用@RequestBody Map<String, String> payload。请务必在您的请求标题中加入'Content-Type': 'application/json'
  • 如果您确实想使用@RequestParam,请改用GET请求,并通过网址参数发送数据。

MVC控制器的替代解决方案

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

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

答案 1 :(得分:2)

您应该使用@RequestBody而不是@RequestParam 你应该提供整个对象作为请求的主体 @RequestParam用于GET,而不是POST方法

你可以做点什么 public saveUser(@RequestBody User user) { do something with user }

它将被映射为User对象,例如

答案 2 :(得分:2)

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

  1. 首先,在很多需要GET或POST HTTP消息的情况下,我都使用df.values[:,1:]*=df.qtd[:,None] df Out[461]: qtd a b c d e z 0 90 90 0 0 0 0 0 1 10 0 0 0 0 0 10 2 40 0 40 0 0 0 0 3 80 0 0 80 0 0 0 4 90 0 90 0 0 0 0 ,我想说的是,它工作得很好;
  2. POST消息的数据有效载荷(正文),被称为投票最多的答案(再次由@Synch引用)实际上是文本数据,可以合法地完全@RequestParam键-值映射(请参见此处的POST Message Body types);
  3. paramname=paramvalue是Spring Documentation clearly states的官方资料,其中:
      

    在Spring MVC中,“请求参数”映射到查询参数,形式   数据以及多部分请求中的部分。

因此,我认为答案是肯定的,只要docs.spring.io请求映射了该方法,并且您可以使用@RequestParam类的方法的参数使用@Controller注释不要指望对象,这是完全合法的,并且没有错。

答案 3 :(得分:0)

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

以上代码无效。

正确的语法是:

public void createLeave(@RequestBodyMap<String, String> requestParams)

答案 4 :(得分:-1)

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

这是针对多部分/表单数据编码类型的请求。

相关问题