SpringBoot开发详解(五)--Controller接收参数以及参数校验
原文链接:http://blog.csdn.net/qq_31001665
Controller 中注解使用
接受参数的几种传输方式以及几种注解:
在上一篇中,我们使用了JDBC链接数据库,完成了简单的后端开发。但正如我在上文中抛出的问题,我们能不能更好的优化我们在Controller中接受参数的方式呢?这一篇中我们就来聊一聊怎么更有效的接收Json参数。
传输参数的几种Method
在定义一个Rest接口时,我们通常会使用GET,POST,PUT,DELETE几种方式来完成我们所需要进行CRUD的一些操作,我们在这里罗列和教大家在实际开发中的使用,一些基本概念我们就不再赘述,例如使用POST的优缺点,可使用参数的大小限制等地:
-
GET:一般用于查询数据,不办函数据的更新以及插入操作。由于明文传输的关系,我们一般用来获取一些无关用户的信息。
-
POST:一般用于数据的插入操作,也是使用最多的传输方式,但是在H5调用时会有跨域的问题,一般使用JSONP来解决。
-
PUT:我们使用PUT方式来对数据进行更新操作。
-
DELETE:用于数据删除,注意在数据库内是逻辑删除(改变数据状态,用户不再查询得到,但还保留在数据库内)还是物理删除(真删了)。
以上是很标准的REST风格的接口形式,其实我们可以进源码看到,他们只不过封装了
@RequestMapping(
method = {RequestMethod.POST}
)
这个方法,和我们使用以前的@RequestMapping后写参数是一致的。但是在实际开发中我们一般是前后端分离开发的,像IOS以及ANDROID开发他们会固定使用同一套模版进行传输,这时可能你所有的接口都会是POST方法。这需要你在开发中事先和前端人员进行约定,这时接口文档就会变得非常重要了。方法,入参,出参,报错信息都必须清晰的描述在接口文档中,所以不要小看编写文档的能力哦。当然,SpringBoot也为我们提供了强大的API模版,例如swagger。不过使用swagger也不是一劳永逸的,关于swagger,我们之后再聊。
获取参数的几种常用注解
在上一篇中我们使用了几种注解来获取参数,例如@RequestParam,@PathVariable,@RequestBody。那我们现在来逐一看一下这些注解我们该如何使用。
-
@PathVariable:一般我们使用URI template样式映射使用,即url/{param}这种形式,也就是一般我们使用的GET,DELETE,PUT方法会使用到的,我们可以获取URL后所跟的参数。
-
@RequestParam:一般我们使用该注解来获取多个参数,在()内写入需要获取参数的参数名即可,一般在PUT,POST中比较常用。
-
@RequestBody:该注解和@RequestParam殊途同归,我们使用该注解将所有参数转换,在代码部分在一个个取出来,也是目前我使用到最多的注解来获取参数(因为前端不愿意一个一个接口的调试)例如下代码:
- @PostMapping("/createUserByMap")
- public void createUserByMap(@RequestBody Map<String,Object> reqMap){
- String tel = reqMap.get("tel").toString();
- String pwd = reqMap.get("pwd").toString();
- userService.createUser(tel,pwd);
- }
当然,我们获取参数不仅仅只有上面所提到的那些,还有@RequestHeader来获取头信息里的值,@CookieValue来获取Cookie值等等。在这,我也仅仅说明一些较常用的取值方法而已。
使用对象直接获取参数
当我们掌握以上几种方式来获取参数时,看似已经毫无问题,其实还是有的,如果我们的入参十分多呢?一百几十个参数,你是血一百几十个@RequestParam,还是@RequestBody之后取一百几十个次呢?,明显这些做法都十分麻烦,代码太多,关键是我们懒啊……所以,我们也可以通过POJO来直接获取参数,之后通过GET方法直接把需要的参数取出就好。
我们来将上一次的方法给改变下:
- /**
- * 添加用户2
- * @param userInfo
- */
- @PostMapping("/createUser2")
- public void createUser2(UserInfo userInfo){
- userService.createUser(userInfo.getTel(),userInfo.getPassWord());
- }
我们来测试一下,发现失败了,通过错误信息,我们发现SQL提示password为null,也就是说我们没有获取到pwd这个参数,这是因为如果使用对象接受参数,那参数名必须喝对象的属性名保持一致。
我们修改参数名为passWord后可以发现,数据可以争产的进行插入了。
使用@Valid对参数进行校验
在使用对象进行参数接收时,我们可以对参数进行校验,假设我们需要用户输入的密码是整数型且在000000至999999之间的数值,我们可以对属性passWord加上如下注解:
- @Max(value = 999999,message = "超过最大数值")
- @Min(value = 000000,message = "密码设定不正确")
- private String passWord;
这里举的列子并不十分合适,请注意。我们只是针对表单验证进行讲解,在实际开发处理中要选择合适的操作。message是反回的提示默认信息。
在controller中我们改写一下,将返回值设为String,让我们可以看到报错信息。
然后我们给对象加入@Valid注解,并在参数中加入BindingResult来获取错误信息。在逻辑处理中我们判断BindingResult知否含有错误信息,如果有错误信息,则直接返回错误信息。
- /**
- * 添加用户2
- * @param userInfo
- */
- @PostMapping("/createUser2")
- public String createUser2(@Valid UserInfo userInfo, BindingResult bindingResult){
- if (bindingResult.hasErrors()){
- return bindingResult.getFieldError().getDefaultMessage();
- }
- userService.createUser(userInfo.getTel(),userInfo.getPassWord());
- return "OK";
- }
我们继续通过POSTMAN来测试一下,首先我们传入-10000来设定密码,发现提示错误密码设定不正确:
发现无法完成用户注册,我们继续通过添加密码为1000000来设定密码,发现提示错误信息超过最大数值:
以上就是我们通过简单的表单验证来预防一些恶意数据的侵入。不知道你有没有掌握呢?当然,我们对于数据的验证不仅仅只有表单验证,我们一般通过数据签名的方式来验证一个请求是否合法,也可能是将整个参数进行对称加密后进行传输以保证数据不被明文抓包。
那以上所说的处理模式就会用到Spring为我们提供的另一个强大的功能,也是我们使用Spring系列框架中不可或缺的一部分,AOP,切面编程。我们之前所说的统一报错处理也是使用的AOP功能进行处理的,那关于AOP,我们下周再聊。(原谅我懒得要死,这篇文章也是被迫赶工的……捂脸,逃……)(◐‿◑)