0
点赞
收藏
分享

微信扫一扫

SpringMVC(SpringBoot)--获取参数/传参--方法/实例


简介

        本文用实例介绍SpringBoot获取前端传参的方法,包括:urlencoded/form-data/body/多个body。

        在开发时我们会在Controller获得前端传过来的参数,参数有多种格式,由​​Content-Type​​指定,不同的类型有所不同,本文介绍对于不同的类型后端如何接收。

创建项目

创建SpringBoot项目,引入spring-boot-starter-web

SpringMVC(SpringBoot)--获取参数/传参--方法/实例_jar

实体类

User.java

package com.example.demo.entity;

import java.util.List;

public class User {
private String name;
private Integer age;
private String[] password;
private List<Integer> scoreArray;

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public String[] getPassword() {
return password;
}

public void setPassword(String[] password) {
this.password = password;
}

public Integer getAge() {
return age;
}

public void setAge(Integer age) {
this.age = age;
}

public List<Integer> getScoreArray() {
return scoreArray;
}

public void setScoreArray(List<Integer> scoreArray) {
this.scoreArray = scoreArray;
}
}

Account.java

package com.example.demo.entity;

import java.io.Serializable;

public class Account implements Serializable {
private String phoneNum;
private String[] emails;

public String getPhoneNum() {
return phoneNum;
}

public void setPhoneNum(String phoneNum) {
this.phoneNum = phoneNum;
}

public String[] getEmails() {
return emails;
}

public void setEmails(String[] emails) {
this.emails = emails;
}
}

x-www-form-urlencoded请求

Controller

BasicController.java

package com.example.demo.controller;

import com.example.demo.entity.User;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import java.util.Arrays;
import java.util.List;

// localhost:8080/basic/no_annotation/string1
@RequestMapping("/basic")
@Controller
public class BasicController {
@RequestMapping("/1")
@ResponseBody
public String test1(int intVal, Long longVal, String myStr){
System.out.println("intVal : " + intVal);
System.out.println("longVal : " + longVal);
System.out.println("myStr : " + myStr);
return "Hello world";
}

@RequestMapping("/2")
@ResponseBody
public User test2(@RequestParam Integer intVal,
@RequestParam(value = "my_str", required = false) String[] myStr,
@RequestParam String[] password,
@RequestParam List<Integer> scoreArray,
@RequestParam Integer age,
User user){
System.out.println("intVal : " + intVal);
System.out.println("age : " + age);
System.out.println("myStr : " + Arrays.asList(myStr));
System.out.println("password : " + Arrays.asList(password));
System.out.println("scoreArray : " + scoreArray);

return user;
}

@RequestMapping("/3")
@ResponseBody
public User test3(@RequestBody User user){
return user;
}
}

测试

测试1:基本类型为空导致错误

​​http://localhost:8080/basic/1​​

后端打印

java.lang.IllegalStateException: Optional int parameter 'intVal' is present but cannot be translated into a null value due to being declared as a primitive type. Consider declaring it as object wrapper for the corresponding primitive type.

前端结果

SpringMVC(SpringBoot)--获取参数/传参--方法/实例_jar_02

测试2​:​正常操作​(其实也不正常,最好不要用基本类型接收。)

​​http://localhost:8080/basic/1?intVal=2&myStr=hehe​​

后端

intVal  : 2
longVal : null
myStr : hehe

前端

SpringMVC(SpringBoot)--获取参数/传参--方法/实例_spring_03

测试3​:​正常操作

​​http://localhost:8080/basic/2?intVal=2&my_str=Tony,Stark&name=Jarvis&age=21&password=ab,cd&scoreArray=99,98&phoneNum=12​​

后端

intVal     : 2
age : 21
myStr : [Tony, Stark]
password : [ab, cd]
scoreArray : [99, 98]

前端

SpringMVC(SpringBoot)--获取参数/传参--方法/实例_jar_04

结论


  • 如果一个参数,实体类与接口参数都有,则都会赋值。
  • 若实体类中有数组/List 成员,也会对它直接赋值。
  • 若实体类含有实体类,无法赋值。因为参数中没有与实体类相同名字的key,此时就要用form-data或者json了。(或者x-www-urlencoded也有写类参数的方法,目前不知道)

测试4​:​@RequestParam缺少参数访问(失败)

​​http://localhost:8080/basic/2?intVal=2&my_str=Tony,Stark&name=Jarvis&age=21&password=ab,cd&phoneNum=12​​

后端

2020-07-04 18:00:37.222  WARN 15844 --- [nio-8080-exec-8] .w.s.m.s.DefaultHandlerExceptionResolver : Resolved [org.springframework.web.bind.MissingServletRequestParameterException: Required List parameter 'scoreArray' is not present]

前端

SpringMVC(SpringBoot)--获取参数/传参--方法/实例_java_05

测试5​:​用@RequestBody接收(失败)

​​http://localhost:8080/basic/3?intVal=2&my_str=Tony,Stark&name=Jarvis&age=21&password=ab,cd&scoreArray=99,98&phoneNum=12​​

后端

2020-07-04 14:02:55.954  WARN 15844 --- [nio-8080-exec-3] .w.s.m.s.DefaultHandlerExceptionResolver : Resolved [org.springframework.http.converter.HttpMessageNotReadableException: Required request body is missing: public com.example.demo.entity.User com.example.demo.controller.BasicController.test3(com.example.demo.entity.User)]

前端

SpringMVC(SpringBoot)--获取参数/传参--方法/实例_jar_06

form-data请求

其他网址

​​​​

Controller

FormDataController.java

package com.example.demo.controller;

import com.example.demo.entity.User;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.util.Arrays;
import java.util.List;

// localhost:8080/basic/no_annotation/string1
@RequestMapping("/formdata")
@Controller
public class FormDataController {
@RequestMapping("/1")
@ResponseBody
public String test1(int intVal, Long longVal, String myStr){
System.out.println("intVal : " + intVal);
System.out.println("longVal : " + longVal);
System.out.println("myStr : " + myStr);
return "Hello world";
}

@RequestMapping("/2")
@ResponseBody
public User test2(@RequestParam Integer intVal,
@RequestParam(value = "my_str", required = false) String[] myStr,
@RequestParam String[] password,
@RequestParam List<Integer> scoreArray,
@RequestParam Integer age,
User user){
System.out.println("intVal : " + intVal);
System.out.println("age : " + age);
System.out.println("myStr : " + Arrays.asList(myStr));
System.out.println("password : " + Arrays.asList(password));
System.out.println("scoreArray : " + scoreArray);

return user;
}

@RequestMapping("/3")
@ResponseBody
public User test3(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()));
return user;
}

@RequestMapping("/4")
@ResponseBody
public User test4(@RequestBody 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()));
return user;
}

@PostMapping(value = "/5", headers="content-type=multipart/form-data")
@ResponseBody
public String test5(MultipartFile file1, MultipartFile[] files) {
return "file1名字:" + file1.getOriginalFilename() + "\r\n"
+ "files[0]名字:" + files[0].getOriginalFilename() + "\r\n"
+ "files[1]名字:" + files[1].getOriginalFilename();
}
}

测试

测试1:基本类型为空导致错误

postman(​​http://localhost:8080/formdata/1​​)

SpringMVC(SpringBoot)--获取参数/传参--方法/实例_jar_07

后端

java.lang.IllegalStateException: Optional int parameter 'intVal' is present but cannot be translated into a null value due to being declared as a primitive type. Consider declaring it as object wrapper for the corresponding primitive type.

测试2​:​基本类型不为空(成功)  //​最好不要用基本类型接收。

postman:访问​​http://localhost:8080/formdata/1/​​

SpringMVC(SpringBoot)--获取参数/传参--方法/实例_spring boot_08

后端

intVal  : 2
longVal : null
myStr : hehe

测试3​:​正常操作:没有@RequestBody的接收单个实体类接收

postman的body数据

SpringMVC(SpringBoot)--获取参数/传参--方法/实例_jar_09

后端

name            : Jarvis
password : [ab, cd]
scoreArray : [99, 98]
acount.phoneNum : null
account.emails : [123@qq.com, 456@163.com]

测试4​:​有@RequestBody的接收单个实体类接收(失败)

postman访问:​​http://localhost:8080/formdata/4/​​

postman数据:

SpringMVC(SpringBoot)--获取参数/传参--方法/实例_java_10

后端打印

2020-07-06 09:18:19.637  WARN 16088 --- [nio-8080-exec-1] .w.s.m.s.DefaultHandlerExceptionResolver : Resolved [org.springframework.web.HttpMediaTypeNotSupportedException: Content type 'multipart/form-data;boundary=--------------------------428878162965035610803450;charset=UTF-8' not supported]

测试5: 接收单文件与多文件

postman访问:​​http://localhost:8080/formdata/5​​

postman数据:

SpringMVC(SpringBoot)--获取参数/传参--方法/实例_java_11

JSON请求(单个对象)

Controller

JsonController.java

package com.example.demo.controller;

import com.example.demo.entity.User;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import java.util.Arrays;
import java.util.List;

@RequestMapping("/json")
@Controller
public class JsonController {
@RequestMapping("/1")
@ResponseBody
public User setUserNoAnnotation(User user, List<String> password, Integer[] scoreArray) {
printUser(user);
return user;
}

@RequestMapping("/2")
@ResponseBody
public User setUserAnnotation(@RequestBody User user) {
printUser(user);
return user;
}

@RequestMapping("/3")
@ResponseBody
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")
@ResponseBody
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:正常操作

使用postman,url:​​http://localhost:8080/json/2​​

后端

name            : Jarvis
password : [ab, cd]
scoreArray : [99, 98]
acount.phoneNum : 123
account.emails : [123@qq.com, 456@163.com]

postman

{
"name": "Jarvis",
"age": null,
"password": [
"ab",
"cd"
],
"scoreArray": [
99,
98
],
"account": {
"phoneNum": "123",
"emails": [
"123@qq.com",
"456@163.com"
]
}
}

测试2:(不使用@RequestBody接收)

使用postman,url:​​http://localhost:8080/json/1​​

后端

2020-07-03 23:27:18.504 ERROR 12568 --- [nio-8080-exec-3] 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_51]
at java.lang.Class.getDeclaredConstructor(Class.java:2178) ~[na:1.8.0_51]
at org.springframework.web.method.annotation.ModelAttributeMethodProcessor.createAttribute(ModelAttributeMethodProcessor.java:216) ~[spring-web-5.2.7.RELEASE.jar:5.2.7.RELEASE]
at org.springframework.web.servlet.mvc.method.annotation.ServletModelAttributeMethodProcessor.createAttribute(ServletModelAttributeMethodProcessor.java:85) ~[spring-webmvc-5.2.7.RELEASE.jar:5.2.7.RELEASE]
at org.springframework.web.method.annotation.ModelAttributeMethodProcessor.resolveArgument(ModelAttributeMethodProcessor.java:139) ~[spring-web-5.2.7.RELEASE.jar:5.2.7.RELEASE]
at org.springframework.web.method.support.HandlerMethodArgumentResolverComposite.resolveArgument(HandlerMethodArgumentResolverComposite.java:121) ~[spring-web-5.2.7.RELEASE.jar:5.2.7.RELEASE]
at org.springframework.web.method.support.InvocableHandlerMethod.getMethodArgumentValues(InvocableHandlerMethod.java:167) ~[spring-web-5.2.7.RELEASE.jar:5.2.7.RELEASE]
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:134) ~[spring-web-5.2.7.RELEASE.jar:5.2.7.RELEASE]
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:105) ~[spring-webmvc-5.2.7.RELEASE.jar:5.2.7.RELEASE]
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:879) ~[spring-webmvc-5.2.7.RELEASE.jar:5.2.7.RELEASE]
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:793) ~[spring-webmvc-5.2.7.RELEASE.jar:5.2.7.RELEASE]
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87) ~[spring-webmvc-5.2.7.RELEASE.jar:5.2.7.RELEASE]
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1040) ~[spring-webmvc-5.2.7.RELEASE.jar:5.2.7.RELEASE]
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:943) ~[spring-webmvc-5.2.7.RELEASE.jar:5.2.7.RELEASE]
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006) ~[spring-webmvc-5.2.7.RELEASE.jar:5.2.7.RELEASE]
at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:909) ~[spring-webmvc-5.2.7.RELEASE.jar:5.2.7.RELEASE]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:660) ~[tomcat-embed-core-9.0.36.jar:9.0.36]
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883) ~[spring-webmvc-5.2.7.RELEASE.jar:5.2.7.RELEASE]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:741) ~[tomcat-embed-core-9.0.36.jar:9.0.36]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231) ~[tomcat-embed-core-9.0.36.jar:9.0.36]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.36.jar:9.0.36]
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53) ~[tomcat-embed-websocket-9.0.36.jar:9.0.36]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-9.0.36.jar:9.0.36]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.36.jar:9.0.36]
at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100) ~[spring-web-5.2.7.RELEASE.jar:5.2.7.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) ~[spring-web-5.2.7.RELEASE.jar:5.2.7.RELEASE]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-9.0.36.jar:9.0.36]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.36.jar:9.0.36]
at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93) ~[spring-web-5.2.7.RELEASE.jar:5.2.7.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) ~[spring-web-5.2.7.RELEASE.jar:5.2.7.RELEASE]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-9.0.36.jar:9.0.36]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.36.jar:9.0.36]
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201) ~[spring-web-5.2.7.RELEASE.jar:5.2.7.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) ~[spring-web-5.2.7.RELEASE.jar:5.2.7.RELEASE]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-9.0.36.jar:9.0.36]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.36.jar:9.0.36]
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:202) ~[tomcat-embed-core-9.0.36.jar:9.0.36]
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96) [tomcat-embed-core-9.0.36.jar:9.0.36]
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:541) [tomcat-embed-core-9.0.36.jar:9.0.36]
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:139) [tomcat-embed-core-9.0.36.jar:9.0.36]
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92) [tomcat-embed-core-9.0.36.jar:9.0.36]
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74) [tomcat-embed-core-9.0.36.jar:9.0.36]
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343) [tomcat-embed-core-9.0.36.jar:9.0.36]
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:373) [tomcat-embed-core-9.0.36.jar:9.0.36]
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65) [tomcat-embed-core-9.0.36.jar:9.0.36]
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:868) [tomcat-embed-core-9.0.36.jar:9.0.36]
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1590) [tomcat-embed-core-9.0.36.jar:9.0.36]
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) [tomcat-embed-core-9.0.36.jar:9.0.36]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) [na:1.8.0_51]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) [na:1.8.0_51]
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) [tomcat-embed-core-9.0.36.jar:9.0.36]
at java.lang.Thread.run(Thread.java:745) [na:1.8.0_51]

postman

{
"timestamp": "2020-07-03T15:44:10.224+00:00",
"status": 500,
"error": "Internal Server Error",
"message": "",
"path": "/json/1"
}

测试3:(一个有@RequestBody+多个无)

postman访问:​​http://localhost:8080/json/3?password=ef,gh​​

后端

[ef, gh]
scoreArray = null

name : Jarvis
password : [ab, cd]
scoreArray : [99, 98]
acount.phoneNum : 123
account.emails : [123@qq.com, 456@163.com]

postman

{
"name": "Jarvis",
"age": null,
"password": [
"ab",
"cd"
],
"scoreArray": [
99,
98
],
"account": {
"phoneNum": "123",
"emails": [
"123@qq.com",
"456@163.com"
]
}
}

测试4:多个@RequestBody

postman访问:​​http://localhost:8080/json/4?password=ef,gh​​

后端

2020-07-03 23:48:06.907  WARN 2644 --- [nio-8080-exec-5] .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]

postman

{
"timestamp": "2020-07-03T15:47:45.924+00:00",
"status": 400,
"error": "Bad Request",
"message": "",
"path": "/json/4"
}

错误原因

其他网址:​​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.

JSON请求(多个对象)

其他网址

方案1:​Map对象接收

前端

$("#ok2").click(function(){
var json = {"user":{"id":9527,"userName":"zcy","realName":"钢铁侠"},"info":{"id":998,"address":"纽约"}};
$.ajax({
url:"http://localhost:8080/more/show",
type:"post",
cache:false,
contentType:"application/json",
data:JSON.stringify(json),
success:function(data){
alert(data);
}
});
});

后端

@RequestMapping(value = "/show")
public String test(@RequestBody Map<String,Object> map){

// 拿到Object之后 再做转换为实体即可 可以用FastJson
Object user = map.get("user");
Object info = map.get("info");

return "success";
}

方案2:自定义处理方法

前端

$("#ok2").click(function(){
var json = {"user":{"id":9527,"userName":"zcy","realName":"钢铁侠"},"info":{"id":998,"address":"纽约"}};
$.ajax({
url:"http://localhost:8080/more/custom",
type:"post",
cache:false,
// 直接传josn对象 这里与上文不同
data:json,
success:function(data){
alert(data);
}
});
});

后端

自定义注解 (加在控制器的参数前作为标记)

@Target(ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface JsonObject {
}

自定义处理类(实现HandlerMethodArgumentResolver接口)

public class JsonObjectArgResolverHandler implements HandlerMethodArgumentResolver {

@Override
public boolean supportsParameter(MethodParameter methodParameter) {
return methodParameter.hasParameterAnnotation(JsonObject.class);
}

@Override
public Object resolveArgument(MethodParameter methodParameter,
ModelAndViewContainer modelAndViewContainer, NativeWebRequest nativeWebRequest,
WebDataBinderFactory webDataBinderFactory) throws Exception {

// 获取Controller中的参数名
String name = methodParameter.getParameterName();
// 获取Controller中参数的类型
Class clazz = methodParameter.getParameterType();
Object arg = null;
// 获取该参数实体的所用属性
Field[] fields = clazz.getDeclaredFields();
// 实例化
Object target = clazz.newInstance();

// 创建WebDataBinder对象 反射 遍历fields给属性赋值
WebDataBinder binder = webDataBinderFactory.createBinder(nativeWebRequest,null,name);
for (Field field:fields){
field.setAccessible(true);
String fieldName = field.getName();
Class<?> fieldType = field.getType();
// 在request中 多对象json数据的key被解析为 user[id] user[realName] info[address] 的这种形式
String value = nativeWebRequest.getParameter(name + "[" + fieldName + "]");
arg = binder.convertIfNecessary(value,fieldType,methodParameter);
field.set(target,arg);
}

return target;
}
}

注册自己写的处理类

@Component
public class MyWebAppConfig implements WebMvcConfigurer {
@Override
public void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers) {
// 配置自定义接收参数
WebMvcConfigurer.super.addArgumentResolvers(resolvers);
resolvers.add(new JsonObjectArgResolverHandler());
}
}

Controller

@RequestMapping(value = "/custom")
public String custom(@JsonObject User user, @JsonObject Info info){
System.out.println(user.toString());
System.out.println(info.toString());

return "success";
}


举报

相关推荐

0 条评论