SMALL
안녕하세요, 코린이의 코딩 학습기 채니 입니다.
개인 포스팅용으로 내용에 오류 및 잘못된 정보가 있을 수 있습니다.
조회수 증가 처리 (조건없이)
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
기존과 동일!
새로고침을 해도 증가하지 않고, 최초 읽었을 때만 조회수가 증가되는 것을 확인할 수 있습니다.
LIST
'Java > Servlet & JSP' 카테고리의 다른 글
JSP) 게시글 및 첨부파일 삭제 (0) | 2022.07.04 |
---|---|
JSP) 파일 다운로드 (0) | 2022.07.04 |
JSP) XSS 공격 대비 - escape 처리 (0) | 2022.07.03 |
JSP) 게시글 상세보기 - 게시글 수정/삭제 권한에 따라 버튼 노출하기 (0) | 2022.07.03 |
JSP) 첨부파일이 포함된 게시글 등록 - 첨부파일 처리 (0) | 2022.07.03 |