我有一个SDR项目,我成功验证了POST请求的用户实体,但是一旦使用PATCH或PUT更新现有实体,DB就会在执行验证之前更新(验证器正在执行并出错返回,但数据库正在更新)。
我是否需要为更新设置单独的配置?我错过了额外的一步吗?
@Entity
@JsonIgnoreProperties(ignoreUnknown = true)
public class Member {
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "member_id_gen")
@SequenceGenerator(name = "member_id_gen", sequenceName = "member_id_seq")
@Id
@JsonIgnore
private long id;
@Version
private Integer version;
@NotNull
protected String firstName;
@NotNull
protected String lastName;
@Valid
protected String email;
}
@RepositoryRestResource(collectionResourceRel = "members", path = "member")
public interface MemberRepository extends PagingAndSortingRepository<Member, Long> {
public Member findByFirstName(String firstName);
public Member findByLastName(String lastName);
}
@Component
public class BeforeSaveMemberValidator implements Validator {
public BeforeSaveMemberValidator() {}
private String EMAIL_REGEX = "^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,6}$";
@Override
public boolean supports(Class<?> clazz) {
return Member.class.equals(clazz);
}
@Override
public void validate(Object target, Errors errors) {
Member member = (Member) target;
if(ObjectUtils.isEmpty(member.getFirstName())) {
errors.rejectValue("firstName", "member.firstName.empty");
}
if(ObjectUtils.isEmpty(member.getLastName())) {
errors.rejectValue("lastName", "member.lastName.empty");
}
if(!ObjectUtils.isEmpty(member.getDni()) && !member.getDni().matches("^[a-zA-Z0-9]*$")) {
errors.rejectValue("dni", "member.dni.invalid");
}
if(!ObjectUtils.isEmpty(member.getEmail()) && !member.getEmail().matches(EMAIL_REGEX)) {
errors.rejectValue("email", "member.email.notValid");
}
}
}
@Service
@RepositoryEventHandler(Member.class)
public class MemberService {
@HandleBeforeCreate
@HandleBeforeSave
@Transactional
public void beforeCreate(Member member) {
...
}
}
答案 0 :(得分:0)
我认为您应该将验证工具重命名为MemberValidator
,然后按照here所述进行分配:
@Override
protected void configureValidatingRepositoryEventListener(ValidatingRepositoryEventListener v) {
v.addValidator("beforeCreate", new MemberValidator());
v.addValidator("beforeSave", new MemberValidator());
}
但我建议您使用Bean validation代替自定义验证器。要在SDR项目中使用它,您可以注入LocalValidatorFactoryBean
,然后将其分配给configureValidatingRepositoryEventListener
中的'beforeCreate'和'beforeSave'事件:
@Configuration
@RequiredArgsConstructor // Lombok annotation
public class RepoRestConfig extends RepositoryRestConfigurerAdapter {
@NonNull private final LocalValidatorFactoryBean validatorFactoryBean;
@Override
public void configureValidatingRepositoryEventListener(ValidatingRepositoryEventListener v) {
v.addValidator("beforeCreate", validatorFactoryBean);
v.addValidator("beforeSave", validatorFactoryBean);
super.configureValidatingRepositoryEventListener(v);
}
}
在这种情况下,您的SDR将自动验证所有暴露的SDR存储库的POST,PUT和PATCH请求的有效负载。
有关详细信息,请参阅我的example。