来源:springboot书上看到的例子(《springboot实战派》),之前不会,记录下
1.创建个需要验证的实体类
import lombok.Data;
import org.hibernate.validator.constraints.Length;
import javax.validation.constraints.Email;
import javax.validation.constraints.Max;
import javax.validation.constraints.Min;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import java.io.Serializable;
@Data
public class User implements Serializable {
private Long id;
@NotBlank(message = "用户名不能为空")
@Length(min = 5, max = 20, message = "用户名长度为5-20个字符")
private String username;
@NotNull(message = "年龄不能为空")
@Min(value = 18, message = "最小18岁")
@Max(value = 60, message = "最大60岁")
private Integer age;
@Email(message = "请输入正确的邮箱")
@NotBlank(message = "邮箱不能为空")
private String email;
@MyConstraint
private String answer;
}
这里主要用的是hibernate.validator这个内置校验器,这个校验器看了下,能满足大多需求,新需求就自己开发->@MyConstraint 这个验证的简单开发实例
2.自定义验证业务逻辑的实现类:
import com.example.demo.MyConstraint;
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
public class MyConstraintValidator implements ConstraintValidator<MyConstraint, String> {
//String是校验的类型
@Override
public void initialize(MyConstraint constraint) {
// 启动时执行
}
@Override
public boolean isValid(String s, ConstraintValidatorContext context) {
if (!(s.equals("北京") || s.equals("上海"))) {
return false;
}
return true;
}
}
实现ConstraintValidator这个接口,重写isValid这个方法,上面的那个方法重写还没研究,先重写下验证方法,就判断输入的是不是这俩就行,不是就返回错误信息,错误信息放下面这个类
3.自定义注解类
import com.example.MyConstraintValidator;
import javax.validation.Constraint;
import javax.validation.Payload;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
//用于指定使用范围,该处限定只能在字段上使用
@Target({ElementType.FIELD})
//表示注解在运行时可以通过反射获取到
@Retention(RetentionPolicy.RUNTIME)
//@Constraint注解,里面传入了一个validatedBy的字段,指定该注解校验逻辑
@Constraint(validatedBy = MyConstraintValidator.class)
public @interface MyConstraint {
/**
* @Description: 错误提示
*/
String message() default "请输入中国政治或者经济中心的城市名称";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}
两个必须要添加的,不加看网上很多老哥都因为这个报错
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
完事就能用自己的注解了
就开头加在answer那的那个
@MyConstraint
private String answer;
是哈效果,
4.controller
@Controller
public class TestValidatorController {
@GetMapping("/test")
public String showFrom(User user) {
return "form";
}
@GetMapping("/results")
public String results() {
return "results";
}
@PostMapping("/test")
public String checkUser(@Valid User user, BindingResult bindingResult, RedirectAttributes attr) {
// 特别注意实体中的属性必须都验证过了,不然不会成功
if (bindingResult.hasErrors()) {
return "form";
}
/*
* @Description:
* 1.使用RedirectAttributes的addAttribute方法传递参数会跟随在URL后面 ,如上代码即为?name=long&age=45
* 2.使用addFlashAttribute不会跟随在URL后面,会把该参数值暂时保存于session,待重定向url获取该参数后从session中移除,
* 这里的redirect必须是方法映射路径。redirect后的值只会出现一次,刷新后不会出现了,对于重复提交可以使用此来完成。
*/
attr.addFlashAttribute("user", user);
return "redirect:/results";
}
}
5.使用thymeleaf 的html
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<body>
<style type="text/css">
.warn{color: #ff0000
}
</style>
<form th:action="@{/test}" th:object="${user}" method="post">
<div>
<div>
<span>姓名:</span>
<span><input type="text" th:field="*{username}"/></span>
<span class="warn" th:if="${#fields.hasErrors('username')}" th:errors="*{username}">名字错误</span>
</div>
<div>
<span>年龄:</span>
<span><input type="number" th:field="*{age}"/></span>
<span class="warn" th:if="${#fields.hasErrors('age')}" th:errors="*{age}">年龄错误</span>
</div>
<div>
<span>邮箱:</span>
<span><input TYPE="text" th:field="*{email}"/></span>
<span class="warn" th:if="${#fields.hasErrors('email')}" th:errors="*{email}">邮箱错误</span>
</div>
<div>
<span>验证答案:</span>
<span><input TYPE="text" th:field="*{answer}"/></span>
<span class="warn" th:if="${#fields.hasErrors('answer')}" th:errors="*{answer}">答案错误</span>
</div>
<div>
<span>
<button type="submit">提交</button>
</span>
</div>
</div>
</form>
</body>
</html>
result.html
<html>
<body>
<div th:each="user: ${user}">
恭喜您,<span th:text="${user.username}">名字</span>(先生/女士),数据提交成功!
<div>您的年龄是:
<span th:text="${user.age}"></span></div>
<div> 您的邮箱是:
<span th:text="${user.email}"></span>
</div>
</div>
</body>
</html>
效果如下