첨부파일을 서버에 전송하는 방식은 크게 2가지가 있습니다.
1. <form> 태그를 이용하는 방식
- 일반적으로 페이지 이동과 동시에 첨부파일을 업로드하는 방식
- <iframe>을 이용해서 화면의 이동 없이 첨부파을일 처리하는 방식
2. Ajax를 이용하는 방식
- <input type="file">을 이용하고 Ajax를 처리하는 방식
- HTML5의 Drag And Drop 기능이나 JQuery 라이브러리를 이용해서 처리하는 방식
⇒ 화면 단에서 첨부파일 처리하는 방식은 다양하지만, 서버쪽에서 처리하는 바식은 대부분 비슷합니다.
첨부파일 처리를 위한 라이브러리 혹은 API
1. cos.jar : 2002년 이후에 개발이 종료되었으므로, 더 이상 사용을 권장하지 않음.
2. common-fileupload : 가장 일반적으로 많이 활용되고, 서블릿 스펙 3.0 이전에도 사용 가능
3. 서블릿 3.0 이상 : 3.0 이상부터는 자체적인 파일 업로드 처리가 API 상에서 지원 (Tomcat 7.0 버전 이상에서 지원)
이 게시물에서 3번 API 방식과 <form> 태그를 이용해 파일 업로드를 처리하겠습니다.
pom.xml 에 서블릿 버전을 수정합니다.
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
web.xml에 첨부파일 처리에 대한 설정을 합니다.
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
id="WebApp_ID" version="3.1">
<!-- The definition of the Root Spring Container shared by all Servlets and Filters -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring/root-context.xml</param-value>
</context-param>
<!-- Creates the Spring Container shared by all Servlets and Filters -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- Processes application requests -->
<servlet>
<servlet-name>appServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring/appServlet/servlet-context.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
<multipart-config>
<location>C:\\upload\\temp</location>
<max-file-size>20971520</max-file-size> <!--1MB * 20 각 파일의 최대크기-->
<max-request-size>41943040</max-request-size><!-- 40MB 한번에 요창할 수 있는 최대크기 -->
<file-size-threshold>20971520</file-size-threshold> <!-- 20MB -->
</multipart-config>
</servlet>
<servlet-mapping>
<servlet-name>appServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<filter>
<filter-name>encodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>encodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>
위 web.xml의 설정은 WAS(Tomcat) 자체의 설정이며, 스프링에서 업로드 처리는 MultipartResolver라는 타입의 객체를 빈으로 등록해야합니다.
Spring Legacy Project를 통해 MVC 프로젝트를 생성했다면 Web과 관련된 설정을 입력하는 servlet-context.xml에 객체를 등록합니다.
<beans:bean id="multipartResolver"
class="org.springframework.web.multipart.support.StandardServletMultipartResolver">
</beans:bean>
파일업로드 테스트를 위해 JSP 파일을 생성합니다.
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<form action="fileUpload" method="post" enctype="multipart/form-data">
<input type='file' name='uploadFile' multiple>
<button>UPLOAD</button>
</form>
</body>
</html>
파일 업로드 시 form 태그에 enctype의 속성값을 'multipart/form-data'로 지정해야합니다.
<input type='file'>에 multiple 속성을 지정해 여러 개의 파일을 업로드할 수 있습니다.
fileUpload 경로를 처리할 수 있는 Controller 파일을 생성하고 RequestMapping을 처리해줍니다.
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.multipart.MultipartFile;
@Controller
@Log4j
public class FileUploadController {
@GetMapping("/fileUpload")
public void uploadForm() {
}
@PostMapping("/fileUpload")
public void uploadFormPost(MultipartFile[] uploadFile, Model model) {
String uploadFolder = "D:\\upload";
for (MultipartFile multipartFile : uploadFile) {
log.info("File Name : " + multipartFile.getOriginalFilename());
log.info("File Size: " + multipartFile.getSize());
File saveFile = new File(uploadFolder, multipartFile.getOriginalFilename());
try {
multipartFile.transferTo(saveFile);
} catch (Exception e) {
log.error(e.getMessage());
}
}
}
}
여기까지 처리시 화면에서 첨부한 실제 파일이 업로드 처리됩니다.
이외에도 파일업로드는 신경써야할 부분이 많습니다.
1. 파일업로드 정보를 데이터베이스에 별도로 저장해야합니다.
2. 이미지 파일의 경우 썸네일 파일을 별도로 생성합니다.
3. 파일의 확장자를 확인해 유효성 체크를 해야합니다.
4. 한 폴더에 모든 파일을 업로드하는 경우, 파일을 관리하기 어려우므로 년/월/일 형태의 폴더 등을 생성해 폴더를 분리해서 관리해야합니다.
5. 파일 업로드가 완료된 후 게시물을 조회하여 첨부파일을 클릭(혹은 더블 클릭) 하는 경우 파일 다운로드 혹은 미리보기 (이지미파일)을 처리해야 합니다.
6. 게시물을 삭제하는 경우 데이터베이스에서 해당 게시물의 파일 정보를 조회해 관련 파일도 함께 삭제해줘야합니다.
'개발 > spring' 카테고리의 다른 글
[Spring] 스프링(Spring) Controller의 리턴 타입 (0) | 2022.08.16 |
---|---|
[Spring] 스프링(spring) 어노테이션(Annotation) 정리 (0) | 2022.08.16 |