spring 我可以为Post请求使用@Requestparam注解吗?

biswetbf  于 2023-04-19  发布在  Spring
关注(0)|答案(5)|浏览(270)

我有这个控制器方法:

@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参数时,我得到了一个更一般的错误,它会说它找不到第一个必需的参数(start),而实际上它是与参数end,hours和username一起发送的。
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--,参数params并不完全是我想象的那样。它似乎被用作一个条件。如果一组参数匹配一个值,那么端点控制器方法将被激活。

yeotifhr

yeotifhr1#

好吧,@Sync的答案从根本上是错误的,而不是被问到的问题。
1.首先,我在许多需要GET或POST HTTP消息的场景中使用@RequestParam,我想说,它工作得非常好;

  1. POST消息的有效载荷数据(主体)实际上是 * 文本数据 *,它可以完全合法地是paramname = paramvalue键值Map(参见POST Message Body types);
  2. docs.spring.io,Spring文档的官方源代码,clearly states,它:
    在Spring MVC中,“request parameters”Map到查询参数、表单数据和多部分请求中的部分。
    所以,答案是肯定的,你可以使用@RequestParam注解和@Controller类的方法的参数,只要该方法是一个 *handler方法 *(由@RequestMapping请求Map),并且你不期望Object,这是完全法律的的,没有任何问题。
ttisahbt

ttisahbt2#

你所要求的是根本错误的。POST请求在body payload中发送数据,该数据通过@RequestBodyMap。@RequestParam用于通过URL参数(如/url?start=foo)Map数据。你试图做的是使用@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。为此,请参阅this answer

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

nlejzf6q

nlejzf6q3#

你应该使用@RequestBody而不是使用@RequestParam,你应该提供整个对象作为请求的主体@RequestParam是从URL获取数据
你可以像public saveUser(@RequestBody User user) { do something with user }这样做
它将被Map为User对象,例如

mw3dktmi

mw3dktmi4#

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

上面的代码没有工作。
正确的语法是:

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

它将请求Map到一个Map

qcuzuvrc

qcuzuvrc5#

@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请求。

相关问题