我正在尝试建立一个同时具有REST(POST)端点和Kafka端点的服务,这两个服务都应采用请求对象的JSON表示形式(我们称其为Foo)。我想确保Foo对象有效(通过JSR-303或其他方法)。所以Foo可能看起来像:
public class Foo {
@Max(10)
private int bar;
// Getter and setter boilerplate
}
设置REST端点很容易:
@PostMapping(value = "/", produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<String> restEndpoint(@Valid @RequestBody Foo foo) {
// Do stuff here
}
,如果我发布,{ "bar": 9 }
会处理请求,但是如果我发布:{ "bar": 99 }
,则会收到错误的请求。到目前为止一切都很好!
Kafka端点很容易创建(以及在StringJsonMessageConverter()
上添加KafkaListenerContainerFactory
,这样我就可以进行JSON-> Object转换:
@KafkaListener(topics = "fooTopic")
public void kafkaEndpoint(@Valid @Payload Foo foo) {
// I shouldn't get here with an invalid object!!!
logger.debug("Successfully processed the object" + foo);
// But just to make sure, let's see if hand-validating it works
Validator validator = localValidatorFactoryBean.getValidator();
Set<ConstraintViolation<SlackMessage>> errors = validator.validate(foo);
if (errors.size() > 0) {
logger.debug("But there were validation errors!" + errors);
}
}
但是无论我如何尝试,我仍然可以传递无效的请求,并且它们可以毫无错误地进行处理。
我已经尝试过@Valid
和@Validated
。我尝试添加一个MethodValidationPostProcessor
bean。我尝试将验证器添加到KafkaListenerEndpointRegistrar(例如EnableKafka javadoc):
@Configuration
public class MiscellaneousConfiguration implements KafkaListenerConfigurer {
private Logger logger = LoggerFactory.getLogger(this.getClass());
@Autowired
LocalValidatorFactoryBean validatorFactory;
@Override
public void configureKafkaListeners(KafkaListenerEndpointRegistrar registrar) {
logger.debug("Configuring " + registrar);
registrar.setMessageHandlerMethodFactory(kafkaHandlerMethodFactory());
}
@Bean
public MessageHandlerMethodFactory kafkaHandlerMethodFactory() {
DefaultMessageHandlerMethodFactory factory = new DefaultMessageHandlerMethodFactory();
factory.setValidator(validatorFactory);
return factory;
}
}
我现在已经花了几天时间,而我的其他想法也用光了。甚至有可能(无需将验证写入我的每个kakfa端点中)吗?