우당탕탕 개발일지

17일차_게시판 프로젝트(10) 본문

개발 프로젝트/게시물 프로젝트

17일차_게시판 프로젝트(10)

ujin302 2024. 3. 26. 18:09
반응형

1. 다중파일 첨부 

1-1. 주의 사항

파일 첨부할 때는 여러개 한번에 선택해야 함...

그렇지 않을 경우에는 마지막에 선택한 파일만 인식 

이걸 몰라서 1시간 반을 버림 ㅎㅎㅎㅎㅎㅎ

 

 

1-2. 다중파일 첨부 업로드_View

save.html

1. input 태그 

  • multiple 설정 추가 

파일 탐색기에서 여러개 파일 선택 업로드 

아래 화면처럼 파일 개수 나옴 

 

 

1-3. 다중파일 업로드_Server

BoardController.java

1. board/save 로 받음 

2. boardService.save : 전해 받은 boardDTO 값 저장 

 

 

BoardService.java

[ save 메소드 소스 ]

기존 단일 파일 첨부에서 다중 파일에 대한 로직으로 소스 변경 

 

[ 단일 처리 ]

1. 파일 저장 로직 

2. tb_board 에 게시물 관련 정보 저장 

3. tb_board_file 에 파일 관련 정보 저장

 

[ 다중 처리 ]

1. tb_board 에 게시물 관련 정보 저장   

2. 파일 저장 로직

3. tb_board_file 에 파일 관련 정보 저장

* 2,3 번은 파일 개수만큼 반복 

 

public void save(BoardDTO boardDTO) throws IOException {
    // throws IOException : save 메소드에서 발생한 예외를 상위 메소드인 BoardService 에서 처리하기 위해 사용Z
    // 상위에서 처리하는게 더 올바른 경우도 있고 해당 메소드에서 처리하는게 더 올바른 경우가 있다!

    // 파일 첨부 여부에 따라 로직 분리
    if(boardDTO.getBoardFile().isEmpty()) {
        // 첨부 파일 X

        // 1. DTO의 값들을 Entity에 옮겨담는 함수 호출
        BoardEntity boardEntity = BoardEntity.toSaveEntitiy(boardDTO);

        // 2. DB에 저장 (tb_board)
        // save : JPA가 가지고 있는 함수
        boardRepository.save(boardEntity);
    } else {
        // 파일 첨부 ㅇ
        /*
            1. DTO에 담긴 파일 추출 (실제 파일)
            2. 파일의 이름  추출
            3. 서버 저장용 이름 생성
                : 내사진.jpg -> 8397980824_내사진.jpg
            4. 저장 경로 설정
            5. 해당 경로에 파일 저장
            6. tb_Board 에 해당 데이터 save 처리 (-> 게시물 관련 Data)
            7. tb_Board_File 에 해당 데이터 save 처리 (-> 첨부파일 관련 Data)
         */
        /* 단일 첨부 파일
        MultipartFile boardFile = boardDTO.getBoardFile(); // 1
        String originalFilename = boardFile.getOriginalFilename(); // 2
        String storedFileName = System.currentTimeMillis() + " " + originalFilename; // 3
        String savePath = "E:/Board_File/" + storedFileName; // 4. 실제 존재하는 경로 값
        boardFile.transferTo(new File(savePath)); // 5
        // transferTo : 파일 저장 메소드 & 예외 발생 가능성으로 인해서 throws IOException 사용

        // 6
        BoardEntity boardEntity = BoardEntity.toSaveFileEntitiy(boardDTO); // 6-1. DTO -> Entity (id값이 없다)
        Long savedId = boardRepository.save(boardEntity).getId(); // 6-2. Entity 객체 저장(tb_board) & 저장한 id 가져오기
        System.out.println("저장한 ID (첨부파일 O ) : " + savedId);
        BoardEntity board = boardRepository.findById(savedId).get(); // 6-3. 저장한 id에 대한 Data 가져오기

        // 7
        BoardFileEntity boardFileEntity = BoardFileEntity.toBoardFileEntity(board, originalFilename, storedFileName); // 7-1. File Entity에 저장
        boardFileRepository.save(boardFileEntity); // 7-2. DB에 저장 (tb_board_file)
         */

        // 다중 첨부 파일
        // 6
        BoardEntity boardEntity = BoardEntity.toSaveFileEntitiy(boardDTO); // 6-1. DTO -> Entity (id값이 없다)
        Long savedId = boardRepository.save(boardEntity).getId(); // 6-2. Entity 객체 저장(tb_board) & 저장한 id 가져오기
        System.out.println("저장한 ID (첨부파일 O ) : " + savedId);
        BoardEntity board = boardRepository.findById(savedId).get(); // 6-3. 저장한 id에 대한 Data 가져오기

        for (MultipartFile boardFile : boardDTO.getBoardFile()) {
            String originalFilename = boardFile.getOriginalFilename(); // 2
            String storedFileName = System.currentTimeMillis() + " " + originalFilename; // 3
            String savePath = "E:/Board_File/" + storedFileName; // 4. 실제 존재하는 경로 값
            boardFile.transferTo(new File(savePath)); // 5
            // transferTo : 파일 저장 메소드 & 예외 발생 가능성으로 인해서 throws IOException 사용

            // 7
            BoardFileEntity boardFileEntity = BoardFileEntity.toBoardFileEntity(board, originalFilename, storedFileName); // 7-1. File Entity에 저장
            boardFileRepository.save(boardFileEntity); // 7-2. DB에 저장 (tb_board_file)
        }
    }
}

 

 

주의깊게 봐야하는 부분

1. 객체 변환(boardEntity) : BoardDTO -> BoardEntity

2. tb_board에 데이터 저장 및 저장된 Id 값 추출 

3. 해당 Id 에 대한 Row 데이터 추출 

4.  파일 Data 처리 로직 (파일 개수만큼 반복)

1) 매개변수 boardDTO가 가지고 있는 파일 추출 

2) originalFilename : boardEntity가 가지고 있는 원본 이름 추출 

3) storedFileName : 서버 저장용 파일명 생성 

4) savePath : 로컬 파일 저장 전체경로 설정

5) transferTo : 파일 저장 

6) tb_board_file 에 파일 관련 Data 저장 

 

 

1-4. 다중 첨부파일 상세페이지_View

detail.html

1. 파일 개수만큼 보여주기 위해 반복문 사용

2. 해당 경로에 있는 파일 보여주기 

 

 

 

1-5. 다중 첨부파일 상세페이지_Server

BoardController.java

(소스 수정 X )

요청 들어옴 

BoardService의 findById 메소드 호출  

 

 

BoardService.java

(소스 수정 X)

BoardDTO의 toBoardDTO 메소드 호출 

 

 

BoardDTO.java

toBoardDTO 메소드의 전체 소스

[ 단일 첨부 파일 ]

무조건 첫번째 파일의 이름만 사용 

 

[ 다중 첨부 파일 ]

파일을 하나씩 가져와 사용 

public static BoardDTO toBoardDTO(BoardEntity boardEntity) {
    BoardDTO boardDTO = new BoardDTO();
    boardDTO.setId(boardEntity.getId());
    boardDTO.setBoardWriter(boardEntity.getBoardWriter());
    boardDTO.setBoardPass(boardEntity.getBoardPass());
    boardDTO.setBoardTitle(boardEntity.getBoardTitle());
    boardDTO.setBoardContents(boardEntity.getBoardContents());
    boardDTO.setBoardHits(boardEntity.getBoardHits());
    boardDTO.setBoardCreatedTime(boardEntity.getCreatedTime());
    boardDTO.setBoardUpdatedTime(boardEntity.getUpdatedTime());
    boardDTO.setFileAttached(boardEntity.getFileAttached());

    if(boardEntity.getFileAttached() == 1) { // 파일 있음
        /* 단일 첨부 파일
        // 파일 이름 가져오기
        // OriginalFileName, StoredFileName : tb_board_file(BoardFileEntity)
        boardDTO.setOriginalFileName(boardEntity.getBoardFileEntityList().get(0).getOriginalFileName());
        boardDTO.setStoredFileName(boardEntity.getBoardFileEntityList().get(0).getStoredFileName());
         */

        // 다중 파일 첨부
        List<String> originalFileNameList = new ArrayList<>();
        List<String> storedFileNameList = new ArrayList<>();

        for(BoardFileEntity boardFileEntity : boardEntity.getBoardFileEntityList()) {
            // List에 파일명을 하나씩 담음
            originalFileNameList.add(boardFileEntity.getOriginalFileName());
            storedFileNameList.add(boardFileEntity.getStoredFileName());
            System.out.println("originalFileName : " + boardFileEntity.getOriginalFileName() + "& storedFileNameList : " + boardFileEntity.getStoredFileName());

        }
        boardDTO.setOriginalFileName(originalFileNameList);
        boardDTO.setStoredFileName(storedFileNameList);
    }

 

toBoardDTO

파일 기존, 서버용 파일명 DTO 객체로 변경 

 

1. List 생성 

  • originalFileNameList : 기존 파일명 List
  • storedFileNameList : 서버용 파일명 List

2. List에 원소 추가 

  • originalFileNameList : boardFileEntity의 기존 파일명 추가 
  • storedFileNameList : boardFileEntity의 서버용 파일명 추가 

3. DTO객체로 변경  

 

 

 

1-6. 결과화면 

[ tb_board_file ]

 

[ View ]

 

1-7. 유튜브 영상

https://www.youtube.com/watch?v=iBYK3U_s0qY&list=PLV9zd3otBRt7jmXvwCkmvJ8dH5tR_20c0&index=20

 

 


 

2. 댓글 내용 

2-1. ajax 사용 

ajax 사용하기 위해서는 jquery 필요 

 

detail.html

해당 url 필수! 

 

 

2-2. 댓글 작성 기능 

detail.html >> html 태그

1. input : 작성자, 내용을 작성

2. button : 댓글 작성 후 클릭하여 서버에게 데이터 전송 

3. commentWriter() : 서버에게 데이터 전송하는 메소드 

( 결과 화면은 2-5 참고 )

 

 

detail.html >> Js

commentWriter 함수 설명 

 

1. 필요한 데이터 저장 

  • writer : commentWriter(태그 id)에 대한 값을 가져와 변수에 저장 
  • comment : commentContents(태그 id)에 대한 값을 가져와 변수에 저장
  • id : 게시글 id 

2. type (요청방식)

  • post

3. url (요청주소)

  • /comment/save

4. data (요청데이터) >> json 형태로 데이터 전달 

  • "commentWriter" : writer
  • "commentContents" : comment 
  • "boardId" : id 

5. 결과

  • sucess : 성공일 경우 해당 메소드 실행
  • error : 에러 발생할 경우 해당 메소드 실행 

 

 

2-3. Controller

CommentController.java

댓글 기능 관련 Controller 클래스 생성 

 

1. /comment/save 주소로 post 요청

2. @ModelAttribute 어노테이션을 사용하여 commentDTO로 데이터 받음 

3. public 다음에 "@ResponseBody" 어노테이션 >> ajax 문법...! 

>> 해당 부분 공부 필요함.

 

 

2-4. DTO

CommentDTO.java

댓글 기능 관련 DTO 클래스 생성 

 

1. detail.html 파일에서 데이터 요청 시, 작성 명칭과 동일하게 작성

>> 동일하게 작성해야 자동으로 해당 데이터와 매핑됨

>> 2-5. [ Console ] 화면 참고! 

 

 

2-5. 결과 화면 

[ View ] 

 

[ Console ]

 

 

 

2-6. 유튜브 영상

https://www.youtube.com/watch?v=Jnv3WISlY3s&list=PLV9zd3otBRt7jmXvwCkmvJ8dH5tR_20c0&index=22

 

 

 

 

반응형