【发布时间】:2016-01-08 23:32:29
【问题描述】:
我正在使用 Spring Boot Data REST 来持久化我的 User 实体
@Entity
public class User {
@Id
@GeneratedValue
private long id;
@NotEmpty
private String firstName;
@NotEmpty
private String lastName;
@NotEmpty
private String email;
@Size(min = 5, max = 20)
private String password;
// getters and setters
}
使用存储库:
public interface UserRepository extends CrudRepository<User, Long> {}
我要做的是首先验证POSTed 用户:
@Configuration
public class CustomRestConfiguration extends SpringBootRepositoryRestMvcConfiguration {
@Autowired
private Validator validator;
@Override
protected void configureValidatingRepositoryEventListener(ValidatingRepositoryEventListener validatingListener) {
validatingListener.addValidator("beforeCreate", validator);
}
}
只有在将用户密码存储到数据库之前对其进行哈希处理:
@Component
@RepositoryEventHandler(User.class)
public class UserRepositoryEventHandler {
private PasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
@HandleBeforeCreate
public void handleUserCreate(User user) {
user.setPassword(passwordEncoder.encode(user.getPassword()));
}
}
但事实证明,验证是在密码散列之后执行的,因此由于 散列 密码太长而失败。
有什么方法可以指示 Spring 先执行验证,然后才对密码进行哈希处理?我知道我可以自己编写一个控制器并以细粒度的方式指定所有内容,但我宁愿把它作为最后的手段。
【问题讨论】:
-
您使用的是什么版本的 Spring Boot/Data REST?我刚刚在我的应用程序上对此进行了测试,当我在 Repo 处理程序和
SizeValidatorForCharSequence中放置断点时,验证器中的那个在处理程序之前被命中,所以对我来说它按预期工作。我正在使用 Spring Boot 1.2.5 -
@BohuslavBurghardt 我在 Spring Boot
1.2.6.RELEASE上,它管理所有其他依赖版本。我真的不知道如何在验证器上放置一个断点,因为我自动装配了 JPA 创建的一个(我想)。它发生在幕后某处。不过会尝试这样做 -
@Wojtek,在 bean 验证成功后(在它持久化实体之前),我是否可以使用其他任何钩子来获得控制?
-
@masT 这不正是您需要的吗?它在验证之后和持久化之前被调用。还是您的意思是在 JPA 进行实体验证之后?我已经有一段时间没有使用 Spring 或 JPA 了,所以我真的无法回答你的问题。
-
@Wojtek,就我而言,这不是我需要执行的验证,而是为其他一些属性提供值(从另一个存储库中获取),因此寻找任何钩子验证后做这个处理。
标签: java spring validation spring-data-rest