【问题标题】:Form validation with entities使用实体进行表单验证
【发布时间】:2018-12-01 19:06:11
【问题描述】:

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

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

用户实体:

@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>

【问题讨论】:

  • 您可能应该使用 DTO,但您正在寻找的是 验证组

标签: java spring hibernate spring-boot jpa


【解决方案1】:

试试这个:

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 的约束来验证您的对象。我建议将此验证移至服务层。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多