본문 바로가기
Java Web/Spring Boot

[Spring Boot] 프로젝트 외부 HOST 컴퓨터에 파일 업로드하기

by 스응 2023. 4. 24.
728x90
728x90

#  관련 포스팅

  - 업로드된 파일을 JSP에 가져오기 : https://young0105.tistory.com/243

 


#  form - input 태그

1
2
3
4
5
6
7
8
9
10
11
<!-- enctype="multipart/form-data" 필수 ! -->
<form action="/user/sign-up" method="post" enctype="multipart/form-data">
    <div class="custom-file">
        <!-- accept 속성은 업로드 가능한 확장자를 제한하는 속성 -->
        <!-- dto로 받는다면, 반드시 name을 멤버변수명과 동일하게 설정할 것 -->
           <input type="file" class="custom-file-input" id="customFile" accept=".jpg, .jpeg, .png" name="file">
           <label class="custom-file-label" for="customFile">Choose file</label>
      </div>
      <br><br>
    <button type="submit" class="btn btn-primary">submit</button>
</form>
cs

 

#  상수 선언

  1) 업로드 파일의 최대 크기

  2) 업로드한 파일을 저장할 경로

 

1
2
3
4
5
6
7
8
9
10
11
public class Define {
    
    // 이미지 처리 관련 (최대 파일 크기 늘리기)
    public final static int MAX_FILE_SIZE = 1024 * 1024 * 20// 최대 20MB
    // 1 byte == 8 bit
    // 1 KB == 1,024 byte
    // 1 MB == 1,048,476 byte (1024 * 1024)
 
    public final static String UPLOAD_DIRECTORY = "C:\\spring_upload\\bank\\upload";
    
}
cs

 

#  file을 받을 DTO

1
2
3
4
5
6
7
8
9
10
11
12
13
@Data
public class SignUpFormDto {
 
    // 파일을 받을 수 있는 멤버변수
    private MultipartFile file; // input 태그의 name과 일치시킬 것
    // 다중 처리는 리스트 대신 배열로 사용함 -> MultipartFile[]
 
    // 기존 파일명
    private String originFileName;
    // 랜덤 문자열을 붙인 파일명 (실제 업로드되는 파일명)
    private String uploadFileName;
    
}
cs

 

# form 태그를 처리하는 Controller

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
@Controller
@RequestMapping("/user")
public class UserController {
    
    // 서비스
    @Autowired // 객체 생성 시 의존 주입 처리
    private UserService userService;
    
    @Autowired // 해주면 예전처럼 request.getSession하지 않아도 가져와짐 
    private HttpSession session;
 
    @PostMapping("/sign-up")  // Post 방식에서 @RequestBody 없으면 Form 태그에서 땡겨온다는 뜻
    public String signUpProc(SignUpFormDto signUpFormDto) {
    
        // file을 업로드할 수도 있고, 하지 않을 수도 있게 함
        
        MultipartFile file = signUpFormDto.getFile();
        // file을 업로드했다면
        if (file.isEmpty() == false) {
            
            // 최대 파일 크기를 지정함
            if (file.getSize() > Define.MAX_FILE_SIZE) { // 상수로 선언해둔 값 이용
                throw new CustomRestfullException("업로드 파일 크기는 20MB까지만 가능합니다.", HttpStatus.BAD_REQUEST);
            }
 
            // 확장자 검사 가능 (생략)
            
            try {
                // 파일 저장 기능 구현 - 업로드 파일은 HOST 컴퓨터의 다른 폴더에 관리
                String saveDirectory = Define.UPLOAD_DIRECTORY; // 파일을 저장할 경로 지정
                
                // 폴더를 직접 생성하지 않아도, 폴더 유무를 확인하고 자동으로 생성해줌
                File dir = new File(saveDirectory);
                // File객체.exists() : 파일 or 폴더가 존재하는지 확인함
                if (dir.exists() == false) {
                    dir.mkdirs(); // 폴더가 존재하지 않으면 폴더 생성
                }
                
                // 파일명에 붙일 랜덤 문자열
                UUID uuid = UUID.randomUUID();
 
                // 실제 업로드되는 파일명
                String fileName = uuid + "_" + file.getOriginalFilename();
                
                // 파일을 어디에 저장할지 전체 경로 지정
                String uploadPath = Define.UPLOAD_DIRECTORY + File.separator + fileName; // File.separator : / <-를 좀더 명시적으로 
                File destination = new File(uploadPath); // 해당 경로에 fileName이라는 이름으로 파일 생성
 
                file.transferTo(destination); // flush까지 해줌
                
                // 파일이 없으면 null 그대로
                // DB에 저장되도록 Dto에 멤버 변수 값 초기화
                signUpFormDto.setOriginFileName(file.getOriginalFilename());
                signUpFormDto.setUploadFileName(fileName);
                
            } catch (Exception e) {
                e.printStackTrace();
                
            }
        }
        
        // 2. 서비스 호출 (핵심 로직은 서비스에서)
        userService.createUser(signUpFormDto);
        
        // 로그인 페이지로 보냄
        return "redirect:/user/sign-in";
    }
}
cs
320x100
반응형

댓글