0

注釈を使用して、REST Bean に追加の検証ロジックを追加しようとしています。これは一例ですが、ポイントは複数の REST リソース オブジェクト/DTO でアノテーションを使用することです。

私は次のような解決策を望んでいました:

public class Entity {

    @NotNull // JSR-303
    private String name;

    @Phone // Custom phonenumber that has to exist in a database
    private String phoneNumber;
}

@Component
public class PhoneNumberValidator implements Validator { // Spring Validator

    @Autowired
    private PhoneRepository repository;

    public boolean supports(Class<?> clazz) {
       return true;
    }

    public void validate(Object target, Errors errors) {
        Phone annotation = // find fields with annotations by iterating over target.getClass().getFields().getAnnotation
        Object fieldValue = // how do i do this? I can easily get the annotation, but now I wish to do a call to repository checking if the field value exists.
    }
}
4

2 に答える 2

0

Maven モジュール A:

public interface RestValidator<A extends Annotation, T> extends ConstraintValidator<A, T>
public interface PhoneValidator extends RestValidator<PhoneNumber, String>

@Target(FIELD)
@Retention(RUNTIME)
@Constraint(validatedBy = PhoneValidator.class) // This usually doesnt work since its a interface
public @interface PhoneNumber {
   // JSR-303 required fields (payload, message, group)
}


public class Person {

@PhoneNumber
    private String phoneNumber;
}

Maven モジュール B:

@Bean
LocalValidatorFactoryBean configurationPropertiesValidator(ApplicationContext context, AutowireCapableBeanFactory factory) {
    LocalValidatorFactoryBean factoryBean = new LocalValidatorFactoryBean();
    factoryBean.setConstraintValidatorFactory(factory(context, factory));
    return factoryBean;
}

private ConstraintValidatorFactory factory(final ApplicationContext context, final AutowireCapableBeanFactory factory) {
    return new ConstraintValidatorFactory() {
        @Override
        public <T extends ConstraintValidator<?, ?>> T getInstance(Class<T> key) {
            if (RestValidator.class.isAssignableFrom(key)) {
                return context.getBean(key);
            } else {
                return factory.createBean(key);
            }
        }

        @Override
        public void releaseInstance(ConstraintValidator<?, ?> instance) {
            if (!(instance instanceof RestValidator<?, ?>)) {
                factory.destroyBean(instance);
            }
        }
    };
}

@Bean
WebMvcConfigurerAdapter webMvcConfigurerAdapter(final LocalValidatorFactoryBean validatorFactoryBean) {
    return new WebMvcConfigurerAdapter() {  // Adds the validator to MVC
        @Override
        public Validator getValidator() {
            return validatorFactoryBean;
        }
    };
}

次に、Scope = Prototype を持つ PhoneValidator の @Component 実装があります。

私はこの解決策が嫌いで、Spring はデフォルトで Interface の実装を検索する必要があると思いますが、私よりもはるかに賢い人がそうしないことにしたと確信しています。

于 2016-05-30T11:17:28.197 に答える
0

hibernate バリデーターなどの JSR 303 Bean バリデーター実装を試しましたか?

于 2016-05-28T14:55:09.357 に答える