SpringMVC系列--获取参数--实例

创建项目

gitee地址:https://gitee.com/shapeless/demo/tree/master/demo_springboot_mvc

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

实体类

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.

前端结果

测试2正常操作

其实也不正常,最好不要用基本类型接收。

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

后端

intVal  : 2
longVal : null
myStr   : hehe

前端

测试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]

 前端

结论

  • 如果一个参数,实体类与接口参数都有,则都会赋值。
  • 若实体类中有数组/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]

前端

测试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)]

前端

form-data请求

其他网址

使用FormData格式在前后端传递数据 - wenr - 博客园

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.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import java.lang.reflect.Array;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

// 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;
    }
}

测试

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

postman(http://localhost:8080/formdata/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.

测试2基本类型不为空(成功)

最好不要用基本类型接收。

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

后端

intVal  : 2
longVal : null
myStr   : hehe

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

postman的body数据

后端

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数据:

后端打印

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]

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

错误原因

其他网址:https://www.e-learn.cn/topic/3352427

每个方法只能有一个@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请求(多个对象)

其他网址

SpringMVC接收多个对象参数_木子叶的奔跑-CSDN博客_spring接收2个对象的参数

方案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";
}

 

©️2020 CSDN 皮肤主题: 编程工作室 设计师: CSDN官方博客 返回首页
实付0元
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值