째로스 2023. 6. 30. 14:45

※ 파일 전송에서의 기본 인코딩 방식

서버와 클라이언트는 기본 인코딩 방식으로 application/x-www-form-urlencoded 을 사용한다.

이는 문자열만을 주고받는 방식으로 위 이미지에서 처럼 

클라이언트가 uid를 newlec, name을 dragon으로 서버로 전송할 경우

uid=newlec&name=dragon로 문자열을 전송한다.

 

하지만 파일과 같은 바이너리 파일들은 이런 문자열 형태로는 전송하기가 어려운데,

이를 극복하기 위해 나온 것이 multipart/form-data 인코딩 방식이다.

위 이미지처럼 하나의 문자열이 아닌 각 name마다 데이터별 별개의 구분을 주어 전송한다.

 

따라서 우리가 서버를 작성할 때, 파일을 받기 위해서는 multipart/form-data 인코딩 방식의 송수신을 할 수 있도록 설정을 별도로 해줘야한다.

 

1. xml 파일에 multipart/form-data 인코딩을 위한 bean 객체 작성

<bean id="multipartResolver"
    class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
    <property name="maxUploadSize" value="314572800"/>	
</bean>

maxUploadSize는 업로드 할 수있는 최대 파일의 크기를 설정하는 것으로,

314,572,800KB=300*1024*1024 KB(300MB)를 전송할 수 있도록 하였다.

 

(multipart/form-data bean 객체 작성시 property 설정과 관련해 더 알고싶다면 아래 링크를 참고하자.)

 

https://docs.spring.io/spring-framework/docs/1.2.6/javadoc-api/org/springframework/web/multipart/commons/CommonsMultipartResolver.html

 

CommonsMultipartResolver (Spring Framework)

Set the default character encoding to use for parsing requests, to be applied to headers of individual parts and to form fields. Default is ISO-8859-1, according to the Servlet spec. If the request specifies a character encoding itself, the request encodin

docs.spring.io

 

2. form 태그에서 인코딩 방식 설정

<form action="reg" method="post" enctype="multipart/form-data">
                    ...
                    ...
</form>

인코딩 기본 설정은 application/x-www-form-urlencoded이기 때문에 위처럼 인코딩 방식을 따로 설정해줘야한다.

 

3. Dependncy 설정

파일업로드에 필요한 라이브러리 사용을 위해 Maven을 통해 Dependency를 설정해준다.

<!-- https://mvnrepository.com/artifact/commons-fileupload/commons-fileupload -->
<dependency>
    <groupId>commons-fileupload</groupId>
    <artifactId>commons-fileupload</artifactId>
    <version>1.4</version>
</dependency>

 

아래 링크에 해당 라이브러리 메이븐 레포지터리를 첨부한다.

- Apache Commons FileUpload

https://mvnrepository.com/artifact/commons-fileupload/commons-fileupload

 

4. 코드 작성

 1) jsp 파일

<form action="reg" method="post" enctype="multipart/form-data">
    <div class="margin-top first">
        <h3 class="hidden">공지사항 입력</h3>
        <table class="table">
            <tbody>
                		...
                <tr>
                    <th>첨부파일</th>
                    <td colspan="3" class="text-align-left text-indent"><input type="file"
                            name="files" /> </td>
                </tr>
                <tr>
                    <th>첨부파일</th>
                    <td colspan="3" class="text-align-left text-indent"><input type="file"
                            name="files" /> </td>
                </tr>
                    	...
            </tbody>
        </table>
    </div>
    <div class="margin-top text-align-center">
        <input class="btn-text btn-default" type="submit" value="등록" />
        <a class="btn-text btn-cancel" href="list.html">취소</a>
    </div>
</form>

 첨부파일 2개의 name을 files로 통일했다. 따라서 전송시 배열형태로 서버로 전송한다.

 

 2) java 파일

@RequestMapping("reg")
@ResponseBody
public String reg(MultipartFile[] files, HttpServletRequest request) throws IllegalStateException, IOException {

    for(MultipartFile file : files) {  // 파일을 배열에서 하나씩 받아옴
        long size=file.getSize();      // 파일 사이즈 받아옴
        String fileName=file.getOriginalFilename();     // 파일 이름 받아옴
        ServletContext ctx=request.getServletContext();

        String webPath="/static/upload";  // 홈 디렉터리에서부터 파일 설치할 폴더까지의 경로
        String realPath=ctx.getRealPath(webPath); // ServletContext를 통해 절대경로를 받아옴

        //realPath에 해당 폴더가 존재하지 않으면 경로상 모든 디렉터리 생성해줌
        File savePath = new File(realPath);
        if(!savePath.exists())
            savePath.mkdirs();

        realPath+=File.separator+fileName;  // 저장할 폴더까지의 절대경로 + 구분자 + 파일명
        File saveFile = new File(realPath); // os에 마다 구분자가 다르므로 File.separator 사용이 바람직

        file.transferTo(saveFile);  // 해당 경로에 파일 저장
    }
}

위와 같이 설정 후 코드를 작성하면, 첨부파일을 n개 이상 첨부할 수 있는 다중 파일 업로드가 가능하다.

 

 

※주의해야할 점

실제로 파일이 저장되는 경로는 위에서 구한 절대경로가 아니다.위에서 구한 경로인 (자신의 프로젝트 폴더)\webprj\src\main\webapp\static 가 아닌(자신의 프로젝트 폴더)\.metadata\.plugins\org.eclipse.wst\server.core\tmp0\wtpwebapps\webprj\static\upload에 저장이 된다.