파일(File) upload/download
업로드
스프링에서 파일을 업로드 하는 방법에는 여러가지가 있다. 1번인 MultipartFile의 경우를 가장 많이 사용한다.
-
MultipartFile 사용
public String fileUpload(@RequestParam("file") MultipartFile file) throws IOException { if (!file.isEmpty()) { String filename = file.getOriginalFilename(); ... } }
- MultipartHttpServletRequest 사용
public String fileUpload(MultipartHttpServletRequest request) throws IOException { MultipartFile file = request.getFile("file"); if (!file.isEmpty()) { String filename = file.getOriginalFilename(); ... } }
Front-end
- form 태그에
enctype="multipart/form-data"
사용 - input 태그에
type="file"
사용
<form name="docsForm" method="post" enctype="multipart/form-data">
<input type="text" name="title">
<input type="text" name="content">
<input type="file" name="file">
</form>
Back-end
- MultipartFile 사용
-
getOriginalFilename()
: client가 첨부한 파일명 출력(확장자포함) -
transferTo(File file)
: 해당 경로로 파일 전송
public String fileUpload(@RequestParam("file") MultipartFile file) {
if (!file.isEmpty()) {
String originalName = file.getOriginalFilename(); // 본래 파일명(original.jpg)
String extension = originalName.substring(originalName.lastIndexOf("."), fileName.length()); // 확장자 추출(.jpg)
String url = "/Users/europani/file/"; // 폴더 경로
UUID uuid = UUID.randomUUID(); // 새로운 파일명에 쓸 난수 생성(abcedf)
String fileName = uuid.toString() + extension; // 새로운 파일명(abcedf.jpg)
File saveFile = new File(url, fileName); // 경로명:/Users/europani/file/abcedf.jpg
try {
file.transferTo(saveFile);
} catch (IOException e) {
e.printStackTrace();
}
FileVO fileVO = new FileVO();
fileVO.setUrl(url);
fileVO.setFileName(fileName);
fileVO.setOritinalName(originalName);
// ...DB에 저장...
}
}
다운로드
Front-end
<table>
<tr>
<th>
<label for="file">첨부파일</label>
</th>
<td>
<th:block th:each="file : ${files}">
<a th:href="@{/request/fileDown(id=${file.id})}" th:text="${file.originName}"></a>
</th:block>
</td>
</tr>
</table>
Back-end
-
HttpServletResponse
와ResponseEntity
를 사용 하는 2가지 방법이 있다 -
ResponseEntity
를 통한 방법을 사용할 것이다
public ResponseEntity<Resource> fileDownload(@RequestParam Long id, HttpServletRequest request) throws IOException {
// ... id를 사용하여 DB로부터 파일 정보 get...
File file = new File(fileVO.getUrl() + fileVO.getFileName());
String fileName = "";
// IE여부 판별하여 fileName 설정
String userAgent = request.getHeader("User-Agent");
boolean ie = (userAgent.indexOf("MSIE") > -1 || userAgent.indexOf("Trident") > -1);
if (ie) {
fileName = URLEncoder.encode(fileVO.getOriginName(), "utf-8").replaceAll("\\+", "%20");
} else {
fileName = new String(String.valueOf(fileVO.getOriginName()).getBytes("utf-8"), "iso-8859-1");
}
// 헤더 설정
HttpHeaders header = new HttpHeaders();
header.add(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + fileName + "\"");
header.add("Cache-Control", "no-cache, no-store, must-revalidate");
header.add("Pragma", "no-cache");
header.add("Expires", "0");
// 바디 설정(파일)
InputStreamResource resource = new InputStreamResource(new FileInputStream(file));
return ResponseEntity.ok()
.headers(header) // 헤더 삽입
.contentLength(file.length())
.contentType(MediaType.parseMediaType("application/octet-stream"))
.body(resource); // 바디 삽입
}