验证控制器上的字段(作为请求主体),但不验证字段是否保存在数据库中

时间:2018-09-25 05:37:50

标签: java spring

我的Spring启动项目中有以下实体类:

@Entity
@Table(name="user_account_entity")
@JsonDeserialize(using = UserAccountDeserializer.class)
public class UserAccountEntity implements UserDetails {

    private final static String ROLE_USER  = "ROLE_USER";

    @Id
    @NotBlank
    private String id;

    @NotBlank(message="Username cannot be empty")
    @Email(message="Username must be a valid email address")
    private String username;

    @NotBlank(message="Password cannot be empty")
    @Password
    private String password;

    @NotNull
    @MapsId
    @OneToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
    private UserEntity user;

    public UserAccountEntity(final String username, final String password) {
        this.password = password.trim();
        this.username = username.trim();
    }

    public UserAccountEntity() {}
    //setters and getters

}

和以下控制器:

@RequestMapping("/api/authentication")
public class UserAccountControllerImpl implements UserAccountController {

    @Autowired
    private UserAccountService userAccountService;
    @Autowired
    private PasswordEncoder passwordEncoder;

    @Override
    public String create(@RequestBody UserAccountEntity userAccount,
            HttpServletResponse response) {
        String username = userAccount.getUsername();
        String password = userAccount.getPassword();
        UserEntity user = new UserEntity();
        UserAccountEntity userAccount = new UserAccountEntity(username,
                    passwordEncoder.encode(password));
        userAccount.setUser(user);
        userAccountRepository.save(userAccount);
        return userAccountService.authenticateUserAndSetResponsenHeader(
                username, password, response);
    }
}

如您所见,我为字段password有一个自定义验证器:

public class PasswordValidator implements ConstraintValidator<Password, String> {
    public void initialize(Password constraintAnnotation) {}

    public boolean isValid(String value, ConstraintValidatorContext context) {
        String trimmedValue = value.trim();
        if (trimmedValue.length() > 30 || trimmedValue.length() < 8) {
            return false;
        }
        if (!Pattern.compile( "[0-9]" ).matcher(trimmedValue).find()) { // it doesn't contain any digit
            return false;
        }
        if (trimmedValue.toUpperCase().equals(trimmedValue)) { //it's all upper-case
            return false;
        }
        if (trimmedValue.toLowerCase().equals(trimmedValue)) { //it's all lower-case
            return false;
        }
        return true;
    }
}

如何在控制器的请求正文中验证password字段,但是在保存时如何验证呢?当我在保存时对该字段进行编码时,保存时验证不会通过。

1 个答案:

答案 0 :(得分:1)

第一步是在请求正文上使用@Valid。因此,新的代码更改如下所示:

@Override
public String create (@Valid @RequestBody UserAccountEntity userAccount,
        HttpServletResponse response) {
    ...
}

此后,您可以使用InitBinder绑定您的自定义验证器:

@InitBinder
public void binder(WebDataBinder binder) {
    binder.addValidator(new PasswordValidator());
}

请注意,标记为@InitBinder的方法是您的Controller类的一部分。