알쓸전컴(알아두면 쓸모있는 전자 컴퓨터)
drag and drop 파일 업로더 서버 파트 (vue-simple-uploader) 본문
vue-simple-uploader (Server 파트)
simple-uploader 을 사용 하기 위해서는 먼저 POST 로 전송온 request 객체를 multipartHttpServletRequest 으로 변환 해줘야 합니다.
multipartHttpServletRequest 을 사용 하기 위해서는
1.pom.xml
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.0.1</version>
</dependency>
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.2.2</version>
</dependency>
추가해 줍니다.
2.wepapp->WEB-INF->spring->appServlet->servlet-context.xml
<beans:bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<beans:property name="maxUploadSize" value="-1" />
</beans:bean>
bean을 추가해 줍니다.
여기서 옵션으로는
maxUploadSize(최대업로드 가능한 바이트크기)
maxInMemorySize(디스크에 임시 파일을 생성하기 전에 메모리에 보관할수있는 최대 바이트 크기)
defaultEncoding(요청을 파싱할 때 사용할 캐릭터 인코딩. 기본값 ISO-8859-1)
해당 정도가 있습니다.
일단 저는 Controller 에서
@RequestMapping(value = "/suggestion_file_upload", method = RequestMethod.POST)
public void insertBoard_attach_POST(HttpServletRequest request, HttpServletResponse response) {
try {
suggestion_dao.insertBoard_acttach1(request,response);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return;
}
그리고 실제 구현 하는 쪽에서는
import java.util.HashSet;
import java.util.Set;
public class FileInfo {
private final Set<Integer> uploadedChunks = new HashSet<>();
public boolean isUploadFinished(int flowTotalChunks) {
return this.uploadedChunks.size() == flowTotalChunks;
}
public boolean containsChunk(int flowChunkNumber) {
return this.uploadedChunks.contains(flowChunkNumber);
}
public void addUploadedChunk(int flowChunkNumber) {
this.uploadedChunks.add(flowChunkNumber);
}
}
private final Map<String, FileInfo> fileInfos = new ConcurrentHashMap<>();
public synchronized void insertBoard_acttach1(HttpServletRequest request, HttpServletResponse response)
throws Exception {
// TODO Auto-generated method stub
MultipartHttpServletRequest multipartHttpServletRequest = (MultipartHttpServletRequest) request;
int flowChunkNumber = Integer.parseInt(multipartHttpServletRequest.getParameter("chunkNumber"));
int flowTotalChunks = Integer.parseInt(multipartHttpServletRequest.getParameter("totalChunks"));
int flowChunkSize = Integer.parseInt(multipartHttpServletRequest.getParameter("chunkSize"));
int flowTotalSize = Integer.parseInt(multipartHttpServletRequest.getParameter("totalSize"));
String flowIdentifier = multipartHttpServletRequest.getParameter("identifier");
String flowFilename = multipartHttpServletRequest.getParameter("filename");
String relativePath = multipartHttpServletRequest.getParameter("relativePath");
String doc_number = multipartHttpServletRequest.getParameter("doc_number");
MultipartFile file = multipartHttpServletRequest.getFile("file");
System.out.println("flowIdentifier = " + flowIdentifier);
System.out.println("flowFilename = " + flowFilename);
System.out.println("doc_number = " +doc_number);
FileInfo fileInfo = this.fileInfos.get(flowIdentifier);
if (fileInfo == null) {
fileInfo = new FileInfo();
this.fileInfos.put(flowIdentifier, fileInfo);
}
String uploadDirectory = "/var/lib/tomcat8/webapps/suggestion_board/" + doc_number;
File file1 = new File(uploadDirectory);
if (!file1.exists()) {
file1.mkdirs();
}
Path identifierFile = Paths.get(uploadDirectory, flowIdentifier);
// try - Closeable 문법을 사용함
try (RandomAccessFile raf = new RandomAccessFile(identifierFile.toString(), "rw");
InputStream is = file.getInputStream()) {
raf.seek((flowChunkNumber - 1) * flowChunkSize);
long readed = 0;
long content_length = file.getSize();
byte[] bytes = new byte[1024 * 100];
while (readed < content_length) {
int r = is.read(bytes);
if (r < 0) {
break;
}
raf.write(bytes, 0, r);
readed += r;
}
}
fileInfo.addUploadedChunk(flowChunkNumber);
if (fileInfo.isUploadFinished(flowTotalChunks)) {
Path uploadedFile = Paths.get(uploadDirectory, flowFilename);
int j = 0;
while (uploadedFile.toFile().exists()) {
String[] file_names = flowFilename.split("\\.");
if (file_names.length > 1) {
flowFilename = file_names[0] + j + "." + file_names[1];
} else {
flowFilename = file_names[0] + j;
}
uploadedFile = Paths.get(uploadDirectory, flowFilename);
}
Files.move(identifierFile, uploadedFile, StandardCopyOption.ATOMIC_MOVE);
this.fileInfos.remove(flowIdentifier);
}
response.setStatus(HttpStatus.OK.value());
}
위와 같이 코딩해 주었습니다.
flow.js 대응 spring framework 코드를 참고 하여 작성 하였습니다.
디버깅을 해보면 1MB 씩 다운로드 파일이 분할되어 송신 됩니다.
그래서 각각의 분할된 파일을 파일내 적정 위치에 써줘야 되는 작업이 필요합니다.
그래서 chuck 정보 들이 필요 합니다.
'Web > Spring Framework tip' 카테고리의 다른 글
spring -> tomcat 원격 배포 deploy (0) | 2018.10.23 |
---|---|
spring oracle db + mybatis +log4jdbc 연결 (2) | 2018.04.07 |
spring 3.0 자동 bean 생성 (0) | 2018.04.05 |
MyBbatis Query에 부등호(<) 사용시 발생하는 Error (0) | 2018.03.22 |
axios(post) -> spring framework json 객체 변환 (0) | 2018.03.03 |