Spring Multipart 파일 처리

호연지기·2023년 5월 23일
post-thumbnail

📁Multipart란?

한 웹 문서 안에 문자와 바이너리 데이터(이미지, 동영상, 음성 및 기타 형식의 파일 등)가 함께 포함되어 있는 상황.

Multi-part를 위한 설정(application.properties)

업로드 파일 용량 설정
    - 업로드 파일의 최대 크기 : max-file-size
    - 요청 객체에 담을 수 있는 최대 크기 : max-request-size
    (기본값은 각각 10MB.)

Multipart 속성

Spring framework에는 multi-part 라이브러리가 기본 포함되어 있기 때문에 추가할 dependency는 없음

form 태그에 enctype="multipart/form-data"를 추가.
(파일 업로드 처리 시 반드시 필요함.)

파일 태그는 디자인 변경이 용이하지 않기 때문에 label 태그를 사용하여 CSS 처리한다..(이때 파일 태그는 숨김 처리)
대신 선택한 파일명을 보이기 위해서 js로 파일명을 또 다른 input 태그에 출력함.

파일이 1개 일 경우 : 파일명을 그대로 출력
파일이 2개 이상일 경우 : '첫번째 파일명 외 00개'로 출력.

input 태그 file 타입은 'multiple' 속성으로 단일 파일 선택 또는 다중 파일 선택을 하도록 설정할 수 있음.
※ multiple과 multi-part는 관계 없음!

form 태그 내 input 태그에 readonly 속성을 부여하면 해당 input 태그는 전송에서 제외된다.(hidden은 전송됨)

🥙 파일 업로드 (파일 가져오기)

💻 index 소스(단일 파일 태그, 단일 파일 업로드(with some data))

<h2 style="color: yellowgreen">단일 파일 태그, 단일 파일 업로드(with some data)</h2>
<form action="fileProc1" method="post" enctype="multipart/form-data">
    <%--dto값을 받기 위한 input태그--%>
    <input type="text" name="str"><br>
    <input type="number" name="num"><br>

    <input type="file" name="file1"><br>
    <input type="submit" value="전송"><br>
</form>

💻 Controller 소스

@PostMapping("fileProc1")
public String fileProc1(@RequestPart List<MultipartFile> file1, DataDto data, HttpSession session){
    log.info("fileProc1()");
    String view = null;

    try {
        view = hServ.fileUpload1(file1, session);
    } catch (IOException e) {
        e.printStackTrace();
        view = "result";
    }

    return view;
}

💻 Dto 소스

input에 입력하는 소스를 받기 위한 데이터 처리

import lombok.Data;

@Data
public class DataDto {
    private String str;
    private int num;
}

🧐 결과


log.info()에 디버그 포인트 체크해두고 파일이 제대로 들어오는지 체크

파일 선택 후 전송버튼 누르기

입력한 문자열 qqq123이 각각 str, num으로 들어오고 파일도 정삭적으로 가져왔다.

🥙 파일 저장하기

파일 업로드 처리 시 유의사항

1) form 태그에 enctype="multipart/form-data"를 반드시 작성해야 한다.
2) 컨트롤러에서 파일을 받을 때 @RequestPart 어노테이션을 해당 파라미터 앞에 붙인다.
3) 파일을 받기 위한 매개변수는 List여야 한다. (MultipartFile)
4) 매개변수 이름은 파일 태그에 name 속성 값과 같아야 한다.
   또는, @RequestPart("name속성값")으로 작성한다.
5) 파일을 전송하던 하지 않던 List의 사이즈는 최소 1이다.
   파일 목록의 사이즈가 1이고 첫번째 파일의 이름이 ""(공백)이면 파일을 전송한 것이 아니다.

💻 Service 소스(HomeService)

public String fileUpload1(List<MultipartFile> file, HttpSession session) throws IOException {
        log.info("fileUpload1");

        //파일 저장 위치 지정. session으로 처리
        String realPath = session.getServletContext().getRealPath("/");
        log.info(realPath);
        //파일 업로드용 폴더 생성
        realPath += "upload/";
        File folder = new File(realPath);
        if(folder.isDirectory() == false){
            folder.mkdir();//폴더 생성 메소드
        }

        //파일 목록에서 파일을 가져와서 개별적으로 반복하여 처리
        for(MultipartFile mf : file){
            //파일명 가져오기.
            String fname = mf.getOriginalFilename();
            if(fname.equals("")){
                //업로드를 안한 상태
                return "result";//파일 처리 중지!
            }
            //파일이름 변경(덮어쓰기 방지)
            String sname = System.currentTimeMillis()
                    + fname.substring(fname.lastIndexOf("."));
            //예) gra.jpg -> 784568721.jpg
            File ufile = new File(realPath + sname);
            //파일 저장
            mf.transferTo(ufile);
        }//for end

        return "result";
    }

💻 Controller 소스

//@Autowired는 service 생성 후
    @Autowired
    HomeService hServ;
    
//service 사용 예
@PostMapping("fileProc1")
public String fileProc1(@RequestPart List<MultipartFile> file1, DataDto data, HttpSession session){
    log.info("fileProc1()");
    String view = null;

    try {
        view = hServ.fileUpload1(file1, session);
    } catch (IOException e) {
        e.printStackTrace();
        view = "result";
    }

    return view;
}

서비스 동작 메소드 생성 후 컨트롤러에서 hServ로 불러와 파일 업로드 - 저장 단계로 진행한다.

🧐 결과

폴더 생성하고 파일명을 변경해서 업로드가 된 모습!

📅 DATE

2023.05.23 작성

profile
사람의 마음에 차 있는 너르고 크고 올바른 기운

0개의 댓글