Q: 为什么后端需要校验,只交给前端校验行不行
A: 前后端都需要校验
后端校验防止请求过来的非法数据,对后端进行破坏
Java后端常用的校验框架
Apache commons-validator
- http://commons.apache.org/ 这个地址apache提供了常用的工具类,包括校验框架
- 提供了大量的校验器,如时间、数值、正则表达式、邮箱、URL等待
- 以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=人的姓名不能为空
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。