【你不知道的那些事】SpringMVC之请求参数获取

正文:

我们为什么要对请求参数进行获取呢?(黑人问号脸)

答:我们可以通过获取用户发送的请求,携带特定的参数,我们后台能够根据用户传送过来的参数,返回用户需要的数据。用户有需要我们作为一个合格的程序员,怎么能不给呢是吧。

那我们怎么对参数进行获取呢?

在获取参数之前,我们需要对请求类型进行说明。众所周知,我们常用的请求方式有:GET、POST、PUT等,结果看了请求方式枚举类的源码之后

public enum RequestMethod {
    GET,
    HEAD,
    POST,
    PUT,
    PATCH,
    DELETE,
    OPTIONS,
    TRACE;

    private RequestMethod() {
    }
}

还有这么多请求方式(我居然不知道),赶紧补一补,这时候就找到了另外一个老哥博客,他里面讲的很详细,也很全面,这里我就不过多赘述了,直接送上传送门:传送门 。

我们继续品一品SpringMVC,它猜到了我们这些需求,已经给我们开发好了相应的注解,我们只需要去使用就可以了,哎真香。

@GetMapping()

这个注解很好懂吧,get关键字(划重点,考试要考)用来接收Get请求,括号内填写请求的路径常用的写法是

@GetMapping(path = "子路径")

@GetMapping(value = “子路径”)

这里我要告诉大家一个更常用的写法,那就是直接写请求路径

@GetMapping(“子路径”) 例如@GetMapping(“hello”)(一般人我不告诉他)

有了Get肯定少不了Post啊,也就有了接下来这个注解的登场

@PostMapping() 

@PostMapping的用法和@GetMapping的用法类似,它是用来接收Post请求的。

有了Get和Post当然也有响应的PutMapping等等,这里就不一一讲解,讲一些比较常用的,然后举一反三。接下来还有我们的终极大boss登场:

@RequestMapping() 

为什么说他是终极大boss呢,是因为他包含了上述的所有注解,而且还经常在类上出现,作为父路径,当然也可以在方法上出现,作为子路径。他也有上面的path,value,以及省略这三种写法,而且在括号内规定请求的方式,写法如下

@RequestMapping(method = RequestMethod.GET)

这里有两个注意的点,第一个是,如果在没有写method属性值得时候,系统会默认接收所有的请求,GetMapping那些只能够接收特定的请求,而第二个就是在没有其他属性时,我们可以直接写@RequestMapping(“hello”)没有问题,那看看下面这种写法,有没有问题呢?(不要偷看答案哦)

@RequestMapping("hello", method = RequestMethod.GET)

答案是错误的,在有多个属性之后value就不能省略了,正确写法应该是:

@RequestMapping(value = "hello", method = RequestMethod.GET) 

你们答对了么?

总结一下:常用的请求方式用到了一下三个注解

@GetMapping()

@PostMapping()

@RequestMapping()

括号内的属性有:

path或value: 规定了请求的路径(只有一个路径属性时可以不填)

method:(只有@RequestMapping()注解才有该属性)规定了请求的类型,在没有指定的情况下接收所有请求

到这里请求的方式就差不多了,接下来就可以进入请求参数的获取了。

回想亿下在jsp及servlet中我们需要通过request.getParameter();request.getAttribute();这两种方式获取请求参数,而SpringMVC只需要通过注解,就能够获取相应的数据,还能够获取对象的数据。

我:哇,还能获取对象的信息?

SpringMVC:没问题。

我:我...我对象在哪我都不知道,你还能知道?

SpringMVC:没问题。你只要把数据交给我,我用一个注解就给你安排的明明白白。

我:。。。哦

相声说完,我们聊正事,一般我们发送请求携带参数无非就两种,一种直接将参数拼接到url中以键值对的形式(key-value),另一种放在表单域中进行提交,第二种在表单域中提交又可以分为两种:一种是通过键值对的形式(key-value),一种是通过json格式。

而对于获取数据来说可以简单分为两种一种是json格式,另一种是非json格式。对于两种获取方式也就分出了两个注解:

@RequestParam()

上面注解,是用于获取非json格式的参数。使用情景如下:

在jsp页面中:

<form action="hello">
    用户名:<input type="text" name="name"> <br>
    <input type="submit" value="提交" > <br>
</form>

在controller里:

@RequestMapping(value = "hello")
public String sayHello(@RequestParam(value = "name") String name) {
 	//业务逻辑代码	   
}

这时候有聪明的小伙伴要问了,那么value=“name”是不是可以省略呢。哎,没错可以省略。那么省略和不省略的区别又是什么呢?来听我慢慢道来:先上代码,再解释一波

在jsp页面中:

<form action="hello">
    用户名:<input type="text" name="uname"> <br>
    <input type="submit" value="提交" > <br>
</form>

在controller里:

@RequestMapping(value = "hello")
    public String sayHello(@RequestParam(value = "uname") String name) {
 	//业务逻辑代码	   
}

这时候有小伙伴可能要来了,博zhu,你是在逗我么,这不是和上面的一模一样的么?哎,小伙伴你使用你的火眼金睛细细品一品,是不是有点不一样呢?第一段代码jsp界面传过来的是name后台使用name接收可也省略,而第二段代码jsp界面传过来的是uname后台使用name接收,所以value = "uname"就不能省略了。

这时候我又要说一个一般人我不告诉他的密密了,其实@RequestParam(value = "name") 都可以省略。但是这个省略和不省略就有点区别了。我们跟随到@RequestParam注解的源码中。

public @interface RequestParam {
    @AliasFor("name")
    String value() default "";

    @AliasFor("value")
    String name() default "";

    boolean required() default true;

    String defaultValue() default "\n\t\t\n\t\t\n\ue000\ue001\ue002\n\t\t\t\t\n";
}

这里面有这么一段 boolean required() default true; required默认为true?这就是声明这个字段是必须填写的,我们可以配合上html中标签内属性required一起使用,也就是

<input type="text" name="name" required>

在写上了@RequestParam(value = "name") 注解而前端代码又没有响应数据的时候就会报错,而不写RequestParam(value = "name") 注解的会默认给个null值。

这时候又有聪明的小伙伴发现了,那内个defaultValue又是个啥子列?这个呀是给我们的参数一个默认值,这个是要在required=false时才会生效。那后面一长串

default "\n\t\t\n\t\t\n\ue000\ue001\ue002\n\t\t\t\t\n"

又是啥?其实这一长串也就是作为spring框架中的null,你可以去试试去在idea中点开这个注解,然后复制引号中的内容,到百度搜索框中看看是啥你就明白了。不要问我为什么知道,问就是百度。

这个defaultValue在开发中经常能在分页中见到,写法大概是

@RequestParam(value = "page", required = false, defaultValue = "1") int page

如果没有用过这个的小伙伴不用着急,先混个眼熟。知道有这么个东西。以后再某个场景需要用到分页,哎呦,好像在某位博zhu上看到过这个。对,要的就是这种感觉。

讲了这么多要接下来学习就会轻松很多了,下面我们在讲一下如何获取一个对象。使用场景:

<form action="hello">
    用户名:<input type="text" name="name" required> <br>
    年龄:<input type="number" name="age"> <br>
    住址:<input type="text" name="address"> <br>
    ...
    <input type="submit" value="提交" > <br>
</form>

随着页面逐渐丰富的时候,我们是不是还要去一条一条的获取,就像。。。

public String sayHello(@RequestParam(value = "name", required = true) String name,
                       @RequestParam(value = "age", required = false, defaultValue = "20") int age,
                       @RequestParam(value = "address", required = false, defaultValue = "") String address)

当然也不是完全没有可能,这是要分场景的(这是后话)。但是我们学习就要全面嘛,我们也可以通过一个简单的将用户封装成一个User对象

public class User {
    private String name;
    private int age;
    private String address;
    
    ...省略set和get方法
}

SpringMVC就能够将我们的数据自动封装到我们的User对象中,当然自动也是有前提条件的,也就是我们的字段名要对应得上,他才能够自动封装。

到这里非json格式的数据获取也就差不多结束了,接下来就是json格式的获取。我们想象有这么个场景:我们页面通过异步请求发一个json格式的请求给后台,后台获取到数据后对请求进行相应,接下来我们就要来完成这么个操作。

jsp页面:(这里需要引入jq的脚本)

<script type="text/javascript">  
    $(function(){   
        $("#testJson").click(function(){    
            $.ajax({     
                type:"post",
                url:"${pageContext.request.contextPath}/helloJson",     
                contentType:"application/json;charset=utf-8",
                data:'{"name":"genjoyh","age":"20","address":"guangdong"}',     
                dataType:"json"  
            });  
        }); 
    }) </script>
<!-- 发送异步请求 --> 
<input type="button" value="testJson" id="testJson"/>

controller中:

@RequestMapping(value = "helloJson")
public String sayHello(@RequestBody User user)

这里使用了@RequestBody对json格式的请求数据进行获取。

还有第三种:获取占位符参数

页面发送请求,请求路径如下:

localhost:8080/hello/1

到了后台之后,使用到@PathVariable注解,可以通过如下代码获取:

@RequestMapping(value = "hello/{id}")
public String sayHello(@PathVariable("id") int id)

总结一下:我们使用了3个SpringMVC获取请求参数的注解

@RequestParam:获取非json格式的数据

@RequestBody:获取json格式的数据

@PathVariable:获取占位符参数

这里还有第四种获取请求数据的方式:

@RequestMapping(value = "hello")
public String sayHello(HttpServletRequest request, HttpServletResponse response)

这里直接就可以获取到request和response对象,然后就可以玩servlet那一套。

点关注,不迷路

如果你觉得好看,对你有帮助,请给博zhu点点大拇指。你的支持是对我最大的肯定,也是我不懈努力的动力。

感觉我还有什么地方写的不足,需要修改的地方,请在评论区留言。点点关注,即可提高学习效率,让我们一起努力!