该方案是,在保留Log实体类之前,应检查其属性String description是否至少包含在IllegalWord实体类中找到的单词。这是两个实体类的映射:

// Log.java
@Entity
public class Log {
    @GeneratedValue(strategy=GenerationType.SEQUENCE)
    @Id
    private Long id;

    @NotContainingIllegalWords
    private String description;
}

// IllegalWord.java
@Entity
public class IllegalWord {
    @GeneratedValue(strategy=GenerationType.SEQUENCE)
    @Id
    private Long id;
    private String word;
}
由于我将对select *实体类执行IllegalWord,因此我为其创建了一个存储库类:
// IllegalWordRepository.java
@Repository
public interface IllegalWordRepository extends CrudRepository<IllegalWord, Long> {}
然后创建了ConstraintValidator验证器类,该类将由NotContainingIllegalWords批注使用,而该类又将用于注释String description实体类的Log字段:
// NotContainingIllegalWordsValidator.java
public class NotContainingIllegalWordsValidator implements ConstraintValidator<NotContainingIllegalWords, Object> {
    private static final Logger log = LoggerFactory.getLogger(NotContainingIllegalWordsValidator.class);

    @Autowired
    private IllegalWordRepository illegalWordRepository;

    public void initialize(NotContainingIllegalWords constraintAnnotation) {}

    public boolean isValid(String value, ConstraintValidatorContext cxt) {
        log.debug("illegalWordRepository is null? " + (illegalWordRepository == null));
        // Returns "illegalWordRepository is null? true"
        // It is not injected even with the @Autowired annotation.

        boolean valid = true;

        Collection<IllegalWord> illegalWords = illegalWordRepository.findAll();
        // Encounters a NullPointerException here.

        // valid = ...loop through illegalWords collection and match regex (or whatever optimal approach)
        // with @param value to check if it contains the illegal word.

        return valid;
    }
我认为那样会很简单。但是语句illegalWordRepository.findAll()引发错误,因为illegalWordRepository变量为null。请注意,我在前面的语句中尝试检查它是否为null
我以为我在存储库类中编码有误,因此我尝试在带注释的@Autowired private IllegalWordRepository illegalWordRepository的类中使用@Service,并令人惊讶地将其正确地注入到其中(例如,不是null):
// IllegalWordService.java
@Service
public class IllegalWordService {
    private static final Logger log = LoggerFactory.getLogger(IllegalWordService.class);

    @Autowired
    private IllegalWordRepository illegalWordRepository;

    public IllegalWord generate(String word) {
        log.debug("illegalWordRepository is null? " + (illegalWordRepository == null));
        // Returns "illegalWordRepository is null? false"

        IllegalWord illegalWord = new IllegalWord();
        illegalWord.setWord(word);

        illegalWordRepository.save(illegalWord);
        // Didn't encounter a NullPointerException here.

        return illegalWord;
    }
}
因此,我猜IllegalWordRepository存储库类没有什么不妥。只是它没有注入NotContainingIllegalWordsValidator验证器类中,因为我希望它与@Autowired注释一起使用(如果那是@Autowired注释甚至旨在起作用的方式,对不起,我是Spring Framework中的新手。)
如果有适当的方法可以在ConstraintValidator实例中执行@Entity查询,请告诉我。
相关的未解答的SO问题:Inject Repository inside ConstraintValidator with Spring 4 and message interpolation configuration

尝试失败:
我试图用NotContainingIllegalWordsValidator注释对@Configurable类进行注释,如下所示:
@Configurable(autowire=Autowire.BY_NAME, preConstruction=true)
public class NotContainingIllegalWordsValidator implements ConstraintValidator<NotContainingIllegalWords, Object> {
但是illegalWordRepository属性仍然是null

最佳答案

由于您的验证器不是由Spring初始化的,因此您无法向其中注入任何内容。您必须通过静态变量访问ApplicationContext

@SpringBootApplication
public class MyApplication {

  private static ApplicationContext applicationContext;

  public static void main(final String[] args) {
    applicationContext = SpringApplication.run(MyApplication.class, args);
  }
  public static ApplicationContext getApplicationContext() {
    return applicationContext;
  }
}
在你的ConstraintValidator中:
public class NotContainingIllegalWordsValidator implements ConstraintValidator<NotContainingIllegalWords, Object> {
  public boolean isValid(String value, ConstraintValidatorContext cxt) {
    ApplicationContext applicationContext = MyApplication.getApplicationContext();
    IllegalWordRepository illegalWordRepository = applicationContext.getBean(IllegalWordRepository.class);
    ...
  }
}

09-28 07:35