带有Monitor文件夹的ISSUES,使用WebService并通过FTP出站通道

时间:2017-01-07 06:26:03

标签: java spring rest spring-integration spring-scheduled

我很难处理一个简单的应用程序,它必须监视文件夹中的新文件,获取每个文件并使用RESTful服务(我的其他应用程序之一)并使用spring integration FTP Outbound channel adapter <发送响应文件< / p>

它具有以下结构:

enter image description here

初​​始化器:

package com.ftpoutbound;

import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.support.SpringBootServletInitializer;

import com.ftpoutbound.client.FtpoutboundApp;
public class ServletInitializer extends SpringBootServletInitializer {

    @Override
    protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
        return application.sources(FtpoutboundApp.class);
    }

}

我在FtpoutboundApp中定义bean:

package com.ftpoutbound.client;

import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;

import org.springframework.context.ApplicationContext;
import org.apache.commons.net.ftp.FTPFile;
import org.apache.log4j.Logger;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration;
import org.springframework.boot.context.event.ApplicationReadyEvent;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.event.EventListener;
import org.springframework.expression.common.LiteralExpression;
import org.springframework.integration.annotation.Gateway;
import org.springframework.integration.annotation.IntegrationComponentScan;
import org.springframework.integration.annotation.MessagingGateway;
import org.springframework.integration.annotation.ServiceActivator;
import org.springframework.integration.file.FileNameGenerator;
import org.springframework.integration.file.remote.session.CachingSessionFactory;
import org.springframework.integration.file.remote.session.SessionFactory;
import org.springframework.integration.ftp.outbound.FtpMessageHandler;
import org.springframework.integration.ftp.session.DefaultFtpSessionFactory;
import org.springframework.messaging.Message;
import org.springframework.messaging.MessageHandler;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.web.client.RestTemplate;

import com.ftpoutbound.monitor.MonitorDirectory;

@Configuration
@SpringBootApplication
@ComponentScan({ "com.ftpoutbound" })
@IntegrationComponentScan
@EnableAutoConfiguration(exclude = { DataSourceAutoConfiguration.class, HibernateJpaAutoConfiguration.class })
@EnableScheduling
public class FtpoutboundApp implements ApplicationContextAware {

    final static Logger logger = Logger.getLogger(FtpoutboundApp.class);

    @Autowired
    private MonitorDirectory monitor;

    @Autowired
    MyGateway gateway;

    @Value("${remotedirectory}")
    private String remotedirectory;

    @Value("${remotehost}")
    private String remotehost;

    @Value("${remoteport}")
    private int remoteport;

    @Value("${remoteuser}")
    private String remoteuser;

    @Value("${remotepassword}")
    private String remotepassword;

    @Value("${outbound214sname}")
    private String outbound214sname;

    public static void main(String[] args) {
        SpringApplication.run(FtpoutboundApp.class, args);
    }

    public void createGateway(File file214) {
        try {
            gateway.sendToFtp(file214);
            file214.delete();
        } catch (Exception e) {
            logger.error("ERROR APP OUTBOUND\n");
            logger.error(e);
        }
    }

    @Bean
    public SessionFactory<FTPFile> ftpSessionFactory() {
        DefaultFtpSessionFactory sf = new DefaultFtpSessionFactory();
        sf.setHost(remotehost);
        sf.setPort(remoteport);
        sf.setUsername(remoteuser);
        sf.setPassword(remotepassword);
        return new CachingSessionFactory<FTPFile>(sf);
    }

    @Bean
    @ServiceActivator(inputChannel = "ftpChannel")
    public MessageHandler handler() {
        FtpMessageHandler handler = new FtpMessageHandler(ftpSessionFactory());
        handler.setRemoteDirectoryExpression(new LiteralExpression(remotedirectory));
        handler.setFileNameGenerator(new FileNameGenerator() {

            @Override
            public String generateFileName(Message<?> message) {
                String date = new SimpleDateFormat("yyyyMMdd").format(new Date());
                String time = new SimpleDateFormat("HHmmssssssss").format(new Date());
                return outbound214sname + "." + date + time;
            }
        });
        return handler;
    }

    @MessagingGateway
    public interface MyGateway {

        @Gateway(requestChannel = "ftpChannel")
        void sendToFtp(File file);
    }

    @EventListener
    public void afterApplicationReady(ApplicationReadyEvent event) {
        try {
            logger.info("INICIO DE MONITOREO DE ARCHIVOS HG");
            monitor.startMonitoring();
        } catch (IOException e) {
            logger.error("ERROR EN MONITOREO  DE FOLDER ENTRADA ARCHIVOS HG:\n" + e);
        } catch (InterruptedException e) {
            logger.error("INTERRUPCIÓN EN MONITOREO  DE FOLDER ENTRADA ARCHIVOS HG:\n" + e);
        }
    }

    @Bean
    RestTemplate restTemplate() {
        return new RestTemplate();
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
    }

}

监视器从FtpoutboundApp启动: 我正在使用SCHEDULED注释,因为Watchservice无法正常工作

package com.ftpoutbound.monitor;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.ClosedWatchServiceException;
import java.nio.file.FileSystems;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardWatchEventKinds;
import java.nio.file.WatchEvent;
import java.nio.file.WatchKey;
import java.nio.file.WatchService;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import com.ftpoutbound.client.FtpoutboundApp;
import com.ftpoutbound.restfulclient.httpPost;

@Component
public class MonitorDirectory {

    final static Logger logger = Logger.getLogger(MonitorDirectory.class);

    @Autowired
    private httpPost httppost;

    @Value("${inboundhgfilesfolder}")
    private String inboundhgfilesfolder;

    @Value("${inboundhgfilesfolderbak}")
    private String inboundhgfilesfolderbak;

    @Value("${hglin}")
    private String hglin;

    @Scheduled(fixedRate = 10000)
    public void startMonitoring() throws IOException, InterruptedException {
        try {
            listFiles();
        } catch (Exception e) {
            logger.error("ERROR MONITOREANDO FOLDER");
            logger.error(e);
        }
    }

    public void listFiles() throws Exception {
        File directory = new File(inboundhgfilesfolder);
        File[] fList = directory.listFiles();
        for (File file : fList) {
            String fileName = file.getName();
            if (file.isFile()) {
                readFile(fileName);
                Thread.sleep(1000);
            }
        }
    }

    public void readFile(String fileName) throws IOException {

        String hgFile = fileName.substring(0, 7);
        if (hgFile.equals(hglin)) {

            InputStream input = new FileInputStream(inboundhgfilesfolder + fileName);
            StringBuilder builder = new StringBuilder();
            int ch;
            while ((ch = input.read()) != -1) {
                builder.append((char) ch);
            }
            try {
                httppost.get214fromRestful(builder.toString());
            } catch (Exception e) {
                logger.error("ERROR EN POST REQUEST DESDE APP OUTBOUND:\n" + e);
            }
        }
        moveFile(fileName);
    }

    public void moveFile(String fileName) {

        Path source = Paths.get(inboundhgfilesfolder + fileName);
        Path newdir = Paths.get(inboundhgfilesfolderbak + fileName);
        try {
            Files.move(source, newdir);
        } catch (IOException e) {
            logger.error("ERROR MOVIENDO ARCHIVO:\n" + e);
        }
    }
}

使用RESTful应用程序的HTTPclient

package com.ftpoutbound.restfulclient;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;

import com.ftpoutbound.client.FtpoutboundApp;

@Component
public class httpPost {

    final static Logger logger = Logger.getLogger(httpPost.class);

    @Value("${restful214url}")
    private String restful214url;

    @Value("${outbound214sfolder}")
    private String outbound214sfolder;

    @Autowired
    private FtpoutboundApp ftpoutbound;

    public void get214fromRestful(String hgfile) throws Exception {
        logger.info("OBTENIENDO 214");
        logger.info("DIRECCION" + restful214url);
        logger.info("ARCHIVO" + hgfile);

        RestTemplate restTemplate = new RestTemplate();
        String result = restTemplate.postForObject(restful214url, hgfile, String.class);

        File file = createFile214local(result.toString());
        logger.info("RESULTADO DE POST:");
        logger.info(result.toString());

        ftpoutbound.createGateway(file);

    }

    private File createFile214local(String hgfile) {

        logger.info("ESCRIBIENDO 214");
        File file = new File(outbound214sfolder + "214.tmp");
        try {
            file.createNewFile();
            FileWriter fw = new FileWriter(file.getAbsoluteFile());
            BufferedWriter bw = new BufferedWriter(fw);
            bw.write(hgfile);
            bw.close();

        } catch (IOException e) {
            logger.error("ERROR ESCRIBIENDO FILE:\n->" + e);
        }

        return file;
    }

}

但该应用似乎无法正常工作,它在使用RESTful之前冻结:

            logger.info("OBTENIENDO 214");
            logger.info("DIRECCION" + restful214url);
            logger.info("ARCHIVO" + hgfile);

我注意到这些行在日志中打印了两次,仍不确定这是否是线程问题或者是什么导致APP甚至没有完成服务器中的部署,我有另一个类似的App(除了那个没有使用RESTful)它工作正常,另一个FTPInbound通道适配器,它工作正常,但我有几天想知道我缺少什么或这是最好的方法。

相信我,非常感谢帮助。

1 个答案:

答案 0 :(得分:0)

问题在于此 我的出站通道配置类正在实现ApplicationContextAware,它导致RestTemplate在使用我的微服务应用程序时冻结应用程序,因此我更改为扩展SpringBootServletInitializer并实现WebApplicationInitializer并且它有效。 / p>