Java 监视器文件夹、使用WebService和通过FTP出站通道发送文件出现问题
我在处理一个简单的应用程序时遇到了麻烦,它必须监视文件夹中的新文件,获取每个文件并使用RESTful服务(我的另一个应用程序),并使用spring integration FTP Outbound channel adapter发送响应文件 其结构如下: 初始值设定项:Java 监视器文件夹、使用WebService和通过FTP出站通道发送文件出现问题,java,spring,rest,spring-integration,spring-scheduled,Java,Spring,Rest,Spring Integration,Spring Scheduled,我在处理一个简单的应用程序时遇到了麻烦,它必须监视文件夹中的新文件,获取每个文件并使用RESTful服务(我的另一个应用程序),并使用spring integration FTP Outbound channel adapter发送响应文件 其结构如下: 初始值设定项: package com.ftpoutbound; import org.springframework.boot.builder.SpringApplicationBuilder; import org.springfram
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 {
}
}
以及使用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);
我注意到这些行在日志中打印了两次,仍然不确定这是否是线程问题,或者是什么原因导致应用程序甚至无法在服务器上完成部署,我有另一个类似的应用程序(除了一个不使用RESTful的应用程序),它工作正常,另一个FTPInbound通道适配器工作正常,但是我有几天的时间来思考我错过了什么,或者什么是最好的方法。
相信我,我们将非常感谢您的帮助。问题是
我的出站通道配置类正在实现
ApplicationContextAware
,它导致RestTemplate在使用我的微服务应用程序时冻结应用程序,因此我改为扩展SpringBootServletilizer
并实现WebApplicationInitializer
,它正常工作。第一步,一如既往,是为org.springframework
启用调试日志记录;您将获得许多诊断日志记录。如果您停止获取日志,请使用jstack或visualvm进行线程转储。谢谢Gary,我正在进行调试,但我的应用程序是否具有良好的逻辑:定义ftpoutboun bean->使用@EventListener开始监视,并从监视器使用RESTful,然后调用->ftpoutbound.createGateway(文件)发送文件?
logger.info("OBTENIENDO 214");
logger.info("DIRECCION" + restful214url);
logger.info("ARCHIVO" + hgfile);