在 Spring 中验证 JMS 负载
Validating JMS payload in Spring
我有一个发送电子邮件的简单服务。可以使用 REST 和 JMS API 调用它。我希望在处理之前验证请求。
当我使用 REST 调用它时,我可以看到 org.springframework.validation.DataBinder
调用了 void validate(Object target, Errors errors, Object... validationHints)
,然后调用了来自 Hibernate 的验证器。这按预期工作。
问题是我无法使用 JMS Listener 达到相同的效果。监听器实现如下:
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.jms.annotation.JmsListener;
import org.springframework.stereotype.Component;
import our.domain.mailing.Mailing;
import our.domain.mailing.jms.api.SendEmailFromTemplateRequest;
import our.domain.mailing.jms.api.SendSimpleEmailRequest;
import javax.validation.Valid;
@ConditionalOnProperty("jms.configuration.destination")
@Component
@AllArgsConstructor(onConstructor = @__(@Autowired))
@Slf4j
public class SendMailMessageListener {
Mailing mailing;
@JmsListener(destination = "${jms.configuration.destination}")
public void sendEmailUsingTemplate(@Valid SendEmailFromTemplateRequest request) {
log.debug("Received jms message: {}", request);
mailing.sendEmailTemplate(
request.getEmailDetails().getRecipients(),
request.getEmailDetails().getAccountType(),
request.getTemplateDetails().getTemplateCode(),
request.getTemplateDetails().getLanguage(),
request.getTemplateDetails().getParameters());
}
@JmsListener(destination = "${jms.configuration.destination}")
public void sendEmail(@Valid SendSimpleEmailRequest request) {
log.debug("Received jms message: {}", request);
mailing.sendEmail(
request.getRecipients(),
request.getSubject(),
request.getMessage());
}
}
这些方法接收有效载荷但未经过验证。它是 Spring 引导应用程序,我添加了 @EnableJms
。您能否指导 Spring 源代码的哪一部分负责发现 @Validate
并处理它?如果您对如何制作有任何提示运行,我将不胜感激。
解决方法很简单,在官方文档中有清楚的描述:29.6.3 Annotated endpoint method signature。您需要做的事情很少:
- 提供实现
JmsListenerConfigurer
的配置(添加 @Configuration
class 实现此接口)
- 在此配置的顶部添加注释
@EnableJms
- 创建 bean
DefaultMessageHandlerMethodFactory
。可以在这个配置下完成
- 通过您的配置实现接口
JmsListenerConfigurer
的方法 void configureJmsListeners(JmsListenerEndpointRegistrar registrar)
,并使用您刚刚创建的 bean 设置 MessageHandlerMethodFactory
- 将
@Validated
而不是 @Valid
添加到负载参数
您可以在监听器中使用@Valid。您的回答非常接近。在创建 DefaultMessageHandlerMethodFactory
的步骤中调用 .setValidator(validator)
,其中验证器来自 org.springframework.validation
。您可以像这样配置验证器:
@Bean
public LocalValidatorFactoryBean configureValidator ()
{
return new LocalValidatorFactoryBean();
}
然后将验证器实例注入您的 jms 配置
我有一个发送电子邮件的简单服务。可以使用 REST 和 JMS API 调用它。我希望在处理之前验证请求。
当我使用 REST 调用它时,我可以看到 org.springframework.validation.DataBinder
调用了 void validate(Object target, Errors errors, Object... validationHints)
,然后调用了来自 Hibernate 的验证器。这按预期工作。
问题是我无法使用 JMS Listener 达到相同的效果。监听器实现如下:
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.jms.annotation.JmsListener;
import org.springframework.stereotype.Component;
import our.domain.mailing.Mailing;
import our.domain.mailing.jms.api.SendEmailFromTemplateRequest;
import our.domain.mailing.jms.api.SendSimpleEmailRequest;
import javax.validation.Valid;
@ConditionalOnProperty("jms.configuration.destination")
@Component
@AllArgsConstructor(onConstructor = @__(@Autowired))
@Slf4j
public class SendMailMessageListener {
Mailing mailing;
@JmsListener(destination = "${jms.configuration.destination}")
public void sendEmailUsingTemplate(@Valid SendEmailFromTemplateRequest request) {
log.debug("Received jms message: {}", request);
mailing.sendEmailTemplate(
request.getEmailDetails().getRecipients(),
request.getEmailDetails().getAccountType(),
request.getTemplateDetails().getTemplateCode(),
request.getTemplateDetails().getLanguage(),
request.getTemplateDetails().getParameters());
}
@JmsListener(destination = "${jms.configuration.destination}")
public void sendEmail(@Valid SendSimpleEmailRequest request) {
log.debug("Received jms message: {}", request);
mailing.sendEmail(
request.getRecipients(),
request.getSubject(),
request.getMessage());
}
}
这些方法接收有效载荷但未经过验证。它是 Spring 引导应用程序,我添加了 @EnableJms
。您能否指导 Spring 源代码的哪一部分负责发现 @Validate
并处理它?如果您对如何制作有任何提示运行,我将不胜感激。
解决方法很简单,在官方文档中有清楚的描述:29.6.3 Annotated endpoint method signature。您需要做的事情很少:
- 提供实现
JmsListenerConfigurer
的配置(添加@Configuration
class 实现此接口) - 在此配置的顶部添加注释
@EnableJms
- 创建 bean
DefaultMessageHandlerMethodFactory
。可以在这个配置下完成 - 通过您的配置实现接口
JmsListenerConfigurer
的方法void configureJmsListeners(JmsListenerEndpointRegistrar registrar)
,并使用您刚刚创建的 bean 设置MessageHandlerMethodFactory
- 将
@Validated
而不是@Valid
添加到负载参数
您可以在监听器中使用@Valid。您的回答非常接近。在创建 DefaultMessageHandlerMethodFactory
的步骤中调用 .setValidator(validator)
,其中验证器来自 org.springframework.validation
。您可以像这样配置验证器:
@Bean
public LocalValidatorFactoryBean configureValidator ()
{
return new LocalValidatorFactoryBean();
}
然后将验证器实例注入您的 jms 配置