본문 바로가기
웹 프로그래밍 기초/자바기반의 웹&앱 응용SW 개발자

자바기반의 웹&앱 응용 SW개발자 양성과정 53일차 -83

by oncerun 2020. 5. 15.
반응형

파일 업로드하기.

 

글쓰기 페이지에서 제목과 내용 그리고 사진을 저장한 뒤 post를 했을 경우 개발자 도구의 Network화면이다.

데이터를 인코딩한후 서버에 보냈는데 파일은 전송이 되지 않았습니다. 왜냐하면 전송되는 타입은 문자열이 기본이기 때문이다. 즉 쿼리 스트링을 보내는 것처럼 url로 인코딩해서 보냈습니다.

 

파일을 전송하고싶다면 보내는 쪽의 설정을 변경합니다.

 

form태그 안에서 전송방식의 기본 타입을 확인할 수 있습니다.

 <form action="reg" method="post" enctype="application/x-www-form-urlencoded">

여러 가지 타입을 받기 위해 우리는 설정을 변경해 줍니다.

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

multipart/form-data는 파일 업로드가 있는 양식 요소에 사용되는 enctype 속성의 값 중 하나이고,

multipart는 폼데이터가 여러 부분으로 나뉘어 서버로 전송되는 것을 의미합니다.

<form> 요소의 method 속성 값이 “post”인 경우에만 사용할 수 있습니다.!

multipart/form-data 타입은 바이너리로 전송하기 때문에 인코딩을 해준 뒤 서버에 저장해야 합니다.

 

파일 업로드를 위한 서블릿 설정

 

먼저 파일의 사이즈 제한을 걸어줍니다.

바이트단위입니다.

maxFileSize = 1024*1024*100 = 100MB

 

다중 파일의 사이즈를 합친 size값입니다.

maxRequestSize = 300*1024*1024

 

서버 메모리에 넣을 수 있는 한계입니다.

1mb가 넘으면 다른 디스크에 저장합니다.

fileSizeThreshold = 1024*1024

디스크의 위치를 지정해줍니다.

location 정해주지 않으면 운영체제가 사용하는 temp디렉터리에 저장됩니다.

절대 경로만 가능

 

WEB.XML 서버 전체에서 영향

 

<multipart-config>

<location>/tmp <location>

<max-file-size>1024*1024*100 </max-file-size>

<max-request-size>1024*1024*300 </max-request-size>

<file-size-threshold>1024*1024 </file-size-threshold>

</multipart-config>

 

annotation으로 개별 jsp마다 설정하기

@MultipartConfig(
fileSizeThreshold = 1024*1024,
maxFileSize = 1024*1024*100,
maxRequestSize = 300*1024*1024
)

 

form태그 안에 존재하는 파일 타입의 input이 존재합니다.

<input type="file"name="file" />

이제 submit버튼을 눌렀을 때 서버에서 받기 위해 controller에서 로직을 준비합니다.

 

part정보에 있는 content를 얻기 위해 request를 이용합니다.

Part part = request.getPart("file");

part는 바이너리 컨텐트를 넘겨주기 때문에  받기 위해

part.getInputStream(); 을 가져옵니다.

스트림을 통해 전달받은 파일을 저장해야 합니다.

 

저장하기 위한 경로는 시스템 경로가 필요합니다.

만약 /upload에 저장한다면 루트를 통한 경로를 넘겨줬을 때 물리 경로를 받환해주는 함수가 필요합니다.

request.getServletContext(). getRealPath("/upload");

 

Part part = request.getPart("file");
fileName =part.getSubmittedFileName();//얻어온 파일의 이름을 얻어옵니다.
String path = "/upload";
String realPath =request.getServletContext().getRealPath(path); //시스템경로

 

InpuStream fis = filePart.getInputStream(); 을  fis라 정의해준뒤

 

int b =fis.read(); 1바이트값씩을 읽어줍니다. 다읽었을 경우 -1을 리턴합니다. 따라서 int형 반환함수입니다.

 

실제파일을 저장하기위한 물리경로

 

realPath에 파일명을 붙여야합니다. 붙여주기위해 구분자가 필요합니다. 운영체제마다 구분자가 다르므로 함수를 사용해줍니다.

String filePath = realPath+File.separator+fileName;

FileOutputStream fos = new FileOutputStream(filePath);

 

1바이트씩하지않고 바이트배열로 받습니다. 

byte[] buf = new byte[1024]; 1kb씩 저장하기위한 공간

int size =0; //데이터의 개수를 받는 size

while((size=fis.read(buf)) != -1 ){ 

  읽었으면 사용합니다.

fos.write(buf,0,size) 버퍼의 담긴내용 출력

0부터 size길이만큼 반복해 저장합니다.

}

 

 

반응형

댓글