두 개의 부트 앱이 있다. 하나는 client 구현, 하나는 server를 구현해서 파일을 전송해보자.
일단 클라이언트 측 작업 먼저
<!-- https://mvnrepository.com/artifact/commons-net/commons-net -->
<dependency>
<groupId>commons-net</groupId>
<artifactId>commons-net</artifactId>
<version>3.6</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework.integration/spring-integration-ftp -->
<dependency> //요거는 필요없을 수도 있겠다.
<groupId>org.springframework.integration</groupId>
<artifactId>spring-integration-ftp</artifactId>
<version>2.0.4.RELEASE</version>
</dependency>
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import javax.annotation.PostConstruct;
import org.apache.commons.net.PrintCommandListener;
import org.apache.commons.net.ftp.FTP;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPReply;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
public class FTPUploader { //매번 new 하는 것보다는,
FTPClient ftpClient = null;
private static final Logger log = LoggerFactory.getLogger(FTPUploader.class);
// param( host server ip, username, password ) 생성자
public FTPUploader(String host, String user, String pwd) throws Exception {
//log.debug("싱글톤으로 박을 수 없나.");
ftpClient = new FTPClient();
ftpClient.setDefaultPort(2121);
ftpClient.addProtocolCommandListener(new PrintCommandListener(new PrintWriter(System.out)));
int reply;
ftpClient.connect(host);// 호스트 연결
reply = ftpClient.getReplyCode();
if (!FTPReply.isPositiveCompletion(reply)) {
ftpClient.disconnect();
throw new Exception("Exception in connecting to FTP Server");
}
ftpClient.login(user, pwd);// 로그인
ftpClient.setFileType(FTP.BINARY_FILE_TYPE);
ftpClient.enterLocalPassiveMode();
}
// param( 보낼파일경로+파일명, 호스트에서 받을 파일 이름, 호스트 디렉토리 )
public void uploadFile(String localFileFullName, String fileName, String hostDir) throws Exception {
try (InputStream input = new FileInputStream(new File(localFileFullName))) {
this.ftpClient.storeFile(hostDir + fileName, input);
// storeFile() 메소드가 전송하는 메소드
}
}
public void disconnect() {
if (this.ftpClient.isConnected()) {
try {
this.ftpClient.logout();
this.ftpClient.disconnect();
} catch (IOException f) {
f.printStackTrace();
}
}
}
}
비동기 서비스 생성
소켓으로 filePath를 C:\test\CsFTPSendText.txt 요런 식으로 쏴줄거다.
@Async
public void ftpSendToCs2(String filePath) throws Exception { // Central Statino sever로 파일 전송
FTPUploader ftpUploader = new FTPUploader("localhost", "kyu",
"1234");
logger.debug("filePath: " + filePath);
File fileTest = new File(filePath);
String fileName = fileTest.getName();
logger.debug("simpleFileName: " + fileName);
logger.debug("FTP SEND START");
//ftpUploader.uploadFile(filename, "CsFTPSendText.txt", "C:" + File.separator + "kangminkyu" + File.separator + "aaaaaaa" + File.separator);
ftpUploader.uploadFile(filePath, fileName, File.separator); //파일 전송시 공백있는 이름의 파일을 전송하면 안 됨, 위에서 이미 공백을 다 제거했기 때문.
ftpUploader.disconnect();
logger.debug("FTP SEND DONE");
}
<!-- https://mvnrepository.com/artifact/commons-net/commons-net -->
<dependency>
<groupId>commons-net</groupId>
<artifactId>commons-net</artifactId>
<version>3.6</version>
</dependency>
<dependency>
<groupId>org.apache.ftpserver</groupId>
<artifactId>ftpserver-core</artifactId>
<version>1.0.6</version>
</dependency>
package net.lunalabs.central.config.ftp;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import javax.annotation.PostConstruct;
import org.apache.ftpserver.FtpServer;
import org.apache.ftpserver.FtpServerFactory;
import org.apache.ftpserver.ftplet.Authority;
import org.apache.ftpserver.ftplet.FtpException;
import org.apache.ftpserver.ftplet.FtpReply;
import org.apache.ftpserver.ftplet.FtpRequest;
import org.apache.ftpserver.ftplet.FtpSession;
import org.apache.ftpserver.ftplet.Ftplet;
import org.apache.ftpserver.ftplet.FtpletContext;
import org.apache.ftpserver.ftplet.FtpletResult;
import org.apache.ftpserver.ftplet.UserManager;
import org.apache.ftpserver.listener.ListenerFactory;
import org.apache.ftpserver.usermanager.PropertiesUserManagerFactory;
import org.apache.ftpserver.usermanager.impl.BaseUser;
import org.apache.ftpserver.usermanager.impl.WritePermission;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Configuration;
import lombok.RequiredArgsConstructor;
import net.lunalabs.central.service.FtpService;
@Configuration
@RequiredArgsConstructor
public class FtpServerMain {
private final FtpService ftpService;
private static final Logger logger = LoggerFactory.getLogger(FtpServerMain.class);
private final FtpProperties ftpProperties;
@PostConstruct
public void ftpServerStart(){
FtpServerFactory serverFactory = new FtpServerFactory();
ListenerFactory factory = new ListenerFactory();
// set the port of the listener
factory.setPort(ftpProperties.getPort());
//factory.set
// replace the default listener
serverFactory.addListener("default", factory.createListener());
PropertiesUserManagerFactory userManagerFactory = new PropertiesUserManagerFactory();
// userManagerFactory.setFile(new File("conf/myusers.properties"));
// serverFactory.setUserManager(userManagerFactory.createUserManager());
// String[] strAccountList = "아이디/비번,아이디/1234,아이디/1234".split(",");
UserManager um = userManagerFactory.createUserManager();
for(String AccountInfo : ftpProperties.getUserlist()) { //strAccountList
int idx=AccountInfo.indexOf("/");
String id= AccountInfo.substring(0,idx);
String pwd= AccountInfo.substring(idx+1);
/* logger.trace("id=="+id+"||pw=="+pwd);*/
BaseUser user = new BaseUser();
user.setName(id);
user.setPassword(pwd);
user.setEnabled(true);
logger.info("ftp 등록된 유저이름: " + user.getName());
logger.info("ftp 등록된 유저패스워드: " + user.getPassword());
user.setHomeDirectory(ftpProperties.getUploadDir()); //요기가 FTP server file root경로
java.util.List<Authority> authorities = new java.util.ArrayList<Authority>();
authorities.add(new WritePermission());
user.setAuthorities(authorities);
try {
um.save(user);
} catch (FtpException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
serverFactory.setUserManager(um);
Map<String, Ftplet> m = new HashMap<String, Ftplet>();
m.put("miaFtplet", new Ftplet()
{
@Override
public void init(FtpletContext ftpletContext) throws FtpException {
logger.info("init");
logger.info("Thread #" + Thread.currentThread().getId());
}
@Override
public void destroy() {
logger.info("destroy");
logger.info("Thread #" + Thread.currentThread().getId());
}
@Override
public FtpletResult beforeCommand(FtpSession session, FtpRequest request) throws FtpException, IOException
{
logger.info("beforeCommand " + session.getUserArgument() + " : " + session.toString() + " | " + request.getArgument() + " : " + request.getCommand() + " : " + request.getRequestLine());
logger.info("Thread #" + Thread.currentThread().getId());
//do something
return FtpletResult.DEFAULT;//...or return accordingly
}
@Override
public FtpletResult afterCommand(FtpSession session, FtpRequest request, FtpReply reply) throws FtpException, IOException
{
logger.info("afterCommand " + session.getUserArgument() + " : " + session.toString() + " | " + request.getArgument() + " : " + request.getCommand() + " : " + request.getRequestLine() + " | " + reply.getMessage() + " : " + reply.toString());
String strFileName = request.getArgument();
String strMsg = reply.getMessage();
logger.info("afterCommand " + strFileName + "::::::" + strMsg);
if (strMsg.equals("Transfer complete.")) {
// if (strMsg.equals("Requested file action okay, file renamed.")) {
String ip= session.getClientAddress().getAddress().toString();
try{
ftpService.ftpFileDBSave("C:\\kangminkyu\\FTPfileUpload", strFileName); //일단은 하드코딩
}catch(Exception e) {
}
}
// logger.trace("Thread #" + Thread.currentThread().getId());
//do something
return FtpletResult.DEFAULT;//...or return accordingly
}
@Override
public FtpletResult onConnect(FtpSession session) throws FtpException, IOException
{
logger.info("onConnect " + session.getUserArgument() + " : " + session.toString());
logger.info("Thread #" + Thread.currentThread().getId());
//do something
return FtpletResult.DEFAULT;//...or return accordingly
}
@Override
public FtpletResult onDisconnect(FtpSession session) throws FtpException, IOException
{
logger.info("onDisconnect " + session.getUserArgument() + " : " + session.toString());
logger.info("Thread #" + Thread.currentThread().getId());
//do something
return FtpletResult.DEFAULT;//...or return accordingly
}
});
serverFactory.setFtplets(m);
// start the server
FtpServer server = serverFactory.createServer();
try {
server.start();
} catch (FtpException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} }
}