Q: 为什么后端需要校验,只交给前端校验行不行
A: 前后端都需要校验后端校验防止请求过来的非法数据,对后端进行破坏
Java后端常用的校验框架
Apache commons-validator
- 这个地址apache提供了常用的工具类,包括校验框架
- 提供了大量的校验器,如时间、数值、正则表达式、邮箱、URL等待
- 以IntegerValidator为例
IntegerValidator integerValidator = new IntegerValidator(); Integer value = integerValidator.validate("10");System.out.println(value); value = integerValidator.validate("G");System.out.println(value);
/** *Validate/convert an
Integer
using the default *Locale
. * * @param value The value validation is being performed on. * @return The parsedInteger
if valid ornull
* if invalid. */ public Integer validate(String value) { return (Integer)parse(value, (String)null, (Locale)null); }
- 在校验传入的参数时,当能够解析成Integer类型就返回这个数字,如果不能就返回null
- 其它数值类型校验类似
Spring Validator
- Spring框架提供的用于校验对象的Validator接口,在校验过程中与Errors对象配合。校验器可以通过Errors对象报告校验失败的信息
- org.springframework.validation.Validator接口定义
public interface Validator { /** * Can this {@link Validator} {@link #validate(Object, Errors) validate} * instances of the supplied {@code clazz}? *This method is typically implemented like so: *
return Foo.class.isAssignableFrom(clazz);* (Where {@code Foo} is the class (or superclass) of the actual * object instance that is to be {@link #validate(Object, Errors) validated}.) * @param clazz the {@link Class} that this {@link Validator} is * being asked if it can {@link #validate(Object, Errors) validate} * @return {@code true} if this {@link Validator} can indeed * {@link #validate(Object, Errors) validate} instances of the * supplied {@code clazz} */ boolean supports(Class clazz); /** * Validate the supplied {@code target} object, which must be * of a {@link Class} for which the {@link #supports(Class)} method * typically has (or would) return {@code true}. *The supplied {@link Errors errors} instance can be used to report * any resulting validation errors. * @param target the object that is to be validated (can be {@code null}) * @param errors contextual state about the validation process (never {@code null}) * @see ValidationUtils */ void validate(Object target, Errors errors);
- 示例如下,可以使用POSTMAN等工具测试
package com.adagio.domain;import javax.validation.constraints.Max;import javax.validation.constraints.Min;import javax.validation.constraints.NotNull;public class Person { @NotNull private String name; @Min(0) @Max(150) private int age; public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } }
package com.adagio.validator;import org.springframework.util.StringUtils;import org.springframework.validation.Errors;import org.springframework.validation.Validator;import com.adagio.domain.Person;public class PersonValidator implements Validator { @Override public boolean supports(Class clazz) { return Person.class.isAssignableFrom(clazz); } @Override public void validate(Object target, Errors errors) { Person person = Person.class.cast(target); String name = person.getName(); if(!StringUtils.hasLength(name)){ errors.reject("person.name.not.null", "用户名不能为空"); } }}
package com.adagio.controller;import javax.validation.Valid;import org.springframework.stereotype.Controller;import org.springframework.web.bind.annotation.PostMapping;import org.springframework.web.bind.annotation.RequestBody;import com.adagio.domain.Person;@Controller public class PersonController { @PostMapping("/person/save") public Person save(@Valid @RequestBody Person person){ return person; }}
Bean Validation 1.0(JSR-303)
- 常用注解:@Valid、@NotNull、@Null、@Size、@Min、@Max
- 也可以自定义注解及其校验规则
package com.adagio.validator;import static java.lang.annotation.ElementType.FIELD;import static java.lang.annotation.ElementType.METHOD;import static java.lang.annotation.RetentionPolicy.RUNTIME;import java.lang.annotation.Documented;import java.lang.annotation.Retention;import java.lang.annotation.Target;import javax.validation.Constraint;import javax.validation.Payload;@Target({METHOD, FIELD})@Retention(RUNTIME)@Documented@Constraint(validatedBy = {PersonNameConstraintValidator.class})public @interface PersonName { String message() default "{person.name.not.null}"; Class [] groups() default {}; Class [] payload() default {};}
package com.adagio.validator;import javax.validation.ConstraintValidator;import javax.validation.ConstraintValidatorContext;public class PersonNameConstraintValidator implements ConstraintValidator{ /** * 获取并初始化注解信息 */ @Override public void initialize(PersonName constraintAnnotation) { } /** * 设置自定义校验规则 */ @Override public boolean isValid(String value, ConstraintValidatorContext context) { return false; }}
person.name.not.null=人的姓名不能为空
参考: