美文网首页
【Spring Integration】入门示例2例:读取文件并

【Spring Integration】入门示例2例:读取文件并

作者: 伊丽莎白2015 | 来源:发表于2023-01-24 11:50 被阅读0次

    【官网】

    【本文示例】

    • 通过spring-integration,将source文件夹中的文件自动复制到destination文件夹中。
    • 通过spring-integration,发送email。

    1. 示例-1:将source文件夹中的文件自动复制到destination文件夹中

    【示例参考】

    1.1 依赖

    需要引入spring boot parent,我用的是2.7.0版本。这个版本的spring boot,相应引入的spring-integration版本为5.5.12。
    下述的spring-integration-file主要是示例中需要操作file。

        <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-integration</artifactId>
            </dependency>
    
            <dependency>
                <groupId>org.springframework.integration</groupId>
                <artifactId>spring-integration-file</artifactId>
            </dependency>
        </dependencies>
    
    1.2 核心代码,创建两个bean
    • 首先是注解@EnableIngetration,java文档:地址,这个注解是spring-integration 4.0版本后引入的,主要是激活了spring integration相关的配置,有了这个注解,可以不需要老版本的xml配置,除此之外还会自动加入相关的BeanFactoryPostProcessors等。

    • 第一个bean为@InboundChannelAdapter,即spring-integration中的Adapter(分Inbound Adapter和Outbound Adapter,下述定义的FileReadingMessageSource为Inbound Adapter),@InboundChannelAdapter注解会将这个bean标记成Adapter,配置一个从别的系统接收的message(我们下述的例子为source文件夹中拿文件)。

      • Inbound Adapter中可以配置value,即channel的名字,这个在我们接收消息后的下一步(即订阅这个inbound message)的时候要绑定上。
      • 另一个参数为poller,英文的意思是轮询,这里配置的是每1000毫秒轮询一次。
      • 方法中的CompositeFileListFilter是用来过滤的,不配置的话说明读取的是整个source文件夹中的所有文件,配置后只会读取txt后缀的文件。
    • @ServiceActivator(java文档:地址),它需要参数inputChannel,即接收特定的inbound channel中的消息,在消息到达到inbound channel后,在这个方法中处理。在下述的例子中,fileReadingMessageSource()方法负责从source文件夹中读取文件,当文件读取到channel后,fileWritingMessageHandler()会接管处理,并将文件写到destination文件夹中。

      • setAutoCreateDirectory表示如果没有destination文件夹,会自动创建一个。
    @Configuration
    @EnableIntegration
    public class SpringIntegrationConfig {
    
        String folder = "/Users/xx/IdeaProjects/spring-integration-test/src/main";
    
        @Bean
        @InboundChannelAdapter(value = "fileInputChannel", poller = @Poller(fixedDelay = "1000"))
        public MessageSource<File> fileReadingMessageSource() {
            CompositeFileListFilter<File> filter = new CompositeFileListFilter<>();
            filter.addFilter(new SimplePatternFileListFilter("*.txt"));
    
            FileReadingMessageSource readerSource = new FileReadingMessageSource();
            readerSource.setDirectory(new File(folder + "/resources/source"));
            readerSource.setFilter(filter);
            return readerSource;
        }
    
        @Bean
        @ServiceActivator(inputChannel = "fileInputChannel")
        public MessageHandler fileWritingMessageHandler() {
            FileWritingMessageHandler writerHandler =
                    new FileWritingMessageHandler(new File(folder + "/resources/destination"));
            writerHandler.setAutoCreateDirectory(true);
            writerHandler.setExpectReply(false);
            return writerHandler;
        }
    
    1.3 测试
    首先在resources目录下新建source文件夹,并放一些测试文件: image.png

    启动SpringIntegrationApplication,从日志可以看到创建了channel=fileInputChannel,并且该channel有一个订阅者:

    2022-11-27 21:59:36.722 INFO 37452 --- [ main] o.s.i.endpoint.EventDrivenConsumer : Adding {file:outbound-channel-adapter:springIntegrationConfig.fileWritingMessageHandler.serviceActivator} as a subscriber to the 'fileInputChannel' channel
    2022-11-27 21:59:36.722 INFO 37452 --- [ main] o.s.integration.channel.DirectChannel : Channel 'application.fileInputChannel' has 1 subscriber(s).

    启动后可以看到文件test.txt被自动复制到了destination文件夹中: image.png

    2. 示例-2:通过spring-integration,发送email

    【参考】

    【官方文档】

    2.1 依赖

    和#1一样,需要引入spring boot parent,我用的是2.7.0版本。上述的spring-boot-starter-integration也需要引入。除此之外,还需要引入mail相关的依赖:

    • spring-integration-mail和spring-integration一样,会自动关联5.5.12版本。
    • javax.mail是用来发邮件的。
    • dumbster相当于测试的时候Mock了一个邮件服务器。
    <dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-test</artifactId>
            </dependency>
    
            <dependency>
                <groupId>javax.mail</groupId>
                <artifactId>mail</artifactId>
                <version>1.4</version>
            </dependency>
    
            <dependency>
                <groupId>com.github.kirviq</groupId>
                <artifactId>dumbster</artifactId>
                <version>1.7.1</version>
                <scope>test</scope>
            </dependency>
    </dependency>
    
    2.2 Mail相关配置:

    新建配置文件:smtp.properties

    smtp.host=localhost
    smtp.port=12345
    
    2.3 核心代码:创建三个bean
    • 第一个bean,JavaMailSenderImpl,创建邮件发送的bean,跟spring-integration本身无关,就是email发送的bean。用创建出来的mailSender bean直接发邮件也是可以的,调用send()即可。
    • 第二个bean,创建smtpChannel用来接收email messages用来发送邮件,这个bean也可以不创建,如果没有创建Spring也会帮我们创建,关于DirectChannel,实质上是spring-messaging.jar中的MessageChannel 接口,关于message-channel,可以查看官方文档:https://docs.spring.io/spring-integration/reference/html/channel.html
    • 第三个bean,我们使用mailsSenderMessagingHandler bean来发送邮件,当它收到的message的playload是MailMessage(来自smtpChannel),他就会发送给smtp server。
    @Configuration
    @PropertySource("classpath:/smtp.properties")
    public class MailConfig {
    
        @Value("${smtp.host}")
        private String smptHost;
    
        @Value("${smtp.port}")
        private Integer smtpPort;
    
        @Bean
        public JavaMailSenderImpl mailSender() {
            JavaMailSenderImpl mailSender = new JavaMailSenderImpl();
            mailSender.setHost(smptHost);
            mailSender.setPort(smtpPort);
            return mailSender;
        }
    
        @Bean
        public MessageChannel smtpChannel() {
            return new DirectChannel();
        }
    
        @ServiceActivator(inputChannel = "smtpChannel", outputChannel = "nullChannel")
        public MessageHandler mailsSenderMessagingHandler (Message<MailMessage> message) {
            MailSendingMessageHandler mailSendingMessageHandler = new MailSendingMessageHandler(mailSender());
            mailSendingMessageHandler.handleMessage(message);
            return mailSendingMessageHandler;
        }
    }
    

    【测试】

    • 可以看到我们使用了smtpChannel的send方法,本质上还是调用了MessageChannel接口,这里send的消息会被integration中的mailsSenderMessagingHandler接收,然后它进行处理,这里是通过MailSendingMessageHandler进行发送邮件。
    • 另外SimpleSmtpServer.start(12345)则是使用了dumbster包的mock邮件服务器。
    @Slf4j
    @SpringBootTest
    public class MailTest {
    
        @Autowired
        MessageChannel smtpChannel;
    
        @Test
        public void mailsend() throws IOException {
            SimpleSmtpServer mailServer = SimpleSmtpServer.start(12345);
            smtpChannel.send(new GenericMessage<>(buildMailMessage("Test 1", "content 1")));
            mailServer.stop();
    
            log.info("email send successfully..............");
            List<SmtpMessage> messagesSent = mailServer.getReceivedEmails();
            Assertions.assertEquals(1, messagesSent.size());
    
            log.info("received body: {}", messagesSent.get(0).getBody());
        }
    
        private MailMessage buildMailMessage(String subject, String content){
            MailMessage mailMessage = new SimpleMailMessage();
            mailMessage.setTo("test-to@com.test");
            mailMessage.setFrom("noreply@com.test");
            mailMessage.setCc("test-cc@com.test");
            mailMessage.setText(content);
            mailMessage.setSubject(subject);
            return mailMessage;
        }
    }
    

    相关文章

      网友评论

          本文标题:【Spring Integration】入门示例2例:读取文件并

          本文链接:https://www.haomeiwen.com/subject/upmcfdtx.html