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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/47457382/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-12 02:36:59  来源:igfitidea点击:

Can I use @Requestparam annotation for a Post request?

javaspringspring-mvcspring-web

提问by Maurice

I have this controller method:

我有这个控制器方法:

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

However when I send a post request to this endpoint I get the following

但是,当我向此端点发送发布请求时,我得到以下信息

"{"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"}"

When I remove the params argument from the @PostMappingannotation I get a more general error, it will say that it cannot find the first required parameter (start), while it really is being send together with the parameters end, hours and username.

当我从@PostMapping注释中删除 params 参数时,我得到一个更一般的错误,它会说它找不到第一个必需的参数 (start),而它实际上是与参数 end、hours 和 username 一起发送的。

how to get param in method post spring mvc?

如何在 spring mvc 后的方法中获取参数?

I've read in this post that @RequestParamcan only be used for get methods, but if I remove @RequestParamand stick with the params argument of the @PostMappingannotation it still doesn't work. I know I can use @RequestBodybut I do not want to make a class just for those 4 parameters. Can anyone tell me how I can make this work?

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

Thank you

谢谢

EDIT: I'm reading here https://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/web/bind/annotation/RequestMapping.html#params--that the argument params isn't exactly what I thought it was. It seems to be used as a condition. If a set of parameters match a value then the endpoint controller method will be activated.

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

采纳答案by Sync

What you are asking for is fundamentally wrong. POST requests sends data in a body payload, which is mapped via @RequestBody. @RequestParamis used to map data through the URL parameters such as /url?start=foo. What you are trying to do is use @RequestParamto do the job of @RequestBody.

你所要求的从根本上是错误的。POST 请求在正文有效负载中发送数据,该有效负载通过@RequestBody. @RequestParam用于通过 URL 参数映射数据,例如/url?start=foo. 您正在尝试做的是@RequestParam用来完成@RequestBody.

Alternative solutions for REST controllers

REST 控制器的替代解决方案

  • Introduce a DTO class. It is the most preferred and clean method.
  • If you really want to avoid creating a class, you can use @RequestBody Map<String, String> payload. Be sure to include 'Content-Type': 'application/json'in your request header.
  • If you really want to use @RequestParam, use a GET request instead and send your data via URL parameters.
  • 介绍一个 DTO 类。这是最优选和最干净的方法。
  • 如果你真的想避免创建一个类,你可以使用@RequestBody Map<String, String> payload. 请务必包含'Content-Type': 'application/json'在您的请求标头中。
  • 如果您真的想使用@RequestParam,请改用 GET 请求并通过 URL 参数发送您的数据。

Alternative solutions for MVC controllers

MVC 控制器的替代解决方案

  • Introduce a DTO class and use it with annotation @ModelAttribute.
  • If you transform the form data into JSON, you can use @RequestBody Map<String, String> payload. To do this, please see this answer.
  • 引入一个 DTO 类并将其与 annotation 一起使用@ModelAttribute
  • 如果将表单数据转换为 JSON,则可以使用@RequestBody Map<String, String> payload. 为此,请参阅此答案

It is not possible to map form data encoded data directly to a Map<String, String>.

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

回答by Nenad Jovicic

You should use @RequestBodyinstead of using @RequestParamAnd you should provide whole object as a body of request @RequestParamis for GET, and not POST method

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

you can do something like public saveUser(@RequestBody User user) { do something with user }

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

and it will be mapped as User object for example

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

回答by Jerald Macachor

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

This is for multipart/form-data enctype post request.

这是用于 multipart/form-data enctype post 请求。

回答by Giorgi Tsiklauri

Well, I think the answer by @Synch is fundamentally wrong, and not the question being asked.

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

  1. First of all, I use @RequestParamin a lot of scenarios expecting either GET or POST HTTP messages and I'd like to say, that it works perfectly fine;
  2. POST Message's data payload (body), which is referred to the most voted answer (again, by @Synch) is actually the text data, which can perfectly legally be paramname=paramvaluekey-value mapping(s) alike (see POST Message Body typeshere);
  3. docs.spring.io, an official source for Spring Documentation, clearly states, that:

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

  1. 首先,我@RequestParam在许多需要 GET 或 POST HTTP 消息的场景中使用,我想说,它工作得非常好;
  2. POST 消息的数据负载(正文),指的是投票最多的答案(再次,@Synch)实际上是文本数据,它可以完全合法地成为paramname=paramvalue键值映射(请参阅此处的POST 消息正文类型) ;
  3. docs.spring.io,Spring 文档的官方来源,明确指出

    在 Spring MVC 中,“请求参数”映射到查询参数、表单数据和多部分请求中的部分。

So, I think the answer is YES, you can use @RequestParamannotation with @Controllerclass's method's parameter, as long as that method is request-mapped by @RequestMappingand you don't expect Object, this is perfectly legal and there's nothing wrong with it.

所以,我认为答案是肯定的,您可以使用@RequestParam带有@Controller类方法参数的注释,只要该方法是请求映射的@RequestMapping并且您不期望 Object,这是完全合法的,并且没有任何问题。