SpringMVC 传递参数过程当中 RquestBody,RequestParam 区别

最近面试遇到问springmvc传递参数相关的问题,在网上看到一篇解释比较详细的博客,原文连接:https://blog.csdn.net/LostSh/article/details/68923874面试

这里copy记录一下,方便本身之后回顾。ajax

SpringMVC中咱们能够选择数种接受JSON的方式,在说SpringMVC如何接受JSON以前,咱们先聊聊什么是JSON。具体的定义我也不赘述了,在JavaScript中咱们常常这样定义JSON 对象。spring

var jsonObject = { "username":"admin", "password":123 }json

这种形式的咱们叫它JSON对象,同时还有一个概念叫作JSON字符串,字符串呢,顾名思义,是由’ ‘或者” “包裹起来的一个总体,咱们称之为字符串。咱们知道字符串是能够直接输出的,而对象不能直接输出。因此在JavaScript中,咱们能够浏览器

//定义一个对象 jsonObjectvar jsonObject = { "username":"admin", "password":123 }; alert(jsonObject);服务器

此时,会显示[object Object]而不会输出JSON对象的内容,JavaScript向咱们提供了两个工具mvc

JSON.parse() 
用于将一个 JSON 字符串转换为 JavaScript 对象。 
JSON.stringify() 
用于将 JavaScript 值转换为 JSON 字符串。
app

因此当咱们输入async

alert(JSON.stringify(jsonObject));工具

就会显示 {“username”:”admin”,”password”:123};

* 好了 对于JSON的讲解就到这里了 下面咱们说一说SpringMVC *

既然JSON有着上述两种存在方式,那咱们经过ajax向SpringMVC传值的时候,咱们该传哪种呢? 
咱们首先尝试直接发送JSON对象

//定义json对象

            var username = $("#username").val();

            var password = $("#password").val();

            var json = {

                "username" : username,

                "password" : password

            };

 

// Jquery Ajax请求

$.ajax({

                url : "jsontest",

                type : "POST",

                async : true,

                data : json,

                dataType : 'json',

                success : function(data) {

                    if (data.userstatus === "success") {

                        $("#errorMsg").remove();

                    } else {

                        if ($("#errorMsg").length <= 0) {

                            $("form[name=loginForm]").append(errorMsg);

                        }

                    }

                }

            });

咱们首先想一想SpringMVC提供了什么给咱们,有一个@RequestParam的注解,对于这个注解,它的做用和咱们Servlet中的request.getParameter是基本相同的。咱们首先使用这个注解来获取

    @RequestMapping("/jsontest")

    public void test(@RequestParam(value="username",required=true) String username,

    @RequestParam(value="password",required=true) String password){

        System.out.println("username: " + username);

        System.out.println("password: " + password);

    }

后台成功输出的咱们的参数,成功接受!

SpringMVC如此智能,若是咱们去除@RequestParam注解,直接将两个值放入会有什么后果?

@RequestMapping("/jsontest")

    public void test(String username,String password){

        System.out.println("username: " + username);

        System.out.println("password: " + password);

    }

一样成功接收输出

SpringMVC提供了一个@RequestBody,它是用来处理前台定义发来的数据Content-Type: 不是application/x-www-form-urlencoded编码的内容,例如application/json, application/xml等; 

细心的朋友们或许发现了,在以前的Ajax中,咱们没有定义Content-type的类型,Jquery默认使用application/x-www-form-urlencoded类型。那么意思就是SpringMVC的@RequestParam注解,Servlet的request.getParameter是能够接受到以这种格式传输的JSON对象的。

 

为何呢!?GET请求想必你们都不陌生,它将参数以url?username=”admin”&password=123这种方式发送到服务器,而且request.getParameter能够接收到这种参数,咱们在浏览器地址栏上也能够看到这一点。而咱们Ajax使用的POST,而且发送的是JSON对象,那么后台是如何获取到的呢?答案就在于这个Content-Type x-www-form-urlencoded的编码方式把JSON数据转换成一个字串,(username=”admin”&password=123)而后把这个字串添加到url后面,用?分割,(是否是和GET方法很像),提交方式为POST时候,浏览器把数据封装到HTTP BODY中,而后发送到服务器。因此并不会显示在URL上。(这段可能有点绕口,但愿你们用心理解一下。) 

终于说完了,长吐一口气。因此说咱们使用@RequestBody注解的时候,前台的Content-Type必需要改成application/json,若是没有更改,前台会报错415(Unsupported Media Type)。后台日志就会报错Content type ‘application/x-www-form-urlencoded;charset=UTF-8’ not supported,这些错误Eclipse下Tomcat是不会显示错误信息的,只有使用了日志才会显示,如何配置日志你们能够看我上一篇文章。接下来咱们正确配置一下,上面说到了 Content-Type须要更改,同时咱们的data也要更改了,这种注解方式只接受JSON字符串而不是JSON对象

$.ajax({

                url : "jsontest",

                type : "POST",

                async : true,

                contentType : "application/json",

                data : JSON.stringify(json),

                dataType : 'json',

                success : function(data) {

                    if (data.userstatus === "success") {

                        $("#errorMsg").remove();

                    } else {

                        if ($("#errorMsg").length <= 0) {

                            $("form[name=loginForm]").append(errorMsg);

                        }

                    }

                }

            });

后台也更改一下,json其实能够理解为键值对嘛,因此咱们用Map接收,而后对字符串或者其余数据类型进行进一步处理。

    @RequestMapping("/jsontest")

    public void test(@RequestBody(required=true) Map<String,Object> map  ){

        String username = map.get("username").toString();

        String password = map.get("password").toString();

        System.out.println("username: " + username);

        System.out.println("password: " + password);

    }

同时,我又想起了神奇的SpringMVC,因此我决定去掉注解试试,好的,果断被爆了一个空指针错误…尝试就此打住。 
SpringMVC还提供了参数直接和POJO绑定的方法,咱们来尝试一下。前台同样,就不贴出来了。

@RequestMapping("/jsontest")

    public void test(@RequestBody User user  ){

        String username = user.getUsername();

        String password = user.getPassword();

        System.out.println("username: " + username);

        System.out.println("password: " + password);

    }

OK,此次是能够取到值的,我我的对于登陆这类小数据量的上传来讲不太喜欢这种方法,User里面的变量不少,我只用了其中两个,没有必要去建立一个User对象,通常数据量小的时候我仍是比较喜欢使用单独取值出来的。咱们再想想,若是是在上传JSON对象的状况下,咱们可不能够绑定POJO呢,答案是能够的,不要使用@RequestParam注解,不然会报Required User parameter 'user' is not present错误。到此讲解基本结束了,下面来总结一下。

当Ajax以application/x-www-form-urlencoded格式上传即便用JSON对象,后台须要使用@RequestParam 或者Servlet获取。 当Ajax以application/json格式上传即便用JSON字符串,后台须要使用@RquestBody获取

相关文章
相关标签/搜索