본문 바로가기
Java | spring/Java Basic

Java 파일 업로드, 다운로드 처리(+파일 사이즈 제한 세팅 방법)

by 워니 wony 2023. 12. 17.

프로그램을 개발하다 보면 파일 업로드, 다운로드 처리하는 경우가 다수 있다.

간단하게 게시판을 만들더라도, 첨부파일을 올리거나 이미지를 올릴 수 있게 하는 기능을 기본적으로 구현한다.

 

웹 서비스에서 파일 업로드

게시판 서비스를 제공한다면, 게시글을 작성할 때 파일만 업로드하는게 아니라 글을 작성하고 파일도 함께 첨부하게 된다. 이런 경우 일반 데이터는 텍스트로 전달하고 첨부파일은 바이너리 데이터로 전송해야 한다.(파일 업로드 시 파일 데이터는 바이너리 데이터로 전송)

 

HTTP로 데이터 전송 시 entype을 multipart/form-data 전송하면 각각의 항목이 Part로 구분해서 한번에 전달이 된다. 

Form 태그로 전송 시 아래와 같이 써야 한다.

enctype="multipart/form-data"

 

 

 

업로드 파일 사이즈 제한 방법

application.properties 에서 아래와 같이 설정해 주면 된다.

아래 설정보다 큰 사이즈 파일 업로드 시 예외(SizeLimitExceededException) 발생한다.

  • max-file-size : 파일 하나의 최대 사이즈, 미설정 시 기본값 1MB
  • max-request-size : 여러개 파일 업로드 시 그 전체의 합, 기본값 10MB
spring.servlet.multipart.max-file-size=10MB
spring.servlet.multipart.max-request-size=100MB

 

 

 

간단한 스프링 파일 업로드 구현 방법

스프링에서는 파일 처리를 편리하게 사용할 수 있도록 Multipartfile 이라는 인터페이스를 지원한다.

@Slf4j
@Controller
@RequestMapping("/board")
public class SpringUploadController {

    @PostMapping("/save")
    public String save(@RequestParam String title,
                       @RequestParam String author,
                       @RequestParam MultipartFile file) throws IOException {
        log.info("title={}, author={}", title, author);
        
        String path = "/Users/Shared/file/";
        if (!file.isEmpty()) {
            String fullPath = path + file.getOriginalFilename();
            file.transferTo(new File(fullPath)); // 파일은 해당 경로에 저장
        }
        
        return "upload";
    }
    
}

위와 같이 작성하면 파일을 바로 받아서 서버에 저장이 가능하다. 로컬에서 실행 한다면, 로컬에 path에 해당하는 위치에 폴더가 있어야 한다. 일반적으로 서버에 폴더를 만들어서 파일을 저장하기 보다는 스토리지에 저장을 하도록 로직을 구현하는 편이다. 그리고 데이터베이스에는 UUID나 key 값 등을 저장해서 해당 파일을 찾을 수 있도록 한다.

 

 

 

 

파일 다운로드 구현 코드

@Slf4j
@Controller
@RequiredArgsConstructor
public class BoardController {
	private final BoardRepository boardRepository;

    @GetMapping("/attach/{boardId}")
    public ResponseEntity<Resource> downloadAttach(@PathVariable Long boardId) throws MalformedURLException {
        Board board = boardRepository.findById(boardId);
        String fileKey= board.geFile().getKey();
        String uploadFileName = board.getFile().getUploadFileName();

		String path = "/Users/Shared/file/";
        UrlResource resource = new UrlResource("file:" + path + fileKey);

        //한글 파일명 깨지지 않도록 처리
        String encodeUploadFileName = UriUtils.encode(uploadFileName, StandardCharsets.UTF_8);

        String contentDisposition = "attachment; filename=\"" + encodeUploadFileName + "\"";
        return ResponseEntity.ok()
                .header(HttpHeaders.CONTENT_DISPOSITION, contentDisposition)
                .body(resource);
    }
}

위와 같이 하면 클릭 시 화면을 파일을 다운로드 할 수 있다. 일반적으로 한글로 파일명을 올릴 수도 있기 때문에 인코딩이 필요하다.

 

그리고 아래 코드의 경우는 HTTP 규약으로 정해진 것으로 아래와 같이 작성해서 Response Header에 전달 하는 경우 파일을 다운로드 할 수 있게 된다. 

"attachment; filename=\"" + encodeUploadFileName + "\"";

 

 

 

 

반응형

댓글