본문 바로가기
Java/Servlet & JSP

JSP) 조회수 증가 처리

by 박채니 2022. 7. 4.

안녕하세요, 코린이의 코딩 학습기 채니 입니다.

 

개인 포스팅용으로 내용에 오류 및 잘못된 정보가 있을 수 있습니다.


조회수 증가 처리 (조건없이)

 

Controller

BoardViewServlet

@WebServlet("/board/boardView")
public class BoardViewServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
	private BoardService boardService = new BoardService();

	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		try {
			// 1. 사용자입력값 처리
			int no = Integer.parseInt(request.getParameter("no"));
			
			// 2. 업무로직 
			Board board = boardService.findByNo(no);
			
			// XSS 공격대비 (Cross-site Scripting)
			board.setContent(HelloMvcUtils.escapeXml(board.getContent()));
			board.setTitle(HelloMvcUtils.escapeXml(board.getTitle()));
			
			// 개행문자 변환처리
			board.setContent(HelloMvcUtils.convertLineBeedToBr(board.getContent()));
			
			// 3. view단 처리
			request.setAttribute("board", board);
			request.getRequestDispatcher("/WEB-INF/views/board/boardView.jsp").forward(request, response);
		} catch(Exception e) {
			e.printStackTrace();
			throw e;
		}
	}
}

 

Service

BoardService

public Board findByNo(int no) {
    Connection conn = getConnection();
    Board board = null;
    try {
        int result = boardDao.updateReadCount(conn, no);

        // board 테이블에서 조회
        board = boardDao.findByNo(conn, no);

        // attachment 테이블에서 조회
        List<Attachment> attachments = boardDao.findAttachmentByNo(conn, no);
        ((BoardExt) board).setAttachments(attachments);
        commit(conn);
    } catch(Exception e) {
        rollback(conn);
        throw e;
    } finally {
        close(conn);			
    }
    return board;
}

 

Dao

BoardDao

// updateReadCount = update board set read_count = read_count + 1 where no = ?
public int updateReadCount(Connection conn, int no) {
    PreparedStatement pstmt = null;
    int result = 0;
    String sql = prop.getProperty("updateReadCount");

    try {
        pstmt = conn.prepareStatement(sql);
        pstmt.setInt(1, no);
        result = pstmt.executeUpdate();
    } catch (SQLException e) {
        throw new BoardException("조회수 증가처리 오류!", e);
    } finally {
        close(pstmt);
    }
    return result;
}

새로고침할 때마다 조회수가 증가처리 되는 것을 확인할 수 있습니다.

하지만, 이러한 조회수 증가는 없죠..

조회수 증가에 따른 조건을 설정해줘야 합니다. (회원에 따라, 브라우저에 따라 등등)


조회수 증가 처리 (조건 O)

- 브라우저에 따라 관리

 

Controller

BoardViewServlet

@WebServlet("/board/boardView")
public class BoardViewServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
	private BoardService boardService = new BoardService();

	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		try {
			// 1. 사용자입력값 처리
			int no = Integer.parseInt(request.getParameter("no"));
			
			// 읽음 여부 판단
			Cookie[] cookies = request.getCookies();
			String boardCookieVal = "";
			boolean hasRead = false;
			
			if(cookies != null) {
				for(Cookie cookie : cookies) {
					String name = cookie.getName();
					if("boardCookie".equals(name)) {
						boardCookieVal = cookie.getValue();
						if(boardCookieVal.contains("[" + no + "]")) {
							hasRead = true;
						}
						break;
					}
				}
			}
			
			// 쿠키 처리
			if(!hasRead) {
				Cookie cookie = new Cookie("boardCookie", boardCookieVal + "[" + no + "]");	// 기존 존재하던 value + 현재 조회한 [no]
				cookie.setPath(request.getContextPath() + "/board/boardView");
				cookie.setMaxAge(365 * 24 * 60 * 60);
				response.addCookie(cookie);
			}
			
			
			// 2. 업무로직 
			Board board = hasRead ? boardService.findByNo(no) : boardService.findByNo(no, hasRead);
			
			// XSS 공격대비 (Cross-site Scripting)
			board.setContent(HelloMvcUtils.escapeXml(board.getContent()));
			board.setTitle(HelloMvcUtils.escapeXml(board.getTitle()));
			
			// 개행문자 변환처리
			board.setContent(HelloMvcUtils.convertLineBeedToBr(board.getContent()));
			
			// 3. view단 처리
			request.setAttribute("board", board);
			request.getRequestDispatcher("/WEB-INF/views/board/boardView.jsp").forward(request, response);
		} catch(Exception e) {
			e.printStackTrace();
			throw e;
		}
	}
}

boardCookie 를 가져와서 기존 데이터에 현재 조회한 [no]이 존재한다면 hasRead는 true로 변경해주었습니다.

만일 기존 cookie value에서 현재 조회한 [no]이 조회되지 않는다면 hasRead는 그대로 false를 유지하게 됩니다.

 

이를 이용하여 쿠키 처리를 해주었고, 만약 hasRead가 false라면 boardCookie에 기존 value + 현재조회한 [no]을 추가해줍니다.

hasRead 값을 이용하여 true라면, 단순 게시글 조회 / false라면, 단순 게시글 조회 + read 카운팅 처리해줍니다.

 

Service

BoardService

public Board findByNo(int no) {
    return findByNo(no, true);
}

public Board findByNo(int no, boolean hasRead) {
    Connection conn = getConnection();
    Board board = null;
    try {
        if(!hasRead) {
            int result = boardDao.updateReadCount(conn, no);				
        }

        // board 테이블에서 조회
        board = boardDao.findByNo(conn, no);

        // attachment 테이블에서 조회
        List<Attachment> attachments = boardDao.findAttachmentByNo(conn, no);
        ((BoardExt) board).setAttachments(attachments);
        commit(conn);
    } catch(Exception e) {
        rollback(conn);
        throw e;
    } finally {
        close(conn);			
    }
    return board;
}

코드의 중복을 줄이기 위하여 위와 같이 코드를 짰습니다.

 

Dao

BoardDao

기존과 동일!

새로고침을 해도 증가하지 않고, 최초 읽었을 때만 조회수가 증가되는 것을 확인할 수 있습니다.