본문 바로가기
국비과정/Backend

국비 83일차 - [MVC] 첨부파일 수정, 파일 다운로드 하단에 뜨기, 조회수 증가, 댓글 기능, 관리자 페이지

by Jeong.dev 2022. 7. 25.

■ 수업 파일

05.MVC2

- mvc/board/controller/FileDownServlet.java
- webapp/views/board/view.jsp
- mvc/board/controller/BoardService.java
- mvc/board/controller/ViewServlet.java
- mvc/board/controller/UpdateServlet.java

 

 

■ 첨부파일 수정 

- 수정 내용 없음 -> 기존 파일 유지, 수정 내용 있음 -> 기존 파일 삭제

 

1. UpdateServlet 파일의 doPost 내용 수정

- mvc/board/controller/UpdateServlet.java

MultipartRequest mr = new MultipartRequest(request, path, maxSize, encoding, new FileRename());

board = new Board();

board.setNo(Integer.parseInt(mr.getParameter("no")));
board.setTitle(mr.getParameter("title"));
board.setWriterId(mr.getParameter("writer"));
board.setContent(mr.getParameter("content"));

// 게시글 수정 시 기존 첨부파일이 수정되지 않으면 null 값이 나온다.
String originalFileName = mr.getOriginalFileName("upfile"); 
String filesystemName = mr.getFilesystemName("upfile");

// null이 아니면 -> 수정되었다면 
if (originalFileName != null && !originalFileName.equals("")) {
    File file = new File(path + "/" + mr.getParameter("renamedFileName")); // 기존 업로드된 파일

    // 파일이 수정되면 기존에 업로드된 파일 지우기
    if (file.exists()) { // 기존 업로드된 파일 있으면
        file.delete(); // 그 파일 삭제한다.
    }

    board.setOriginalFileName(originalFileName);
    board.setRenamedFileName(filesystemName);
} else { // null값이면 -> 수정된 내용 없으면 기존 이름 그대로 가져온다.
    board.setOriginalFileName(mr.getParameter("originalFileName"));
    board.setRenamedFileName(mr.getParameter("renamedFileName"));
}


result = new BoardService().save(board);

 

 

 

■ 첨부파일 다운로드 시 하단에 창 뜨게 하기

1. 첨부파일 버튼 jsp 수정

- webapp/views/board/view.jsp

<tr>
    <th>첨부파일</th>
    <td>
        <c:if test="${ empty board.originalFileName }">
            <span>-</span>
        </c:if>
        <c:if test="${ not empty board.originalFileName }">
            <img src="${ path }/resources/images/file.png" width="20px" height="20px">
            <a href="javascript:" id="fileDown">					
                <span>${ board.originalFileName }</span>
            </a>	
        </c:if>
    </td>
</tr>

<script>
    $("#fileDown").on("click", ()=>{
    	<%-- /board/fileDown 서블릿 지정해주기(만들기) --%>
        location.assign("${ path }/board/fileDown?oname=${board.originalFileName}&rname=${ board.renamedFileName }")
    });
</script>

- <a href="javascript:"  : 앵커태그가 반영되지만 실제로 링크가 걸리지 않는다. (a href="#" 와 동일)

   id 입력하여 아래 스크립트 작성하기 위해서 쓴다.

 

 

2. 파일 다운로드 서블릿 만들기

- mvc/board/controller/FileDownServlet.java

- URL : /board/fileDown

- doGet 요청만 지정함

- 코드 : 파일 참고

- / 이거 파일경로 역슬래시로 하려면 \\ 두번 써야한다.

 

3. (번외) 서블릿 생성 대신 저장된 파일 URL로 구현하기

- webapp/views/board/view.jsp

- 이렇게 쓰면 보안상 문제가 있기 때문에 실무에서는 사용하면 안 된다.

<c:if test="${ not empty board.originalFileName }">
    <img src="${ path }/resources/images/file.png" width="20px" height="20px">
    <a href="javascript:" id="fileDown">					
        <span>${ board.originalFileName }</span>
    </a>
    <%-- webapp(webroot) 밑에 파일이 저장되어 있으면 URL 통해서 접근 가능하다. 아래 방법으로 가능하다.
         하지만 실무에서는 서버에 저장하기때문에 서블릿을 통해 처리해줘야한다.
    <a href="${ path }/resource/upload/board/${board.renamedFileName}"
        download="${ board.originalFileName }">파일 다운</a>
    --%>
</c:if>

 

 

 

■ 조회수 증가

1. BoardService 수정

- board.controller/BoardService.java

public Board getBoardByNo(int no) {
    Board board = null;
    Connection connection = getConnection();

    board = new BoardDao().findBoardByNo(connection, no);

    // 게시글 조회수 증가 로직
    if(board != null) {
        int result = new BoardDao().updateReadCount(connection, board);

        if(result > 0) {
            commit(connection);
        } else {
            rollback(connection);
        }
    }

    close(connection);

    return board;
}

 

 

2. BoardDao 수정 (updateReadCount 메소드 생성)

public int updateReadCount(Connection connection, Board board) {
    int result = 0;
    PreparedStatement pstmt = null;
    String query = "UPDATE BOARD SET READCOUNT=? WHERE NO=?"; // 게시글 행의 번호와 조회수 가져오기

    try {
        pstmt = connection.prepareStatement(query);

        board.setReadCount(board.getReadCount()+1); // 현재 조회수에서 1 증가하기

        pstmt.setInt(1, board.getReadCount()); 
        pstmt.setInt(2, board.getNo());

        result = pstmt.executeUpdate();
    } catch (SQLException e) {
        e.printStackTrace();
    } finally {
        close(pstmt);
    }

    return result;
}

- update는 ResultSet 필요 없다.

- result = pstmt.executeUpdate();  -> result에 안 담으면 계속 롤백된다.

 

 

3. 새로 고침 시 조회수 증가 방지

1) board.controller/ViewServlet.java

- 쿠키에 조회한 게시글의 번호를 기록하여 한 번 조회하면 그 뒤에는 조회수가 올라가지 않도록 설정

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    Board board = null;
    int no = Integer.parseInt(request.getParameter("no"));

    // 1. 쿠키에 조회한 이력이 있는지 확인
    Cookie[] cookies = request.getCookies(); // 클라이언트의 모든 쿠키를 가져온다. (쿠키 없으면 null)
    String boardHistory = ""; // 조회한 게시글 번호를 저장하는 변수
    boolean hasRead = false; // 읽은 글이면 true, 안 읽었으면 false

    if(cookies != null) {
        String name = null;
        String value = null; // 쿠키 값 가져올 지역변수
        for (Cookie cookie : cookies) {
            name = cookie.getName();
            value = cookie.getValue();

            // boardHistory인 쿠키 값을 찾기
            if(name.equals("boardHistory")) {
                boardHistory = value; // 기존 값 읽어서 boardHistory에 담기

                if(value.contains("|" + no + "|")) { // contains(문자열) : 해당하는 문자열이 존재하면 true
                    hasRead = true;

                    break;
                }
            }
        }
    } 

    // 2. 읽지 않은 게시글이면 cookie에 기록
    if (!hasRead) {
        Cookie cookie = new Cookie("boardHistory", boardHistory + "|" + no + "|");

        cookie.setMaxAge(-1); // setMaxAge(-1) : 브라우저 종료되면 삭제 됨
        response.addCookie(cookie); // 클라이언트에 내려줌
    }

    board = new BoardService().getBoardByNo(no, hasRead);

    request.setAttribute("board", board);
    request.getRequestDispatcher("/views/board/view.jsp").forward(request, response);
}

 

2) board.controller/BoardService.java

 

2) board.controller/UpdateServlet.java

- true로 고정

 

 

■ 댓글 기능

- 댓글 테이블 생성

- mvc.board.controller/ReplyServlet.java 생성

- mvc/board/model/dao/BoardDao.java 수정
- mvc/board/model/service/BoardService.java 수정
- webapp/views/board/view.jsp 수정

 

■ 관리자

- mvc.admin.controller/MemberListServlet .java 생성

- mvc.common.filter/AdminFilter.java 생성

- webapp/views/common/header.jsp 수정

 

 

댓글