카테고리 없음

Servlet/JSP - 일반게시글 작성2(파일첨부)

thesunset 2022. 11. 16. 19:32

1. 일반게시글 작성2(파일첨부)

<com.kh.board.controlloer>BoardInsertController

1) 인코딩 설정(POST)

request.setCharacterEncoding("UTF-8");

2) 값뽑기 : multipart객체를 이용해보자

- form 태그로 전송을 하는데 일반 방식이 아닌 multipart/form-date방식으로 전송하는 경우 request.getParameter로 값 뽑기가 불가함 

=> multipart라는 객체에 값을 이관해서 다뤄야 한다.

step 0) enctype이 multipart/form-data로 잘 전송되었을 경우 true,
 전반적인 내용이 수정되도록 조건을 걸어줌

if(ServletFileUpload.isMultipartContent(request)) {

파일 업로드를 위한 라이브러리 다운로드 (http://www.servlets.com)

파일 업로드를 위한 라이브러리명 : cos.jar (com.oreilly.servlet의 약자)

다운로드해서 dev폴더에 넣어주기
복사해서 lib폴더에 넣어주기

파일 업로드를 할 때 어디에 올리는 것일까?

서버 => 관리자의 (우리) PC

webContent내에 있는 것들만 사용자에게 배포할 수 있음 => 하드디스크의 저장공간
개발 외의 자료들 resource폴더에 담으므로 'board_upfiles' 새폴더 생성하기 

 

step 1) 전송되는 파일을 처리할 작업 (전송되는 파일의 용량제한, 전달된 파일을 저장할 경로)

1_1. 전송파일 용량 제한 

* (int maxSize = 10MByte)

하기 전에 앞서 용량 단위 알아보기

Byte -> KByte -> MByte -> GByte -> TByte -> PByte ..

 1KByte == 1024Byte(2의 10승)
 1MByte == 1024Byte(2의 10승) == 1024 * 1024Byte(2의 20승)

int maxSize = 10 * 1024 * 1024; //10Mbyte

1_2. 전달된 파일을 저장할 서버의 경로 알아내기 (String savePath)
 getRealPath() 호출하는데  => 인자값으로 WebContent부터 board_upfiles폴더까지의 경로 제시 
 HttpServletRequest request
 HttpSession session
 ServletContext application

=> session을 통해 application을 생성할 수 있음

HttpSession session = request.getSession();
ServletContext application = session.getServletContext();

String savePath = application.getRealPath("/resources/board_upfiles/");

 /가 WebContent를 나타냄

값이 잘 들어갔는지 출력해보면, 

System.out.println(maxSize);
System.out.println(savePath);

= 10485760
= C:\web-workspace2\JSP_Project\WebContent\resources\board_upfiles\

잘 들어간 것을 확인할 수 있다. 

 

step 2) 서버에 업로드 작업(파일명수정)

- HttpServletRequest request => MultipartRequest multiRequest객체로 변환

MultipartRequest객체 생성 방법 : 매개변수 생성자를 이용해서 생성(cos.jar에서 제공)

[표현법]
MultipartRequest multiRequest
= new MultipartRequest(request, savePath, maxSize, 인코딩방식, 파일명을 수정시켜주는 객체) 

위 구문 한 줄 실행만으로 첨부파일이 그대로 무조건 업로드 됨
사용자가 올린 파일명은 그대로 해당폴더에 업로드하지 않는 것이 일반적이기 때문에
파일명을 수정시켜주는 객체를 생성


Q. 파일명을 수정하는 이유는?
A. 같은 파일명이 있을 경우를 대비해서 (기존의 파일과 중복), 
파일명에 한글/특수문자/공백문자가 포함된 경우 서버에 따라서 문제가 발생할 수도 있기 때문에 

기본적으로 파일명을 수정시켜주는 객체 => FileRenamePolicy객체 (cos.jar에서 제공)
=> 내부적으로 rename()호출하면서 파일명 수정
=> 기본적으로 동일한 파일명이 있을경우 뒤에 숫자를 카운트해 붙여줌
=> aaa.jpg, aaa1.jpg, aaa2.jpg

하지만 자체적으로 아래와 같이 바꿀 수도 있음 
예) kakaotalk_yyyymmdd_hhmmsssrrr카카오톡
=> 개발자가 임의로 파일명을 수정해서 절대로 파일명이 안 겹치게끔 rename해보기 

MultipartRequest multiRequest = new MultipartRequest(request, savePath, maxSize, "UTF-8", new MyFileRenamePolicy());

<com.kh.common>MyFileRenamePolicy.jsp

인터페이스 구현하기 => implements

public class MyFileRenamePolicy implements FileRenamePolicy{

반드시 미완성된rename이라는 추상메소드를 오버라이딩해서 구현해야 함
=> 기존 파일을 전달받아서 파일명 수정작업 후에 수정된 파일을 반환 시켜줄 것

매개변수 File 객체 => 반환 File객체 

 

 

- 매개변수로 원본파일 받음

public File rename(File originFile) {

- 원본 파일명 추출(확장자) => 매개변수로 전달받은 원본 파일로부터 

String originName = originFile.getName(); //"aaa.jpg"

* java-File부분 다시 한 번 복습하기 !

수정 파일명 만들기(규칙) => 최대한 이름이 겹치지 않도록
파일이 업로드된 시간(년월일시분초) + 5자리 랜덤값(10000~99999) + 확장자 
- 확장자 : 원본파일 그대로 (원본파일명에서 뽑아서)

 

원본명           수정명
aaa.jpg =>  kakao_20221114150820.jpg 형태로 변환

 

1) 파일이 업로드된 시간 추출

- SimpleDateformat 활용(자바스크립트에서 했던거=> 안한듯..?)

String currentTime = new SimpleDateFormat("yyyyMMddHHmmss").format(new Date());

2) 5자리 랜덤값 int ranNum (10000~99999) : Math.random

int ranNum = (int)(Math.random()*90000)+10000;

3) 확장자 뽑기 => String ext : substring

String ext = originName.substring(originName.lastIndexOf("."));

4) 1+2+3조합해서 수정파일명 변수에 담기

String changeName = currentTime + "_" + ranNum + ext;

5) 기존의 파일을 수정된 파일명으로 적용시켜서 리턴

return new File(originFile.getParent(), changeName);