Spring.09_Spring File

이혜민·2024년 9월 8일

spring

목록 보기
10/18

< 수업 순서 - 2024.09.06 >

1. FileController

  • request 객체 : 클라이언트의 요청 정보가 저장된 객체

  • MultipartHttpServletRequest 객체 : [multipart/form-data] 형식으로 전달된 값 또는 파일을 처리하기 위한 객체

    • MultipartHttpServletRequest.getFile(String name) : 전달파일의 정보가 저장된 MultipartFile 객체를 반환하는 메소드
  • MultipartFile 객체에 클라이언트로부터 받은 파일을 서버에 저장(업로드), 저장된 전달파일에 대한 검증

  • 전달파일이 저장될 서버 디렉토리(폴더)의 시스템 경로를 반환받아 저장 - resources/images : 직접 Front Controller에서 응답, 이미지를 바로 출력할 수 있다. 모든 웹자원을 Front Controller가 View로 응답해주기 때문에

  • MultipartFile.getOriginalname() : MultipartFile 객체에 저장된 전달파일의 이름을 반환하는 메소드 - 원본 파일명

  • 서버 디렉토리에 저장될 파일에 대한 정보가 저장된 File 객체 생성 - 업로드 처리될 파일 설정

  • MultipartFile.transTo(File file) : MultipartFile 객체에 저장된 전달파일의 내용을 File 객체에 저장된 파일에 저장되도록 업로드 처리하는 메소드

2. form_one.jsp : 사용자로부터 입력받은 파일을 form 태그를 사용해 요청 페이지에 전달하기 위해 entype 속성값을 반드시 [multipart/form-data]로 설정

  • enctype 속성 : 폼 데이터를 서버로 전송할 때의 인코딩 방식 지정
    • multipart/form-data : 파일 업로드를 포함한 폼 데이터를 전송할 때 사용되며 이 방식은 파일과 텍스트 데이터 함께 전송 가능

3. upload_success_one.jsp

4. FileController(수정)

  • @RequestParam 어노테이션을 이용해 MultipartFile 객체를 매개변수로 작성

    • request.getParam 객체를 작성할 필요가 없다.
  • WebApplicationContext.getServletContext() : WebApplicationContext 객체(스프링 컨테이너)를 사용해 ServletContext 객체를 반환하는 메소드 - request 객체가 없어서 WebApplicationContext 객체를 이용해 ServletContext 객체 반환

  • model 객체로 addAttribute() 메소드를 호출하여 파일 정보 저장

  • 문제점 : 전달파일의 이름과 같은 이름의 파일이 서버 디렉토리에 있는 경우 기존 파일 대신 전달파일로 덮어 씌워 저장

  • 해결법 : 전달파일의 이름으로 서버 디렉토리에 저장하지 않고 중복되지 않는 전달파일의 이름을 중복되지 않는 이름으로 변경해 저장되도록 업로드 처리

    → 파일의 이름이 절대 중복되지 않는다.

⭐클라이언트로부터 전달받은 파일을 서버 디렉토리에 업로드 처리하는 방법

1. commons-fileupload 라이브러리를 프로젝트에 빌드 처리

5. pom.xml : commons-fileupload 라이브러리 빌드 처리

6. servlet-context.xml : [multipart/form-data] 형식으로 전달되는 값 또는 파일을 처리하는 기능을 제공하는 클래스(CommonsMultipartResolver)를 Spring Bean으로 등록

7. FileController(수정)

  • 똑같은 이름으로 값이 여러개 전달될 때 배열 or List 객체 사용
  • list 객체를 for문을 이용해 모두 업로드 처리

8. form_two.jsp : 파일 여러개 전달

  • mulitple 속성 : 파일을 여러개 입력받아 전달하기 위한 기능을 제공하는 속성

9. upload_success_two.jsp


< 게시판 만들기 >

10. 오라클 테이블, 시퀀스 생성 : file_board

  • create table file_board(num number primary key, writer varchar2(20), subject varchar2(20), filename varchar2(200));

    • 파일을 여러개 입력받아 여러개 저장하려면 테이블을 더 만들어서 num과 연결해서 사용
  • create sequence file_board_seq; : 자동 증가값

11. FileBoard DTO 클래스

12. FileBoardMapper 인터페이스

13. FileBoardMapper.xml

  • insert 명령 : 매개변수로 FileBoard 객체를 전달받아 삽입 행의 갯수 반환
  • delete 명령 : 매개변수로 게시글 번호를 전달받아 삭제 행의 갯수 반환
  • select 명령 ① : 매개변수로 게시글 번호를 받아 검색하여 해당 검색행 반환
  • select 명령 ② : 전체 행의 갯수 반환 - Paging 처리를 위해
  • select 명령 ③ : 매개변수로 Map 객체(페이징 정보)를 전달받아 검색 행들을 List 객체로 반환 - 원하는 페이지의 게시글만 검색되도록
    • 전체 행을 검색하고 그 행들에 번호를 부여한 뒤 원하는 행번호(startRow ~ endRow)만 검색하는 SQL 명령

14. FileBoardDAO 인터페이스 : FileBoardMapper 인터페이스와 동일

15. FileBoardDAOImpl DAO 클래스 : SqlSession 객체 필드를 생성하여 getMapper() 메소드 호출하여 Mppaer 메소드 호출하여 오버라이딩된 메소드의 반환값으로 작성

16. FileBoardService 인터페이스

17. Pager : 페이징 처리 관련 값들을 저장하기 위한 클래스 - 회사 내에 만들어 둔 클래스가 있음

  • 생성자 매개변수로 전달받은 값을 저장하기 위한 필드 생성

  • 생성자로 초기화된 필드값을 사용해 계싼 결과값을 저장하기 위한 필드 생성

  • calcPaging() 메소드

    • totalPage=(int)Math.ceil((double)totalSize/pageSize) : 전체 페이지 갯수는 전체 게시글의 갯수를 한 페이지에 표시할 게시글의 갯수로 나눔. 소숫점이 나올 수도 있으니 double로 형변환. 소수점이 나오면 Math.ceil() 메소드로 무조건 올림 처리. Math.ceil을 정수형으로 변환
    • statRow=(pageNum-1)*pageSize+1 : 요청 페이지에 출력될 게시글의 시작 행번호(요청 페이지의 첫글 번호)는 요청하는 페이지 번호에서 1을 빼고 한 페이지 당 출력될 게시글의 갯수에 더하기 1
    • endRow=pageNum*pageSize : 요청 페이지에 출력될 게시글의 종료 행번호는 요청 페이지 번호와 한 페이지에 출력될 게시글의 갯수를 곱한 값
    • startPage=(pageNum-1)/blockSize*blockSize+1 : 예를들어 7페이지를 요청한다면 6/5가 1이 되고 곱하기 5 더하기 1은 6. 요청한 7페이지의 시작 페이지 번호는 6
    • endPage=startPage+blockSize-1 : 현재 불럭에 출력될 시작 페이지 번호에 하나의 페이지에 출력될 페이지 번호의 갯수를 더한 뒤 1을 뺀 값
    • prevPage=startPage-blockSize : 이전 페이지에 출력될 시작 페이지 번호는 현재 페이지에 출력된 시작 페이지 번호에서 한 페이지에 출력될 페이지 번호의 갯수를 뺀 값
    • nextPage=endPage+blockSize : 다음 페이지에 출력될 시작 페이지 번호는 현재 페이지에 출력된 시작 페이지 번호에서 한 페이지에 출력될 페이지 번호의 갯수를 더한 값

19. FileBoardServiceImpl Service 클래스 : FileBoardService 인터페이스 상속받아 메소드 오버라이드, TransactionManager 기능을 사용해 롤백 처리가 필요한 메소드에 @Transactional 어노테이션 작성

  • insert, delete, select(int num) SQL 명령은 이전과 같음

  • getFileBoardList(int pageNum, int pageSize) : 메소드의 매개변수로 요청 페이지 번호와 하나의 페이지에 출력될 게시글의 갯수를 전달받아 FILE_BOARD 테이블에 저장된 행에서 페이지 번호에 해당하는 게시글 목록을 검색해 게시글 목록과 페이징 처리 관련 정보를 Map 객체의 엔트리로 추가하여 반환하는 메소드

    • Pager라는 클래스로 객체를 만들어 매개변수에 pageNum, pageSize, totalSize, blockSize 값을 전달하면 pager라는 객체가 페이징 처리를 해줌

➡️설명 : FileBoardServiceImpl에서 FileBoardService 인터페이스를 상속받아 오버라이드된 getFileBoardLiat(int pageNum, int pageSize) 메소드의 반환값은 Map(String, Object) 객체 이다. Pager라는 객체를 생성하여 페이징 처리에 관련된 정보를 가져와 사용한다. FileBoardDAO 객체의 selectFileBoardList(Map<String, Objcet> map) 메소드의 매개변수에 전달될 Map 객체를 생성 => pageMap. 생성된 pageMap 객체에 put() 메소드 호출하여 맵값 추가. startRow 라는 key와 pager.getStartRow() Pager 클래스에서 StartRow 값 가져와 value 추가. EndRow 동일. startRow와 EndRow 값이 매개변수로 설정된 FileBoardDAO 클래스의 selectFileBoardList 매개변수 호출하여 List 객체인 fileBoardList 객체에 저장. 요청 처리 메소드에게 반활될 처리 결과값을 저장하기 위한 Map 객체 생성

< 수업 순서 - 2024.09.09 >

📍 파일 업로드(Write)

1. FileController(수정) : fileBoardWrite() 메소드 작성

  • /write 페이지를 GET 방식으로 요청하면 file/board_write JSP 반환

  • POST 방식(file 폴더 밑에 있는 write 페이지를 post 방식으로 요청) : 매개변수에 @ModelAttribute 어노테이션(DTO 클래스를 이용해 값들을 여러개 이용해 전달받으려면)을 사용해 뷰에 제공할 command 객체를 만들어 fileBoard 클래스에 저장된 값을 전달, @RequestParam 어노테이션(전달값이 하나인 경우)을 사용해 MultipartFile 객체를 생성해 업로드된 파일에 대한 정보 저장

  • upload 객체가 비어있으면 upload_write 페이지 반환

  • 다운로드 기능을 제공하는 프로그램에서만 파일에 접근 가능하도록 /WEB-INF 폴더(클라이언트의 접근을 제한하고자)에 업로드 폴더 생성

  • 업로드 처리될 파일명을 생성하여 FileBoard 객체의 filename 필드값으로 변경 - 중복되지 않게 원본파일 이름 변경

  • 전달파일을 서버 디렉토리에 저장되도록 업로드 처리

    • File 객체 생성 : 매개변수로 경로와 파일명을 불러와 작성 - trensferTo() : file 객체에 저장된 경로에 저장된 파일명으로 저장하는 기능
  • FileBoardService 객체로 addFileBoard() 메소드를 호출하여 업로드된 정보를 저장(FILE_BOARD 테이블에 행으로 삽입 처리)

  • 클라이언트에게 URL 주소를 전달하여 응답 처리 - 리다이렉트 방식으로 list 응답(리다이렉트 이동)

2. board_write.jsp : 자료실(입력페이지)

📍 파일 목록(List) 표시

3. FileController(수정) : fileBoardList() 메소드 작성

  • /list 페이지를 요청

  • @RequestParam 어노테이션을 사용하여 pageNum, pageSize(전달값)을 매개변수(클라이언트로부터 전달받는 값)로 등록(400 에러 방지 : defaultValue 속성 설정), Controller에서 생성된 데이터를 뷰에 전달할 수 있는 Mapper 객체를 매개변수로 등록하여 생성

  • FileBoardService 인터페이스를 상속받은 자식클래스의 객체를 제공받아 필드에 저장되도록 의존성 주입(생성자로 인한 의존성 주입)

  • FileBoardServiceImpl 클래스의 getFileBoardList(int pageSize, int pageSize) 메소드를 호출하여 map 객체(resultMap) 반환

  • 뷰에게 데이터를 전달하기 위한 model 객체에 addAttribute() 메소드를 호출하여 pager 이름으로 pager 객체에 저장된 정보와 fileBoardList이름으로 fileBoardList에 저장된 객체 추가

  • file/board_list 반환 → model 객체에 저장된 정보 View로 전달

4. board_list.jsp : 게시글 목록과 페이지 번호 출력

📍 파일 삭제

5. board_list.jsp(수정)

  • 삭제 버튼에 onclick 속성값에 JavaScript로 함수 생성하여 설정

  • fileDelete(num) 함수가 작동한다면 "게시글을 정말로 삭제 하시겠습니가?"라는 알림뜨고 확인 클릭 시 페이지 요청(c:url 태그로 /file/delete/num=?으로 이동 - 요청 처리 메소드 호출)

6. FileController(수정) : fileBoardDelete() 메소드 작성

  • /delete 페이지를 요청하면 호출되는 메소드

  • 매개변수는 int num

  • 업로드 처리된 파일명을 제공받기 위해 삭제될 게시글을 반환받아 저장 - fileBoard

  • 업로드 처리된 파일이 저장된 서버 디렉토리의 시스템 경로를 반환받아 저장 - uploadDirectory

  • service 클래스의 remove 메소드를 호출하여 삭제

  • 서버 디렉토리에 저장된 게시글의 업로드 파일 삭제 처리

    • File 객체 : 파일 경로 지정, 파일 정보 접근, 파일 생성 및 삭제, 파일 읽기 및 쓰기
  • 리다이렉트 이동하여 list 페이지 요청

📍 파일 다운로드

7. board_list.jsp(수정)

  • 다운로드 버튼에 onclick 속성값에 JavaScript로 함수 생성하여 설정

8. FileController(수정) : fileDownload() 메소드 작성

  • 다운로드 : 서버 디렉토리에 저장된 파일을 클라이언트에게 전달하여 저장하는 기능

  • 요청 처리 메소드에 의해 반환되는 문자열(ViewName)로 다운로드 기능을 제공하는 객체의 메소드를 호출하여 서버 디렉토리에 저장된 파일을 클라이언트에게 전달하여 저장되도록 응답 처리(JSP 반환 ❌)

  • BeanNameViewResolver 객체를 사용해 요청 처리 메소드의 반환값(ViewName)으로 응답 처리 클래스의 객체를 사용해 메소드를 호출해 메소드의 명령으로 응답 처리

  • Spring Bean Configuration File(servlet-context)에 BeanNameViewResolver 클래스를 Spring Bean으로 등록 - ViewResolver 중 가장 우선순위가 높도록 설정

  • /download 페이지 요청시 호출되는 메소드

  • 다운로드 받고자 하는 게시글을 반환받아 저장 - fileBoard

  • Model 객체를 사용해 응답 처리 클래스의 메소드에서 사용할 수 있는 Request Scope 속성값을 저장하여 제공

    • 서버 디렉토리 경로, 파일명 저장
  • BeanNameViewResolver 객체에 의해 응답될 클래스의 Spring Bean 식별자(beanName)를 반환 → fileDownload 호출(FileDownload Bean 객체)

9. servlet-context.xml

  • BeanNameViewResolver 객체 : 요청 처리 메소드의 반환값(ViewName)과 같은 이름을 식별자(beanName)의 객체로 메소드를 호출해 클라이언트에게 응답 처리하기 위한 기능을 제공하는 객체

    - JSP 문서를 응답 처리하지 않고 클래스의 메소드를 호출해 응답 처리

  • 파일 다운로드 기능을 제공하는 응답 처리 클래스를 Spring Bean으로 저장

10. FileDownload : 파일 다운로드 기능을 제공하기 위한 응답 처리 클래스

  • BaenNameViewResolver 객체에 의해 실행되는 응답 처리 클래스는 반드시 AbstractView 클래스(추상 클래스)를 상속받아 작성

  • renderMergeOutputModel() 추상메소드 오버라이드 선언하여 응답 처리에 필요한 명령 작성

  • 매개변수 : Map 객체, 요청 정보가 담긴 request 객체, 응답 정보가 담긴 response 객체

  • renderMergeOutputModel() 메소드의 model 매개변수에 저장된 Map 객체를 사용해 Request Scope 속성값을 맵값으로 반환받아 사용 - uploadDirectory, uploadFilename 저장

  • 서버 디렉토리에 저장된 업로드 파일을 사용해 File 객체 생성

  • 클라이언트에게 파일을 전달하여 응답되도록 응답 파일의 형식(MimeType) 변경

  • 클라이언트에게 응답파일 크기 변경

  • 클라이언트에게 저장될 파일명을 리스폰즈 메세지 머릿부에 저장되도록 설정

  • 업로드 파일을 클라이언트에게 전달하기 위해 리스폰즈 메세지의 몸체부에 파일을 생성할 수 있는 출력스트림을 반환받아 저장

  • 서버 디렉토리에 저장된 업로드 파일의 내용을 읽기 위한 입력스트림 생성하여 저장

  • FileCopyUtils.copy(InputStream in, OutputStream out) : 입력스트림으로 원시 데이터를 읽어 출력스트림으로 전달하는 정적 메소드 - 복사 기능을 제공하는 메소드

11. Scheduler

  • 스프링 스케쥴링(Spring Scheduling) : 특정 날짜 및 시간마다 원하는 명령이 자동으로 실행하는 기능

    • 휴면 계정 처리, 정기적인 메일 전송 등의 기능이 자동 실행되도록 설정
  • 방법 1 : 스케줄링 관련 클래스를 작성하여 servlet-context.xml에 Spring Bean으로 등록하고 특정 날짜 및 시간마다 메소드 자동 호출되도록 설정

  • 방법 2 : 스케줄링 관련 클래스의 메소드에 @Scheduled 어노테이션을 사용해 메소드가 특정 날짜 및 시간마다 자동 호출되도록 설정 가능

12. servlet-context.xml

  • 스케줄링 기능을 구현하기 위해 Spring Bean Configuration File에 task 네임스페이스를 추가해 Spring-task.xsd 파일의 엘리먼트를 사용할 수 있도록 설정

  • scheduled-tasks : scheduler 엘리먼트로 실행될 객체를 설정하기 위한 엘리먼트

  • @Scheduled 어노테이션 사용시

    • task:scheduled-tasks 엘리먼트 주석 처리
    • annotation-driven 엘리먼트 작성
  • annotation-driven : 스케줄링 관련 어노테이션을 사용하기 위해 설정하는 엘리먼트

0개의 댓글