2016-01-13 60 views
2

我有一個簡單的服務發送電子郵件。它可以使用REST和JMS API進行調用。我希望在處理之前驗證請求。驗證Spring中的JMS負載

當我使用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 Boot應用程序,我添加了@EnableJms。你能指導Spring源代碼的哪一部分負責發現@Validate並處理它?如果您對如何使其運行有任何提示,我將非常感激。

+0

Ofcourse也不會爲'處理@ Valid'特定Spring Web MVC框架。如果你想在其他地方添加'MethodValidationPostProcessor'。 –

+0

我認爲這應該是可行的,而不訴諸於使用'MethodValidationPostProcessor'。我可以在'org.springframework.messaging.handler.annotation.support.PayloadArgumentResolver'中看到,有一個方法'void validate(Message message,MethodParameter parameter,Object target)',它委託給'validator'對象在構造函數中。不幸的是,通過的驗證器爲空,我不知道如何設置它。這個驗證器從'DefaultMessageHandlerMethodFactory'傳遞,其中唯一可以設置它的地方(它的setter)永遠不會被調用。 –

+0

手動添加一個'JmsListenerAnnotationBeanPostProcessor'給它一個'DefaultMessageHandlerMethodFactory',它又配置了一個預配置的驗證器。這對於Spring Boot來說可能是一個很好的補充(你似乎正在使用它)來驗證春季消息的消息。 –

回答

2

該解決方案很簡單,並在官方文檔中明確描述:29.6.3 Annotated endpoint method signature。有你所要做的幾件事情:

  1. 提供配置實現JmsListenerConfigurer此配置
  2. 創建豆DefaultMessageHandlerMethodFactory的頂部(加@Configuration類實現了這個接口)
  3. 添加註釋@EnableJms。它可以在此配置進行
  4. 實現您的配置實現的接口JmsListenerConfigurer的方法void configureJmsListeners(JmsListenerEndpointRegistrar registrar)和使用您剛剛創建
  5. 代替@Valid添加@Validated有效載荷參數設定豆MessageHandlerMethodFactory
0

你可以在聽衆中使用@Valid。你的答案非常接近它。在創建DefaultMessageHandlerMethodFactory的步驟中,請致電.setValidator(validator)驗證者的地址是org.springframework.validation。你可以這樣配置驗證:

@Bean 
public LocalValidatorFactoryBean configureValidator() 
{ 
    return new LocalValidatorFactoryBean(); 
} 

然後注入校驗器實例到您的JMS配置