原文网址:
简介
定制app开发本文用示例介绍SpringMVC如何通过JSON定制app开发格式传递入参。
JSON格式使用post方式来请求,即:对应的注解为:@。
@PostMapping注解的方法可以接收1个@RequestBody标记的参数和多个没有@RequestBody标记的参数。
代码
Entity
User.java
- package com.example.demo.entity;
-
- import lombok.Data;
- import java.util.List;
-
- @Data
- public class User {
- private String name;
- private Integer age;
- private String[] password;
- private List<Integer> scoreArray;
- }
Account.java
- package com.example.demo.entity;
-
- import lombok.Data;
- import java.io.Serializable;
-
- @Data
- public class Account implements Serializable {
- private String phoneNum;
- private String[] emails;
- }
Controller
- package com.example.demo.controller;
-
- import com.example.demo.entity.User;
- import org.springframework.web.bind.annotation.RestController;
- import org.springframework.web.bind.annotation.RequestBody;
- import org.springframework.web.bind.annotation.PostMapping;
- import org.springframework.web.bind.annotation.RequestParam;
- import org.springframework.web.bind.annotation.ResponseBody;
-
- import java.util.Arrays;
- import java.util.List;
-
- @RequestMapping("/json")
- @RestController
- public class JsonController {
- @PostMapping("/1")
- public User setUserNoAnnotation(User user, List<String> password, Integer[] scoreArray) {
- printUser(user);
- return user;
- }
-
- @RequestMapping("/2")
- public User setUserAnnotation(@RequestBody User user) {
- printUser(user);
- return user;
- }
-
- @RequestMapping("/3")
- public User setUserAnnotation1(@RequestBody User user, @RequestParam List<String> password, Integer[] scoreArray) {
- System.out.println(password);
- if (scoreArray != null) {
- System.out.println(Arrays.asList(scoreArray));
- } else {
- System.out.println("scoreArray = null");
- }
- System.out.println();
- printUser(user);
-
- return user;
- }
-
- @RequestMapping("/4")
- public User setUserAnnotation2(@RequestBody User user, @RequestBody List<String> password, @RequestBody Integer[] scoreArray) {
- if (password != null) {
- System.out.println(password);
- } else {
- System.out.println("password = null");
- }
-
- if (scoreArray != null) {
- System.out.println(Arrays.asList(scoreArray));
- } else {
- System.out.println("scoreArray = null");
- }
- System.out.println();
- printUser(user);
- return user;
- }
-
- private void printUser(User user){
- System.out.println("name : " + user.getName());
- System.out.println("password : " + Arrays.asList(user.getPassword()));
- System.out.println("scoreArray : " + user.getScoreArray());
- System.out.println("acount.phoneNum : " + user.getAccount().getPhoneNum());
- System.out.println("account.emails : " + Arrays.asList(user.getAccount().getEmails()));
- }
- }
测试
为方便测试,我用了。
测试前提
json的body
- {
- "name": "Jarvis",
- "password": [
- "ab",
- "cd"
- ],
- "scoreArray": [
- 99,
- 98
- ],
- "account": {
- "phoneNum": "123",
- "emails": [
- "123@qq.com",
- "456@163.com"
- ]
- }
- }
正确的用法
1个RequestBody
0个@,多个无@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
后端错误信息
- 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
-
- java.lang.NoSuchMethodException: java.util.List.<init>()
- at java.lang.Class.getConstructor0(Class.java:3082) ~[na:1.8.0_201]
- at java.lang.Class.getDeclaredConstructor(Class.java:2178) ~[na:1.8.0_201]
- ...(其他信息)
错误原因
不支持非@RequstBody的参数是List类型。(数组类型可以)。