Java中的参数验证方法
这篇文章主要讲解了“Java中的参数验证方法”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Java中的参数验证方法”吧!
10年积累的成都做网站、网站建设经验,可以快速应对客户对网站的新想法和需求。提供各种问题对应的解决方案。让选择我们的客户得到更好、更有力的网络服务。我虽然不认识你,你也不认识我。但先做网站设计后付款的网站建设流程,更有巴林右旗免费网站建设让你可以放心的选择与我们合作。
1. Java中的参数验证(非Spring版)
1.1. 前言
为什么我总遇到这种非正常问题,我们知道很多时候我们的参数校验都是放在controller层的传入参数进行校验,我们常用的校验方式就是引入下列的jar包,在参数中添加
@Validated
,并对Bean对象的参数做不同的注解处理就行,对Spring这种常用做法大家应该比较熟了但我现在遇到的需求,因为boss追求通用性,我们的controller入口只有一个,是通过传入参数中的不同tradeCode来区分调用哪个服务,这时我校验参数就得放到具体的每个服务方法上了,这样经过我的测试,加该注解已经不起作用了
javax.validation validation-api 1.1.0.Final
@PostMapping("/save/valid") public RspDTO save(@RequestBody @Validated UserDTO userDTO) { userService.save(userDTO); return RspDTO.success(); }
@Data public class UserDTO implements Serializable { private static final long serialVersionUID = 1L; /*** 用户ID*/ @NotNull(message = "用户id不能为空") private Long userId; /** 用户名*/ @NotBlank(message = "用户名不能为空") @Length(max = 20, message = "用户名不能超过20个字符") @Pattern(regexp = "^[\\u4E00-\\u9FA5A-Za-z0-9\\*]*$", message = "用户昵称限制:最多20字符,包含文字、字母和数字") private String username; /** 手机号*/ @NotBlank(message = "手机号不能为空") @Pattern(regexp = "^[1][3,4,5,6,7,8,9][0-9]{9}$", message = "手机号格式有误") private String mobile; /**性别*/ private String sex; /** 邮箱*/ @NotBlank(message = "联系邮箱不能为空") @Email(message = "邮箱格式不对") private String email; /** 密码*/ private String password; /*** 创建时间 */ @Future(message = "时间必须是将来时间") private Date createTime; }
1.2. 方案
不能用它的注解,但我们可以用它的方法,下面我写了一个用Java代码验证参数的例子,抛砖引玉,并不能直接用在自己的系统哦,想要使用请结合自己系统封装方法,我打算做成注解的形式,利用spring aop切我的服务层,实现的效果就和controller层类似了
1.2.1. 主方法
import org.springframework.validation.annotation.Validated; import javax.validation.ConstraintViolation; import javax.validation.Validation; import javax.validation.Validator; import javax.validation.ValidatorFactory; import java.util.Date; import java.util.Set; import java.util.stream.Stream; /** * @author laoliangliang * @date 2019/10/22 15:19 */ public class ValidLearn { public static void main(String[] args) { ValidLearn learn = new ValidLearn(); learn.testValid(new Order().setIdcard("33062119981012361X").setName(" ").setCreateDate(new Date())); } public void testValid(@Validated Order order) { ValidatorFactory validatorFactory = Validation.buildDefaultValidatorFactory(); Validator validator = validatorFactory.getValidator(); //分组Insert.class则id为空不检验 Set> validate = validator.validate(order, Insert.class); Stream.of(validate).forEach(action -> { for (ConstraintViolation orderConstraintViolation : action) { String message = orderConstraintViolation.getMessage(); System.out.println(message); } }); } }
1.2.2. 实体类
/** * @author laoliangliang * @date 2019/10/21 16:44 */ @Data @Accessors(chain = true) public class Order { @NotNull(message = "id不能为空",groups = Update.class) private Long id; @NotEmpty(message = "name is not null",groups = Insert.class) private String name; @Future(message = "必须之后的时间") private Date createDate; @IdCardValid(message = "idcard 不合法") private String idcard; }
以上两个代码就可以做到检验实体类对象注解,并打印校验不通过的消息了,可以改造成存在校验错误消息则抛出异常
代码还涉及了一些细节,比如group分组和自定义注解
1.2.3. group分组
import javax.validation.groups.Default; /** * @author laoliangliang * @date 2019/10/22 16:32 */ public interface Update extends Default { }
import javax.validation.groups.Default; /** * @author laoliangliang * @date 2019/10/22 16:32 */ public interface Insert extends Default { }
我例子代码中用到了
Insert.class
,表示做插入动作时,存在这个分组的注解才会起作用,因此我id不传,id不为空的注解也不会起作用
1.2.4. 自定义注解
import javax.validation.ConstraintValidator; import javax.validation.ConstraintValidatorContext; import java.util.regex.Matcher; import java.util.regex.Pattern; /** * @author laoliangliang * @date 2019/10/22 15:55 */ public class IdCardValidator implements ConstraintValidator{ private Pattern pattern = Pattern.compile("^[1-9]\\d{7}((0\\d)|(1[0-2]))(([0|1|2]\\d)|3[0-1])" + "\\d{3}$|^[1-9]\\d{5}[1-9]\\d{3}((0\\d)|(1[0-2]))(([0|1|2]\\d)|3[0-1])\\d{3}([0-9]|X)$"); @Override public void initialize(IdCardValid idCardValid) { } @Override public boolean isValid(Object o, ConstraintValidatorContext constraintValidatorContext) { Matcher matcher = pattern.matcher(o.toString()); return matcher.matches(); } }
/** * @author laoliangliang * @date 2019/10/22 15:53 */ @Documented @Target({ElementType.PARAMETER,ElementType.FIELD}) @Retention(RetentionPolicy.RUNTIME) @Constraint(validatedBy = IdCardValidator.class) public @interface IdCardValid { String message() default "身份证不合法"; Class>[] groups() default {}; Class extends Payload>[] payload() default {}; }
这里我以验证身份证号为例,写了个自定义注解,实现
ConstraintValidator
接口,在isValid
方法中实现自定义逻辑即可使用注解
1.3. 总结
此篇举了
Validation
用Java代码实现验证的例子,应对service层参数验证,实际应用到自己代码可以自己写个自定义注解,实现aop切面,在切面中进行验证
感谢各位的阅读,以上就是“Java中的参数验证方法”的内容了,经过本文的学习后,相信大家对Java中的参数验证方法这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是创新互联,小编将为大家推送更多相关知识点的文章,欢迎关注!
网站名称:Java中的参数验证方法
分享路径:http://myzitong.com/article/iegdsg.html