새 파일을 위해 폴더를 모니터링하고 각 파일을 가져 와서 RESTful 서비스 (내 다른 앱 중 하나)를 사용해야하는 간단한 애플리케이션을 처리하는 데 시간이 너무 많이 걸리고 있습니다.) 및 스프링 통합 FTP 바운드 채널 어댑터를 사용하여 상기 응답 파일을 전송Monitor 폴더가있는 문제가 WebService를 사용하고 FTP를 통해 파일을 보냅니다. 아웃 바운드 채널
이는 다음 구조했습니다
이니셜 :
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에 콩을 정의
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에서 시작 : 내가 예약 주석을 사용하고 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);
}
}
}
그리고 편안하고을 소비하는 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;
}
}
하지만 앱이 작동하지 않는 것 같습니다. 에서 편안하고 겨 :
logger.info("OBTENIENDO 214");
logger.info("DIRECCION" + restful214url);
logger.info("ARCHIVO" + hgfile);
나는 이것이 스레드의 문제 또는 무엇도 서버에 배포를 완료하지 않도록 APP 발생하는 경우이 선이 확실하지 여전히 로그에 두 번 인쇄 발견, 나는 또 다른이 비슷한 응용 프로그램 (하나는 RESTful을 소모하지 않는다는 것만 제외하면), 다른 FTPInbound 채널 어댑터와 제대로 작동하지만 정상적으로 작동하지만 몇 일간 실종되었거나 이 작업을 수행하는 가장 좋은 방법은 무엇입니까?
저를 믿으십시오, 도움은 극단적으로 평가 될 것입니다.
항상 첫 번째 단계는'org.springframework'에 대해 DEBUG 로깅을 활성화하는 것입니다. 당신은 많은 진단 로그 기록을 얻을 것이다. 로그를 얻지 않으면 jstack 또는 visualvm을 사용하여 스레드 덤프를 가져옵니다. –
감사합니다. Gary, 디버그를하고 있지만 내 응용 프로그램에 좋은 논리가 있습니다. ftpoutboun beans 정의 -> @EventListener로 모니터링을 시작하고 모니터에서 RESTful을 사용하고 -> ftpoutbound.createGateway (file)를 호출하여 파일을 보냅니다. – viruskimera