처음부터 차근차근

기업형 mvc 모델과 파일 업로드, String.join() 본문

프로그래밍/JSP

기업형 mvc 모델과 파일 업로드, String.join()

_soyoung 2022. 1. 11. 01:12
반응형

기업형 mvc 모델

(패키지 따로 만들기)controller -> servlet class

service class 객체 만들어서 함수 호출하고 그 값 table class 객체 만들어서 대입한 후 

request.setAttribute('a', a);.

그다음 jsp 파일 forwarding.

IndexController - index.jsp(메인) 화면에 출력하는 controller

별다른 내용없고 forwarding만함

 

view -> jsp 파일(WEB-INF 디렉터리 아래)

 

model ->

(패키지 따로 만들기)service class - 실질적인 서비스를 담당하는 class

데이터베이스 관련 내용 들어감.

안에 들어있는 함수들은 최대한 함수를 재사용해서 구현.

예를들어서 return 아래에있는함수(); 이렇게

 

(패키지 따로 만들기)table class - getter, setter, 생성자, toString()함수

view class

 

 

 

파일 업로드

인코드 방식

1. url 인코딩 방식

html form을 통해 데이터를 웹 서버로 submit 할 때 enctype을 생략했거나 enctype="application/x-www-form-urlencoded" 이면 사용되는 기본 인코딩 방식이다.

웹 서버에 데이터를 문자열로 전송한다.

쿼리 스트링 모양이다.

ex) name=ksy&age=22&id=1

 

2. multipart/form-data

웹 서버에 파일을 전송할 때 사용하는 인코딩 방식이다.

form에 enctype="multipart/form-data"를 쓰면 사용되는 인코딩 방식이다.

파트로 나눠서 웹서버에 전송한다.

ex) content-disposition : form-data; name="id"

1

content-disposition : form-data; name="name"

ksy

content-disposition : form-data; name="file"; filename="test.jpg"

6545G54564E452...

 

form에 enctype만 추가한다고 웹 서버에 파일이 전송되지 않는다.

파일을 전송하려면 파일 관련 설정을 해야한다.

 

 

파일 관련 설정 방법 2가지

1.  web.xml 사용

<multipart-config>
	<location>/tmp</location>
    <max-file-size>20848820</max-file-size>
    <max-request-size>20848820</max-request-size>
    <file-size-threshold>1048576</file-size-threshold>
</multipart-config>

2. annotation 사용

@MultipartConfig(
		fileSizeThreshold = 1024*1024,
		maxFileSize = 1024*1024*50,
		maxRequestSize = 1024*1024*50*5
		)


fileSizeThreshold : (1kb * 1kb = 1mb) 파일 크기가 1mb를 넘을 경우에는 서버 메모리가 아닌 디스크를 사용해서 일시저장한다.
maxFileSize : (1kb * 1kb * 50 = 50mb) 보낼 수 있는 하나의 파일 사이즈 최대 크기는 50mb이다. 

maxRequestSize : (1kb * 1kb * 50 * 5= 250mb = 250mb) 전체 파일 사이즈 최대 크기는 250mb이다.

 

 

단일 file 업로드

html 코드

<form action="addPeople" enctype="multipart/form-data">
	<input type="file" name="file_n">
</form>

servlet class에서 file 받기

Part filePart = request.getPart("file_n"); // 바이너리를 넘겨주는 것
InputStream fis = filePart.getInputStream(); // 바이너리 받는 stream == System.in

// 전달 받은 파일의 저장 경로는 절대 경로를 지정해줘야함.(상대 경로 x)
// getRealPath : root를 통한 상대경로를 넘겨주면 그 시스템에 있는 절대경로(물리경로)를 반환하는 함수
String realPath = request.getServletContext().getRealPath("/upload"); // c:Users/user/....
String fileName = filePart.getSubmittedFileName(); // 파일명 대입
String filePath = realPath + File.separator + fileName;// 실제 파일 경로! pathSeparator == \

FileOutputStream fos = new FileOutputStream(filePath); // 바이너리 출력하는 stream


int size = 0; // 읽어온 데이터 byte의 개수
byte[] buf = new byte[1024]; // 1kb buffer
while((size = fis.read(buf)) != -1) { // 파일을 1kb씩 읽음. file 끝까지 다 읽으면 -1반환
    fos.write(buf, 0, size); // 정해놓은 filePath에 1byte씩 내용을 적어넣음
}
//fis.read(buf) : 마지막까지 버퍼 크기만큼 다 쓰는거
//fis.read(buf, 0, size) : 버퍼 지정한 크기만큼 쪼개서 쓰는거 // 이게 훨씬 속도면에서 빠름

fos.close();
fis.close();

 

 

 

다중 파일 업로드

html 코드

<form action="addPeople" enctype="multipart/form-data">
    <input type="file" name="file_n">
    <input type="file" name="file_n">
</form>

servlet class에서 file 받기

Collection<Part> parts = request.getParts();	 
StringBuilder builder = new StringBuilder(); // db에 넣을 문자열 구하기(filename, filename, filename... 이런식으로 넣을 예정)    	


for (Part p : parts) {

    if(p.getName().equals("file_n")) continue; 
    // 두개의 파일 중 하나만 들어왔을 경우 안들어온 file의 size는 0임. 하나만 등록되거나 아무것도 등록안됬을 때도 error나지 않음
    if(p.getSize() == 0) continue; 

    Part filePart =  p;// 바이너리를 넘겨주는 것
    InputStream fis = filePart.getInputStream(); // 바이너리 받는 stream == System.in


    // 전달 받은 파일의 저장 경로는 절대 경로를 지정해줘야함.(상대 경로 x)
    // getRealPath : root를 통한 상대경로를 넘겨주면 그 시스템에 있는 절대경로(물리경로)를 반환하는 함수
    String realPath = request.getServletContext().getRealPath("/upload"); // c:Users/user/....
    String fileName = filePart.getSubmittedFileName(); // 파일명 대입
    String filePath = realPath + File.separator + fileName;// 실제 파일 경로! pathSeparator == \

    File path = new File(realPath);
    if(!path.exists()) { // realPath가 존재하지 않으면
        path.mkdirs(); // 부모 path나 내 path가 없으면 알아서 만들어줌
    }

    builder.append(fileName);
    builder.append(",");

    FileOutputStream fos = new FileOutputStream(filePath); // 바이너리 출력하는 stream


    int size = 0; // 읽어온 데이터 byte의 개수
    byte[] buf = new byte[1024]; // 1kb buffer
    while((size = fis.read(buf)) != -1) { // 파일을 1kb씩 읽음. file 끝까지 다 읽으면 -1반환
        fos.write(buf, 0, size); // 정해놓은 filePath에 1byte씩 내용을 적어넣음
    }
    //fis.read(buf) : 마지막까지 버퍼 크기만큼 다 쓰는거
    //fis.read(buf, 0, size) : 버퍼 지정한 크기만큼 쪼개서 쓰는거 // 이게 훨씬 속도면에서 빠름

    fos.close();
    fis.close();
}

builder.delete(builder.length() - 1, builder.length()); // 마지막 콤마 빼기
// 나중에 people.setFiles(builder.toString()); 해서 db에 값 추가

 

 

+ tomcat은 WebContent를 Root(/)로 본다.

그래서 /upload 는 workspace 상에서 WebContent / upload 디렉터리를 뜻함.

 

+ 저장된 파일은 workspace에서는 보이지 않는다.

절대 경로에 저장되기 때문임...

 

 

String.join(",", 문자열리스트);

: 리스트의 원소들 사이에 ,를 찍어 새 문자열 반환

ex) a b c d e

->a, b, c, d, e

 

 

 

 

출처 : https://www.youtube.com/playlist?list=PLq8wAnVUcTFVOtENMsujSgtv2TOsMy8zd 변형 및 요약 

반응형

'프로그래밍 > JSP' 카테고리의 다른 글

JDBC  (0) 2022.01.12
jstl  (0) 2022.01.10
model1과 model2 방식 특징, 라이브러리의 위치, View 페이지 은닉  (0) 2022.01.09
EL  (0) 2022.01.08
JSP  (0) 2022.01.06
Comments