Spring JMS onException重试

时间:2018-02-14 07:08:00

标签: java spring-boot jms spring-jms

我有一个要求,我需要发送电子邮件但是如果电子邮件服务器关闭或发送电子邮件需要重试特定次数时发生任何错误

下面是我的bean属性

@Bean(destroyMethod = "")
    public JndiTemplate jndiTemplate() {
        Properties environment = new Properties();
        environment.put(Context.INITIAL_CONTEXT_FACTORY, env.getProperty("XXXXXX"));
        environment.put(Context.PROVIDER_URL, env.getProperty("XXXXXX"));
        JndiTemplate jndiTemplate = new JndiTemplate();
        jndiTemplate.setEnvironment(environment);
        return jndiTemplate;
    }

    @Bean(destroyMethod = "")
    public JndiObjectFactoryBean jmsConnFactory() {
        JndiObjectFactoryBean jmsConnFactory = new JndiObjectFactoryBean();
        jmsConnFactory.setJndiTemplate(jndiTemplate());
        jmsConnFactory.setJndiName(env.getProperty("XXXXX"));
        return jmsConnFactory;
    }

    @Bean(destroyMethod = "")
    public JndiObjectFactoryBean jmsDestanation() {
        JndiObjectFactoryBean destination = new JndiObjectFactoryBean();
        destination.setJndiTemplate(jndiTemplate());
        destination.setJndiName(env.getProperty("XXXXXX"));
        return destination;
    }

    @Bean
    public JmsTemplate jmsTemplate() {
        JmsTemplate jmsTemplate = new JmsTemplate();
        jmsTemplate.setDefaultDestination(jmsDestanation());
        jmsTemplate.setConnectionFactory(jmsConnFactory());
        return jmsTemplate;
    }

    @Bean
    public JmsReceiver jmsReciver() {
        return new JmsReceiver();
    }

    @Bean
    public JmsExceptionListener jmsExceptionListener(){
        return new JmsExceptionListener();
    }

    @Bean
    public JmsErrorHandleListener jmsErrorHandleListener(){
        return new JmsErrorHandleListener();
    }   

    @Bean
    public DefaultMessageListenerContainer jmsQueueListner() {
        DefaultMessageListenerContainer listner = new DefaultMessageListenerContainer();
        listner.setDestination(jmsDestanation());
        listner.setConnectionFactory(jmsConnFactory());
        listner.setMessageListener(jmsReciver());
        listner.setExceptionListener(jmsExceptionListener());
        listner.setErrorHandler(jmsErrorHandleListener());  
        return listner;
    }

以下是我的Listener类和错误类

public class JmsReceiver implements MessageListener {

    @Autowired
    JavaMailSender jMailsender;

    @Override
    public void onMessage(Message message) {
        TextMessage text = (TextMessage) message;
        ObjectMapper objectMapper = new ObjectMapper();
        MimeMessage mimeMessage = jMailsender.createMimeMessage();  

        try {
            JmsMessage inMessage = objectMapper.readValue(text.getText(), JmsMessage.class);    
            //this is failing and go to the JmsErrorHandleListener
            jMailsender.send(mimeMessage);

        } catch (JMSException | IOException | MessagingException ex) {
            logger.error("Exception on reading message ",ex);
        }
    }
}

public class JmsErrorHandleListener implements ErrorHandler {

    @Override
    public void handleError(Throwable t) {
        /// not sure how to retry from hear becoz the message was allready read
        /// some how i need to inform the weblogic this message was not read yet
    }
}

当消息到达onMessage时会抛出错误然后执行 JmsErrorHandleListener 但是因为消息已经被读取我不知道如何一次又一次地调用send方法

1 个答案:

答案 0 :(得分:0)

尝试使用以下配置,弹出DMLC管理异常以重试MessageListener执行,如果jMailsender.send(mimeMessage);失败JmsReceiver.onMessage将在5s后无限期重试,请参阅DMLC退避属性

@Bean
public org.springframework.jms.listener.adapter.MessageListenerAdapter jmsReciver() {
    return new org.springframework.jms.listener.adapter.MessageListenerAdapter(receiver());
}

@Bean
public JmsReceiver receiver() {
    return new JmsReceiver();
}


public class JmsReceiver {

    @Autowired
    JavaMailSender jMailsender;

    @Override
    public void onMessage(Message message) throws JMSException {
        TextMessage text = (TextMessage) message;
        ObjectMapper objectMapper = new ObjectMapper();
        MimeMessage mimeMessage = jMailsender.createMimeMessage();  

        try {
            JmsMessage inMessage = objectMapper.readValue(text.getText(), JmsMessage.class);    
            //this is failing and go to the JmsErrorHandleListener
            jMailsender.send(mimeMessage);

        } catch (Throwable ex) {
            logger.error("Exception on reading message ",ex);
            throw new JMSException(ex.getMessage());
        }
    }
}