[Spring] 파일 업로드/다운로드 기능 구현
실행환경
1) MySQL 과 연동되어있으며, DB 에 파일정보를 담은 Pds table 이 존재
Pds table 정보
// Personal Data Store
create table pds(
seq int auto_increment primary key,
id varchar(50) not null,
title varchar(200) not null,
content varchar(4000) not null,
filename varchar(50) not null,
newfilename varchar(50) not null,
readcount decimal(8) not null,
downcount decimal(8) not null,
regdate timestamp not null
)
// 회원정보 테이블과 id로 관계되어있음 (외래키설정)
alter table pds
add foreign key(id) references member(id);
2) pom.xml 에 해당 dependency 가 존재 (maven)
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3.3</version>
</dependency>
3) AOP 필요
[file-context.xml]
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<!-- upload -->
<bean id="multipartResolver"
class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="maxUploadSize" value="104857600"/>
<property name="maxInMemorySize" value="102400"/>
<property name="defaultEncoding" value="utf-8"/>
<property name="uploadTempDir" value="upload"/>
</bean>
<!-- download -->
<bean id="downloadView" class="mul.cam.a.util.DownloadView"></bean>
<!-- DownloadView downloadView = new DownloadView(); -->
<bean id="downloadViewResolver" class="org.springframework.web.servlet.view.BeanNameViewResolver">
<property name="order">
<value>0</value>
</property>
</bean>
</beans>
Upload Controller
/* DB 에 파일 업로드하기 */
@PostMapping(value = "pdsupload.do")
public String pdsupload(PdsDto dto,
@RequestParam(value = "fileload", required = false)
MultipartFile fileload,
HttpServletRequest req) {
// filename 취득
String filename = fileload.getOriginalFilename(); // 원본의 파일명 MutipartFile 의 method
dto.setFilename(filename); // 원본 파일명(DB)
// server경로 설정
String fupload = req.getServletContext().getRealPath("/upload");
// 폴더경로 설정
// String fupload = "c:\\temp";
// 파일명을 충돌되지 않는 명칭(Date)으로 변경
String newfilename = PdsUtil.getNewFileName(filename);
dto.setNewfilename(newfilename); // 변경된 파일명
File file = new File(fupload + "/" + newfilename);
try {
// 실제로 파일 생성 + 기입 = 업로드
FileUtils.writeByteArrayToFile(file, fileload.getBytes());
// db에 저장 (service -> dao -> mybatis -> MySQL 접근)
service.uploadPds(dto);
} catch (IOException e) {
e.printStackTrace();
}
return "redirect:/pdslist.do";
}
@RequestParam( value="fileload", required=false )
MutipartFile 변수명
1) @RequestParam( value="fileload", required=false )
- 1개의 HTTP request parameter를 받기 위해서 사용
- request parameter 의 value(값 형태), required(필수여부), default value (기본값) 을 정할 수 있음
[Spring] @RequestBody, @ModelAttribute, @RequestParam의 차이 - MangKyu's Diary (tistory.com)
2) MutipartFile
- MultipartResolver Bean 등록 시 사용가능
- Spring 에서 업로드한 파일을 표현할 때 사용되는 인터페이스
- 업로드한 파일의 이름, 실제데이터, 파일크기를 구할 수 있음
MultipartFile (Spring Framework 6.0.5 API)
String fupload = req.getServletContext().getRealPath("/upload");
String newfilename = PdsUtil.getNewFileName(filename); // 파일명을 충돌되지 않는 명칭(Date)으로 변경
File file = new File(fupload + "/" + newfilename); // 파일을 담을 File 인스턴스 생성하고 지정한 위치에 저장
try {
// fileload 는 request로 받은 파일데이터, 이를 byte array 로 변환.
// File 객체에 변환한 byte array를 작성.
FileUtils.writeByteArrayToFile(file, fileload.getBytes());
service.uploadPds(dto); // db에 저장
} catch (IOException e) {
e.printStackTrace();
}
1) getServletContext()
- Servlet 에 정보를 전달하기 위해 Servlet container 에서 사용하는 객체의 메서드
- 실행중인 Servlet context 에 대한 참조를 반환 (ServletContext 객체 반환)
2) getRealPath("")
- 지정된 가상경로에 해당하는 실제경로를 반환 (string)
java - What does servletcontext.getRealPath("/") mean and when should I use it - Stack Overflow
3) FileUtils.writeByteArrayToFile(File file, byte[] data, ... )
- byte 배열의 데이터를 File 객체에 작성함
FileUtils (Apache Commons IO 2.5 API)
Convert from a URL to a File. From version 1.1 this method will decode the URL. Syntax such as file:///my%20docs/file.txt will be correctly decoded to /my docs/file.txt. Starting with version 1.5, this method uses UTF-8 to decode percent-encoded octets to
commons.apache.org
Download Controller
/* WEB-INF/upload 에서 파일 불러오기 */
@PostMapping(value = "filedownLoad.do")
public String filedownLoad(int seq, String filename, String newfilename, Model model,
HttpServletRequest req) {
// 경로
// server
String fupload = req.getServletContext().getRealPath("/upload");
// 폴더
// String fupload = "c:\\temp";
// 다운로드 받을 파일
File downloadFile = new File(fupload + "/" + newfilename); // WEB-INF/upload/파일명의 파일객체생성
model.addAttribute("downloadFile", downloadFile); // upload 폴더 안에 있는 파일명 35435345345.txt
model.addAttribute("filename", filename); // 원 파일명 abc.txt
model.addAttribute("seq", seq); // download 카운트 증가
return "downloadView"; // downloadView 로 이동, model 데이터 같이 보냄
}