我很难处理一个简单的应用程序,它必须监视文件夹中的新文件,获取每个文件并使用RESTful服务(我的其他应用程序之一)并使用spring integration FTP Outbound channel adapter <发送响应文件< / p>
它具有以下结构:
初始化器:
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通道适配器,它工作正常,但我有几天想知道我缺少什么或这是最好的方法。
相信我,非常感谢帮助。
答案 0 :(得分:0)
问题在于此
我的出站通道配置类正在实现ApplicationContextAware
,它导致RestTemplate在使用我的微服务应用程序时冻结应用程序,因此我更改为扩展SpringBootServletInitializer
并实现WebApplicationInitializer
并且它有效。 / p>