• SpringBoot--通过JSON传递请求参数--方法/实例


    原文网址:SpringBoot--通过JSON传递请求参数--方法/实例_IT利刃出鞘的博客-CSDN博客

    简介

            本文用示例介绍SpringMVC如何通过JSON格式传递入参。

            JSON格式使用post方式来请求,即:对应的注解为:@PostMapping

            @PostMapping注解的方法可以接收1个@RequestBody标记的参数和多个没有@RequestBody标记的参数

    代码

    Entity

    User.java

    1. package com.example.demo.entity;
    2. import lombok.Data;
    3. import java.util.List;
    4. @Data
    5. public class User {
    6. private String name;
    7. private Integer age;
    8. private String[] password;
    9. private List scoreArray;
    10. }

    Account.java

    1. package com.example.demo.entity;
    2. import lombok.Data;
    3. import java.io.Serializable;
    4. @Data
    5. public class Account implements Serializable {
    6. private String phoneNum;
    7. private String[] emails;
    8. }

    Controller

    1. package com.example.demo.controller;
    2. import com.example.demo.entity.User;
    3. import org.springframework.web.bind.annotation.RestController;
    4. import org.springframework.web.bind.annotation.RequestBody;
    5. import org.springframework.web.bind.annotation.PostMapping;
    6. import org.springframework.web.bind.annotation.RequestParam;
    7. import org.springframework.web.bind.annotation.ResponseBody;
    8. import java.util.Arrays;
    9. import java.util.List;
    10. @RequestMapping("/json")
    11. @RestController
    12. public class JsonController {
    13. @PostMapping("/1")
    14. public User setUserNoAnnotation(User user, List password, Integer[] scoreArray) {
    15. printUser(user);
    16. return user;
    17. }
    18. @RequestMapping("/2")
    19. public User setUserAnnotation(@RequestBody User user) {
    20. printUser(user);
    21. return user;
    22. }
    23. @RequestMapping("/3")
    24. public User setUserAnnotation1(@RequestBody User user, @RequestParam List password, Integer[] scoreArray) {
    25. System.out.println(password);
    26. if (scoreArray != null) {
    27. System.out.println(Arrays.asList(scoreArray));
    28. } else {
    29. System.out.println("scoreArray = null");
    30. }
    31. System.out.println();
    32. printUser(user);
    33. return user;
    34. }
    35. @RequestMapping("/4")
    36. public User setUserAnnotation2(@RequestBody User user, @RequestBody List password, @RequestBody Integer[] scoreArray) {
    37. if (password != null) {
    38. System.out.println(password);
    39. } else {
    40. System.out.println("password = null");
    41. }
    42. if (scoreArray != null) {
    43. System.out.println(Arrays.asList(scoreArray));
    44. } else {
    45. System.out.println("scoreArray = null");
    46. }
    47. System.out.println();
    48. printUser(user);
    49. return user;
    50. }
    51. private void printUser(User user){
    52. System.out.println("name : " + user.getName());
    53. System.out.println("password : " + Arrays.asList(user.getPassword()));
    54. System.out.println("scoreArray : " + user.getScoreArray());
    55. System.out.println("acount.phoneNum : " + user.getAccount().getPhoneNum());
    56. System.out.println("account.emails : " + Arrays.asList(user.getAccount().getEmails()));
    57. }
    58. }

    测试

    为方便测试,我用了knife4j

    测试前提

    json的body

    1. {
    2. "name": "Jarvis",
    3. "password": [
    4. "ab",
    5. "cd"
    6. ],
    7. "scoreArray": [
    8. 99,
    9. 98
    10. ],
    11. "account": {
    12. "phoneNum": "123",
    13. "emails": [
    14. "123@qq.com",
    15. "456@163.com"
    16. ]
    17. }
    18. }

    正确的用法

    1个RequestBody

    0个@RequestBody,多个无@RequestBody

    1个@RequestBody,多个无@RequestBody

    错误的用法(会报错)

    多个@RequestBody

    后端报错信息

    2022-09-20 22:04:45.857  WARN 3340 --- [nio-8080-exec-1] .w.s.m.s.DefaultHandlerExceptionResolver : Resolved [org.springframework.http.converter.HttpMessageNotReadableException: I/O error while reading input message; nested exception is java.io.IOException: Stream closed]
    

    错误原因

            每个方法只能有一个@RequestBody。使用@RequestBody把请求转化为特定的Object(在最后会关闭相应的流),所以在同一个方法中第二次使用@RequestBody是没用的,因为流已经关闭。

            You cannot use it this way as only one @RequestBody per method is allowed. Using @RequestBody Spring converts incoming request body into the specified object (what closes the stream representing body at the end) so attempting to use @RequestBody second time in the same method makes no sense as stream has been already closed.

    不带@RequestBody参数类型是List

    后端错误信息

    1. 2022-09-20 23:19:11.044 ERROR 3340 --- [nio-8080-exec-2] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is java.lang.IllegalStateException: No primary or default constructor found for interface java.util.List] with root cause
    2. java.lang.NoSuchMethodException: java.util.List.()
    3. at java.lang.Class.getConstructor0(Class.java:3082) ~[na:1.8.0_201]
    4. at java.lang.Class.getDeclaredConstructor(Class.java:2178) ~[na:1.8.0_201]
    5. ...(其他信息)

    错误原因

    不支持非@RequstBody的参数是List类型。(数组类型可以)。

  • 相关阅读:
    剑指 Offer II 059. 数据流的第 K 大数值
    【论文阅读】WATSON:通过聚合上下文语义从审计日志中抽象出行为(NDSS-2021)
    linux性能优化--性能追踪建议
    Java方向面试题(一)
    【5分钟背八股】03:说说你对aop的理解?
    【面试题精讲】如果一个类没有声明构造方法,该程序能正确执行吗?
    iOS15适配 UINavigationBar和UITabBar设置无效,变成黑色
    Shiro-集成验证码
    vue3学习(四)--- watch和watchEffect监听
    Grial UI Kit 4发布,版本4中的新增功能
  • 原文地址:https://blog.csdn.net/feiying0canglang/article/details/126955477