본문 바로가기
개발자의 정보/Java & framework

Spring에서 MultipartFile로 파일 저장 / 다운로드

by pastory 2020. 2. 15.

UPLOAD

spring-framework MVC controller 에서 파일을 전송받을 아래와 같이 MultipartFile 형태를 사용하게 된다.

@PostMapping(value = "/upload", consumes = {MediaType.MULTIPART_FORM_DATA_VALUE})
public ResponseEntity<?> addFiles(MultipartFile file) {
	...
    return ResponseEntity.ok(null);
}

파일을 저장하는 방법은 여러가지 이지만 아래와 같은 Method를 만들어 구현해 둔다면 편하게 호출하여 활용할 수 있다.

public void saveFiole(MultipartFile file, String directoryPath) throws IOException {
	// parent directory를 찾는다.
	Path directory = Paths.get(directoryPath).toAbsolutePath().normalize();

	// directory 해당 경로까지 디렉토리를 모두 만든다.
	Files.createDirectories(directory);
    
	// 파일명을 바르게 수정한다.
	String fileName = StringUtils.cleanPath(file.getOriginalFilename());

	// 파일명에 '..' 문자가 들어 있다면 오류를 발생하고 아니라면 진행(해킹및 오류방지)
	Assert.state(!fileName.contains(".."), "Name of file cannot contain '..'");
	// 파일을 저장할 경로를 Path 객체로 받는다.
	Path targetPath = directory.resolve(fileName).normalize();

	// 파일이 이미 존재하는지 확인하여 존재한다면 오류를 발생하고 없다면 저장한다.
	Assert.state(!Files.exists(targetPath), fileName + " File alerdy exists.");
	file.transferTo(targetPath);
}

DOWNLOAD

항상은 아니지만 대부분 저장을 하면 당연히 다운로드도 할 것이다. 다운로드 컨트롤러는 이렇게 쉽게 만들 수 있다.

@GetMapping("/download/{id}")
public ResponseEntity<Resource> downloadMdssFile(
		@PathVariable long id,
		HttpServletRequest request) throws MalformedURLException {
	MdssFile mdssFile = repository.findById(id).get();
	Path filePath = Paths.get(mdssFile.getPath()).toAbsolutePath().normalize();
	Resource resource = new UrlResource(filePath.toUri());
	
	String contentType = null;
	
	try {
		contentType = request.getServletContext().getMimeType(
			resource.getFile().getAbsolutePath()
		);
	}
	catch (IOException ex) {
		log.warn("Could not determine file type.");
		contentType = "application/octet-stream";
	}
	
	return ResponseEntity.ok()
			.contentType(MediaType.parseMediaType(contentType))
			.header(
					HttpHeaders.CONTENT_DISPOSITION,
					"attachment; filename=\"" + mdssFile.getName() + "\""
			)
			.body(resource);
}

파일 업로드와 다운로드는 이렇게 쉽게 해결 가능하다. 끗!

댓글