@RequiredArgsConstructor
@Configuration
public class CustomFtpClient {
private static final Logger logger = LoggerFactory.getLogger(CustomFtpClient.class);
private final Common common;
@Bean("MFtpClient")//싱글톤으로 쓰고 싶어서
public FTPClient ftpClient() throws Exception {
logger.debug("싱글톤");
FTPClient ftpClient = new FTPClient();
ftpClient.setDefaultPort(common.ftpPort);
ftpClient.addProtocolCommandListener(new PrintCommandListener(new PrintWriter(System.out)));
int reply;
ftpClient.connect(common.ip);// 호스트 연결
reply = ftpClient.getReplyCode();
if (!FTPReply.isPositiveCompletion(reply)) {
ftpClient.disconnect();
throw new Exception("Exception in connecting to FTP Server");
}
ftpClient.login(common.ftpUser, common.ftpPwd);// 로그인
ftpClient.setFileType(FTP.BINARY_FILE_TYPE);
ftpClient.enterLocalPassiveMode();
return ftpClient;
}
}
객체를 참조하는 클래스를 하나 또 등록하고..
@Component
public class FTPUploader {
private static final Logger log = LoggerFactory.getLogger(FTPUploader.class);
@Qualifier("MFtpClient")
@Autowired
private FTPClient client;
public void uploadFile(String localFileFullName, String fileName, String hostDir) throws Exception {
try (InputStream input = new FileInputStream(new File(localFileFullName))) {
client.storeFile(hostDir + fileName, input);
// storeFile() 메소드가 전송하는 메소드
}
}
public void disconnect() throws Exception {
if (client.isConnected()) {
try {
client.logout();
client.disconnect();
} catch (IOException f) {
f.printStackTrace();
}
}
}
public void CheckAndMakeDirectory(String path) throws Exception{
boolean isExist;
isExist = client.changeWorkingDirectory(path);
// 없으면 폴더 생성
if(!isExist){
client.makeDirectory(path);
}
}
}
사용법은 아래와 같이
@Async
public void ftpSendToCs2(String filePath) throws Exception { // Central Statino sever로 파일 전송
String pattern = Pattern.quote(System.getProperty("file.separator"));
logger.debug("filePath: " + filePath);
File fileTest = new File(filePath);
String fileName = fileTest.getName();
logger.debug("simpleFileName: " + fileName);
logger.debug(fileTest.getAbsolutePath());
logger.debug(fileTest.getParent());
logger.debug(fileTest.getParentFile().toString());
logger.debug(fileTest.getCanonicalPath());
String[] parentStrings =fileTest.getParent().split(pattern);
logger.debug(parentStrings.toString());
logger.debug(parentStrings[parentStrings.length -2]); //부모 폴더의 부모폴더이름을 뽑아낸다.
String folderName = parentStrings[parentStrings.length -2];
ftpUploader.CheckAndMakeDirectory(File.separator + folderName);
logger.debug("FTP SEND START");
ftpUploader.uploadFile(filePath, fileName, File.separator+ folderName + File.separator); //파일 전송시 공백있는 이름의 파일을 전송하면 안 됨, 위에서 이미 공백을 다 제거했기 때문.
//ftpUploader.disconnect();
logger.debug("FTP SEND DONE");
}
FTP 클라이언트를 싱글톤으로 쓰기 위해 @Bean으로 등록했는데, FTP 서버가 먼저 켜지지 않으면 connect를 못하므로 return을 못 시키고, 결국엔 참조하는 FTPUploader가 의존성 에러가 뜨므로, 이걸 사용하지 못할 것 같다.. 다른 좋은 방안은 없을까..