实体验证

时间:2018-12-01 19:06:12

标签: java spring hibernate spring-boot jpa

我有一个带有相应数据库表的实体类“用户”,该表包含许多字段(id,email,firstname,lastname,encryptedPassword,enabled,role)。 但是,如果管理员想在Web应用程序上添加新用户,则只需要填写表单中的某些字段(名字,姓氏,电子邮件)。其余字段由UserService填充。

当尝试使用控制器类中的BindingResult验证表单输入时,BindingResult包含错误,即id,encryptedPassword,enabled和role不能为null。所以我的问题是:在没有太多代码重复的情况下实现工作表格验证的最时髦的方法是什么?

UserEnitity:

@Data
@Entity
@Table(name = "user")
public class User {
    @Id
    @GeneratedValue
    @Column(name = "user_id")
    private Long id;

    @Size(max = 60)
    @NotNull
    @Column(name = "e_mail", unique = true)
    @Email
    private String email;

    @Size(max = 60)
    @NotNull
    @Column(name = "first_name")
    private String firstName;

    @Size(max = 60)
    @NotNull
    @Column(name = "last_name")
    private String lastName;

    @Size(max = 120)
    @NotNull
    @Column(name = "encrypted_password")
    private String encryptedPassword;

    @NotNull
    @Column(name = "enabled")
    private Boolean enabled;

    @ManyToOne
    @JoinColumn(name = "role_id", nullable = false)
    private Role role;
}

控制器:

@Controller
@RequestMapping("employees")
public class EmployeesController {

    private UserService userService;

    @Autowired
    public EmployeesController(UserService userService) {
        this.userService = userService;
    }

    @GetMapping("/add")
    public String getAddEmployeesPage(Model model){
        model.addAttribute("user", new User());
        return "employees/add";
    }

    @PostMapping("/add")
    public String postAddEmployeesPage(@ModelAttribute @Valid User user, BindingResult bindingResult){
        if(bindingResult.hasErrors()){
            return "employees/add";
        }

        userService.addUser(user);

        return "redirect:/employees/add/?successful=true";
    }
}

表格:

 <form action="#" th:action="@{/employees/add}" th:object="${user}" method="post">
                <div class="form-group">
                    <label th:text="#{employees.add.first_name}" for="first_name"></label>
                    <input th:placeholder="#{employees.add.first_name}" th:field="*{firstName}" type="text" class="form-control" id="first_name">
                    <p th:if="${#fields.hasErrors('firstName')}" th:errors="*{firstName}"></p>
                </div>
                <div class="form-group">
                    <label th:text="#{employees.add.last_name}" for="last_name"></label>
                    <input th:placeholder="#{employees.add.last_name}" th:field="*{lastName}" type="text" class="form-control" id="last_name">
                    <p th:if="${#fields.hasErrors('lastName')}" th:errors="*{lastName}"></p>
                </div>
                <div class="form-group">
                    <label th:text="#{employees.add.email}" for="email"></label>
                    <input th:placeholder="#{employees.add.email}" th:field="*{email}" type="email" class="form-control" id="email">
                    <p th:if="${#fields.hasErrors('email')}" th:errors="*{email}"></p>
                </div>
                <p><button th:text="#{button.submit}" type="submit" class="btn btn-primary"></button><button th:text="#{button.reset}" type="reset" class="btn btn-secondary"></button></p>
            </form>

1 个答案:

答案 0 :(得分:0)

尝试一下:

import javax.validation.Validator;
import javax.validation.ConstraintViolation;
@Controller
@RequestMapping("employees")
public class EmployeesController {

  private UserService userService;
  private Validator validator;

  @Autowired
  public EmployeesController(UserService userService, Validator validator) {
        this.userService = userService;
        this.validator = validator;
    }

  @GetMapping("/add")
  public String getAddEmployeesPage(Model model){
        model.addAttribute("user", new User());
        return "employees/add";
    }

  @PostMapping("/add")
  public String postAddEmployeesPage(@ModelAttribute @Valid User user, BindingResult bindingResult){
        if(bindingResult.hasErrors()){
            return "employees/add";
        }
        if(!validateUserForm(user)){
          return "some error message";
        }
        userService.addUser(user);

        return "redirect:/employees/add/?successful=true";
    }

  private boolean validateUserForm(User user){

     Set<ConstraintViolation<User>> violations = validator.validate(user);
     if (!violations.isEmpty()) {
       for (ConstraintViolation<User> violation : violations) {
        // log violation.getMessage();
      }
      return false;
    }
    return true;
}
    }

为控制器添加了一个私有方法,您可以调用该方法来根据您对实体bean的约束来验证对象。我建议将验证移到服务层。