服务端通常将controller层
作为调用的第一层,因而参数校验常常在这里完成,比如非空校验、类型校验等,如下登录接口代码所示:
/** * 登录接口 * * @author 念兮为美 * @datetime 2022/8/11:13:41 */ @PostMapping("/login") public JSONObject login(@RequestBody UserLoginDto userLogin) { String password = userLogin.getPassword(); JSONObject jsonObject=new JSONObject(); if (null == password || "".equals(password)) { jsonObject.put("success",false); jsonObject.put("message","密码不能为空"); return jsonObject; } ... }
假如在controller层
的某个方法中,有很多个需要校验的请求参数,这样写无疑会有多条if判断语句
,因而,我们需要使用优雅的方式处理接口请求参数。
前提是需要在pom
文件中增加如下依赖:
<dependency> <groupId>javax</groupId> <artifactId>javaee-api</artifactId> <version>8.0.1</version> </dependency>
依赖配置好后,编写需要注解的bean,如下代码所示:
package com.superjson.superjsonmanager.dto; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; import javax.validation.constraints.NotBlank; /** * @author 念兮为美 * @datetime 2022/8/5 21:34 * @desc 用户登录请求参数 */ @AllArgsConstructor @NoArgsConstructor @Data public class UserLoginDto { /** 密码 */ @NotBlank(message = "密码不能为空") private String password; /** 类型 */ @NotBlank(message = "登录类型不能为空") private String type; /** 用户名 */ @NotBlank(message = "账号不能为空") private String username; }
我们常用的注解有@NotBlank 、@NotEmpty、@NotNull
等,当然,我们也有可能用到其他注解来检查属性。
注解 | 说明 |
---|---|
@Null | 检查对象是否为null。 |
@NotNull | 检查对象是否不为null,无法查检长度为0的字符串。 |
@NotBlank | 检查约束字符串是不是Null还有被Trim的长度是否大于0,只对字符串,且会去掉前后空格。 |
@NotEmpty | 检查约束元素是否为NULL或者是EMPTY。 |
注解 | 说明 |
---|---|
@AssertTrue | 检查 Boolean 对象是否为 true。 |
@AssertFalse | 检查 Boolean 对象是否为 false。 |
注解 | 说明 |
---|---|
@Size(min=, max=) | 检查对象(Array,Collection,Map,String) 长度是否在给定的范围之内 。 |
@Length(min=, max=) | 检查字符串(String) 长度是否在给定的范围之内。 |
注解 | 说明 |
---|---|
@Past | 检查Date 和Calendar 对象是否在当前时间之前 。 |
@Future | 检查Date 和Calendar 对象是否在当前时间之后 。 |
@Pattern | 检查String 对象是否符合正则表达式的规则。 |
建议在Stirng和Integer类型
使用,不建议在int类型
上使用。因为表单值为“”
时无法转换为int,但可以转换为Stirng为"",Integer为null。
注解 | 说明 |
---|---|
@Min | 检查 Number 和 String 对象是否大等于指定的值 。 |
@Max | 检查 Number 和 String 对象是否小等于指定的值 。 |
@DecimalMax | 被标注的值必须不大于约束中指定的最大值。 这个约束的参数是一个通过BigDecimal 定义的最大值的字符串表示.小数存在精度。 |
@DecimalMin | 被标注的值必须不小于约束中指定的最小值.。这个约束的参数是一个通过BigDecimal 定义的最小值的字符串表示.小数存在精度。 |
@Digits | 检查 Number 和 String 的构成是否合法 。 |
@Digits(integer=,fraction=) | 检查字符串是否是符合指定格式的数字,interger指定整数精度,fraction指定小数精度。 |
@Range(min=, max=) | 检查数字是否介于min和max之间。 |
我们在bean中通过注解定义好类之后,需要在controller层加上@Validated
和BindingResult
参数,如下代码所示:
package com.superjson.superjsonmanager.controller; import com.alibaba.fastjson.JSONObject; import com.superjson.superjsonmanager.dto.UserLoginDto; import com.superjson.superjsonmanager.service.UserService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.validation.BindingResult; import org.springframework.validation.FieldError; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; /** * @author 念兮为美 * @datetime 2022/8/5 21:30 * @desc 用户登录控制器 */ @RestController @RequestMapping("/user") public class UserController { @Autowired private UserService userService; @PostMapping("/login") public JSONObject login( @Validated @RequestBody UserLoginDto userLogin, BindingResult bindingResult) { if (bindingResult.hasErrors()) { JSONObject jsonObject = new JSONObject(); FieldError fieldError = bindingResult.getFieldError(); //获取出错的属性 jsonObject.put("field", fieldError.getField()); //获取出错的注解名字,比如notBlank,notNull等 jsonObject.put("code", fieldError.getCode()); //获取出错的对象名称 jsonObject.put("objectName", fieldError.getObjectName()); //获取错误的信息 jsonObject.put("message", fieldError.getDefaultMessage()); throw new 你自定义的异常("参数请求异常:" + fieldError.getDefaultMessage()); } return userService.getByUsernameAndPassword( userLogin.getUsername(), userLogin.getPassword(), userLogin.getType()); } }
@Valid 和 @Validated 两者都可以对数据进行校验,待校验字段上打的规则注解(@NotNull, @NotEmpty等)都可以对 @Valid 和 @Validated 生效;
@Valid 进行校验的时候,需要用 BindingResult 来做一个校验结果接收。当校验不通过的时候,如果手动不 return ,则并不会阻止程序的执行;
@Validated 进行校验的时候,当校验不通过的时候,程序会抛出400异常,阻止方法中的代码执行,这时需要再写一个全局校验异常捕获处理类,然后返回校验提示。
总体来说,@Validated 使用起来要比 @Valid 方便一些,它可以帮我们节省一定的代码,并且使得方法看上去更加的简洁。
在如上postman中,password和username都为空,按道理说,应该是报错的,但执行后并没有报错,如下图所示:
根据上述3. 编写需要注解的bean
可以看到,password和username都不为空,实际上应该有两个error,但现在是0 error
,就不正常。
实际上,我们少引用hibernate-validator
这个依赖,只需要增加如下依赖即可:
<dependency> <groupId>org.hibernate.validator</groupId> <artifactId>hibernate-validator</artifactId> <version>6.2.3.Final</version> </dependency>
增加如下依赖之后,重启服务后运行。不仅能让@NotBlank
注解生效,也可以让@NotBlank
等注解生效,如下图所示:
注解 | 说明 |
---|---|
@Valid | 递归的对关联对象进行校验, 如果关联对象是个集合或者数组,那么对其中的元素进行递归校验,如果是一个map,则对其中的值部分进行校验.(是否进行递归验证)。 |
@CreditCardNumber | 信用卡验证。 |
验证是否是邮件地址,如果为null,不进行验证,算通过验证。 | |
@ScriptAssert(lang= ,script=, alias=) | 检查脚本语言是否符合预期 |
@URL(protocol=,host=, port=,regexp=, flags=) | 检查URL是否符合预期 |
这一次的节点更新覆盖了加拿大、香港、日本、美国、新加坡、欧洲、韩国等地区,最高速度可达20 M/S。只需复制下方的Clash/v2ray订阅链接,在客户端添加后即可正常使用。
摘要: 本篇文章给大家谈谈通州区宠物店,以及通州区宠物店电话对应的知识点,希望对各位有所帮助,不要忘了收藏本站喔。本文目录一览:1、宠物驯导师的职业概况2、... 本篇文章给
摘要: 大家好,今天小编关注到一个比较有意思的话题,就是关于长沙宠物领养贴吧的问题,于是小编就整理了4个相关介绍长沙宠物领养贴吧的解答,让我们一起看看吧。请问长沙有没有收留藏獒的地方?长沙
概述: 出现空指针异常,常常是因为我们调用的对象是空的而抛出的异常。 问题描述: 第一种: out.println(request.getParameter("username")); 如果r
这一次的节点更新覆盖了新加坡、香港、日本、欧洲、加拿大、韩国、美国等地区,最高速度可达21 M/S。只需复制下方的Clash/v2ray订阅链接,在客户端添加后即可正常使用。
摘要: 本篇文章给大家谈谈十大冷门暴利生意(最挣钱没人干的行业有哪些?),以及冷门生意有哪些十大冷门生意利润高对应的知识点,希望对各位有所帮助,不要忘了收藏本站喔。本文目录一览:1、有..
这一次的节点更新覆盖了香港、新加坡、韩国、欧洲、日本、美国、加拿大等地区,最高速度可达20.9 M/S。只需复制下方的Clash/v2ray订阅链接,在客户端添加后即可正常使用。
1.报错了。。。 You may use special comments to disable some warnings. Use // eslint-disable-next-line to i
摘要: 本篇文章给大家谈谈违约养宠物还能退押金吗怎么处理,以及宠物店押金不退可以报警吗对应的知识点,希望对各位有所帮助,不要忘了收藏本站喔。本文目录一览:1、领养宠物押金一年返还套路怎..
摘要: 大家好,今天小编关注到一个比较有意思的话题,就是关于宠物领养协议书范本最新版下载的问题,于是小编就整理了4个相关介绍宠物领养协议书范本最新版下载的解答,让我们一起看看吧。宠物领养平