0%

4월 5일 연구일지 (게시판에서 새로운 글 작성 표시)

오늘의 주제는?

간만에 작성하는 연구일지입니다.
정말 많이 바빠서 포스팅도 주말에 시간을 내서 작성하게 되네요.

이번 주제는 게시판에서 새로운 글 작성 시 사이드 메뉴에 표시를 하는 것을 다루겠습니다.

위와 같이 새로운 글이 작성될 경우 옆에 new라는 버튼이 뜨게끔 하는 것이 목표입니다.

프로젝트 진행 환경은 Spring BootThymeleaf 에서 진행하고 있음을 알려드립니다.


어떻게 해야 새 글이라는 것을 알 수 있을까?

먼저 아래와 같은 순서로 구현을 생각해 보았습니다.

  1. 새 글이 작성된 기준은 조회 시점 정하기
  2. 각 게시판에서 새 글이 있는지 알기 위한 체크하는 로직이 필요하다.
  3. 새 글이 작성되었다는 것을 저장할 곳이 필요하다.
  4. 새 글이 있는 것을 어디서 조회할 것인가?
  5. 뷰 단에서 해당 값을 찾아서 있는 경우 표시를 해준다.

1번 구현법

프로젝트에서는 하루 전 작성된 글을 기준으로 하였습니다.
이것은 게시판을 저장하는 Repo에서 시간을 조회하는 메서드를 하나 만들었습니다.

List<Board> findByCreateDateAfter(LocalDateTime localDateTime);

그리고 조회할 때는 다음과 같이 사용하였습니다.

boardRepo.findByCreateDateAfter(LocalDateTime.now().minusDays(1))


2번 구현법

새 글을 알기 위해서는 DB를 조회하여 새로운 값이 있는지, 그리고 있다면 어떤 게시판에 새 글이 있는지를 알기 위한 메서드가 필요했습니다.

1
2
3
4
5
6
7
8
9
10
//구형 코드
public List<BoardCategory> getUpToDateContents() {
List<BoardCategory> list = new ArrayList<>();
List<Board> boardList = boardRepo.findByCreateDateAfter(LocalDateTime.now().minusDays(1)).stream()
.filter(board -> !board.getCategory().equals(BoardCategory.TEMP_BOARD))
.filter(board -> !board.getCategory().equals(BoardCategory.SYSTEM))
.collect(Collectors.toList());
for(Board board : boardList) { list.add(board.getCategory()); }
return list.stream().distinct().collect(Collectors.toList());
}

게시판을 저장할 때 각 게시판을 위해 BoardCategory라는 Enum을 만들어서 저장하였습니다.
사실 저 코드는 옛날 코드고 지금은 코드 리펙토링을 통해 불필요한 연산을 줄인 코드를 만들었습니다. (Java8 만세!)

1
2
3
4
5
6
7
8
public List<BoardCategory> getUpToDateContents() {
return boardRepo.findByCreateDateAfter(LocalDateTime.now().minusDays(1)).stream()
.filter(board -> !board.getCategory().equals(BoardCategory.TEMP_BOARD))
.filter(board -> !board.getCategory().equals(BoardCategory.SYSTEM))
.map(Board::getCategory)
.distinct()
.collect(Collectors.toList());
}

3번 구현법

저장할 곳은 세션을 사용하였습니다.

1
2
3
public static void setSessionDataInNewContents(HttpSession session, List<BoardCategory> categoryList) {
session.setAttribute(S_IN_NEW_CONTENTS, categoryList);
}

위와 같이 작성하여 세션에 저장하였습니다.


4번 구현법

조회를 하는 것은 Controller 단에 로그인 등에서 처음 로그인 시 저장하는 법도 생각하였지만, 만약 세션 타임 아웃 시간이 길 경우 갱신에 대한 문제도 있었습니다.
그래서 인터셉터에서 로그인 이후에 대한 호출하는 곳에서 세션에 저장하는 방법으로 구현을 하였습니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
if(hasSessionInAccount(request.getSession())) {
checkAnnotation4ClearSessionInTempData(request,handler);
checkUpToDateContents(request);

return true;
}//세션에 계정 정보가 존재하는 경우
else {
try { response.sendRedirect("/users/login"); }
catch (IOException ie ) {} //만약 리다이렉션 도중 에러가 난 경우
return false;
} //세션 정보가 존재하지 않는 경우
}

**
* 새로운 게시글이 있는지 체크하여 세션에 주입하는 메서드
* @param request
*/
private void checkUpToDateContents(HttpServletRequest request) {
SessionHelper.setSessionDataInNewContents(request.getSession(), boardService.getUpToDateContents());
}

위 코드를 참고하면 되겠습니다.


5번 구현법

뷰 단에서는 메뉴를 구현한 Thymeleaf에서 th:eachth:if를 사용하여 구현을 하였습니다.

1
2
3
4
5
6
7
<i class="fa fa-flag"></i>
<span>공지사항</span>

<span class="pull-right-container" th:each="category : ${session.NewContents}"
th:object="${category}" th:if="${category.toString()} == 'NOTICE'" >
<small class="label pull-right bg-green">new</small>
</span>

위의 thymeleaf의 반복문 내 if문 사용법에 대한 포스팅은 여기를 참고하세요.


결론

위와 같은 방법을 통해서 아래와 같이 기능을 구현하였습니다.

저와 비슷한 고민을 하셨던 분이 있다면 도움이 되셨으면 합니다.

감사합니다.