数据库更新后运行的PUT和PATCH的Spring数据休息验证

时间:2017-10-29 11:32:28

标签: java spring hibernate spring-boot spring-data-rest

我有一个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");
        }
    }
}

BeforeSave服务

@Service
@RepositoryEventHandler(Member.class)
public class MemberService {

    @HandleBeforeCreate
    @HandleBeforeSave
    @Transactional
    public void beforeCreate(Member member) {
        ...
    }

}

1 个答案:

答案 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