Q: 为什么后端需要校验,只交给前端校验行不行
A: 前后端都需要校验
后端校验防止请求过来的非法数据,对后端进行破坏

Java后端常用的校验框架

Apache commons-validator

  • http://commons.apache.org/ 这个地址apache提供了常用的工具类,包括校验框架
  • 提供了大量的校验器,如时间、数值、正则表达式、邮箱、URL等待

clipboard.png

  • 以IntegerValidator为例
IntegerValidator integerValidator = new IntegerValidator();
        
Integer value = integerValidator.validate("10");
System.out.println(value);
        
value = integerValidator.validate("G");
System.out.println(value);
/**
     * <p>Validate/convert an <code>Integer</code> using the default
     *    <code>Locale</code>.
     *
     * @param value The value validation is being performed on.
     * @return The parsed <code>Integer</code> if valid or <code>null</code>
     *  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}?
     * <p>This method is <i>typically</i> implemented like so:
     * <pre class="code">return Foo.class.isAssignableFrom(clazz);</pre>
     * (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}.
     * <p>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<? extends Payload>[] payload() default {};
}
package com.adagio.validator;

import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;

public class PersonNameConstraintValidator implements ConstraintValidator<PersonName, String>{

    /**
     * 获取并初始化注解信息
     */
    @Override
    public void initialize(PersonName constraintAnnotation) {
        
    }

    /**
     * 设置自定义校验规则
     */
    @Override
    public boolean isValid(String value, ConstraintValidatorContext context) {
        return false;
    }

}

person.name.not.null=人的姓名不能为空

参考:https://segmentfault.com/l/15...


麦冬
315 声望13 粉丝

越成熟的稻穗,越饱满厚实