본문 바로가기
스프링과 JPA 기반 웹 어플리케이션 개발/7부 알림

74. 스터디 알림 아이콘 변경

by Backchus 2020. 5. 12.

읽지 않은 알림이 있는 경우 메인 네비게이션 바의 알림 아이콘을 색이 있는 아이콘으로 변경한다..

 

HandlerInterceptor (Spring Framework 5.2.6.RELEASE API)

Intercept the execution of a handler. Called after HandlerMapping determined an appropriate handler object, but before HandlerAdapter invokes the handler. DispatcherServlet processes a handler in an execution chain, consisting of any number of interceptors

docs.spring.io

노티 핸들러 인터셉터 적용 범위

  • 리다이렉트 요청에는 적용하지 않기.
  • static 리소스 요청에는 적용하지 않기.

핸들러 인터셉터 등록

  • 웹 MVC 설정 커스터마이징
@Configuration
@RequiredArgsConstructor
public class WebConfig implements WebMvcConfigurer{
	// ToDo 인터셉터 등록
}

타임리프 + 부트스트랩

  • th:if 조건문으로 읽지 않은 메시지가 있는지 확인.
  • text-info 클래스로 아이콘에 파란색 적용.

핸들러 처리 이후 및 뷰 렌더링 이전에 처리를 위한 인터셉터를 작성

package me.weekbelt.studyolle.modules.notification;

@RequiredArgsConstructor
@Component
public class NotificationInterceptor implements HandlerInterceptor {

    private final NotificationRepository notificationRepository;

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response,
                           Object handler, ModelAndView modelAndView) throws Exception {
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        if (modelAndView != null && !isRedirectView(modelAndView) && authentication != null
                && authentication.getPrincipal() instanceof UserAccount) {
            Account account =  ((UserAccount) authentication.getPrincipal()).getAccount();
            long count = notificationRepository.countByAccountAndChecked(account, false);
            modelAndView.addObject("hasNotification", count > 0);
        }
    }

    private boolean isRedirectView(ModelAndView modelAndView) {
        return modelAndView.getViewName().startsWith("redirect:")
                || modelAndView.getView() instanceof RedirectView;
    }

}

 

확인하지 않은 알림의 숫자를 가져오기위해 NotificationRepository에서 countByAccountAndChecked메소드를 추가한다.

package me.weekbelt.studyolle.modules.notification;

public interface NotificationRepository extends JpaRepository<Notification, Long> {
    long countByAccountAndChecked(Account account, boolean checked);
}

 

생성한 인터셉터를 적용시킨다.

package me.weekbelt.studyolle.infra.config;

@RequiredArgsConstructor
@Configuration
public class WebConfig implements WebMvcConfigurer {

    private final NotificationInterceptor notificationInterceptor;

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        List<String> staticResourcesPath = Arrays.stream(StaticResourceLocation.values())
                .flatMap(StaticResourceLocation::getPatterns)
                .collect(Collectors.toList());
        staticResourcesPath.add("/node_modules/**");

        registry.addInterceptor(notificationInterceptor)
                .excludePathPatterns(staticResourcesPath);
    }
}

 

네비게이션 바를 보여주는 fragments.html에서 main-nav fragment의 벨부분을 수정해준다.

<nav th:fragment="main-nav" class="navbar navbar-expand-sm navbar-dark bg-dark">
   
   // .........
   
            <li class="nav-item" sec:authorize="isAuthenticated()">
                <a class="nav-link" th:href="@{/notifications}">
                    <i th:if="${!hasNotification}" class="fa fa-bell-o" aria-hidden="true"></i>
                    <span class="text-info" th:if="${hasNotification}" ><i class="fa fa-bell" aria-hidden="true"></i></span>
                </a>
            </li>
            
   // ........
</nav>

 

 

참고: https://www.inflearn.com/course/%EC%8A%A4%ED%94%84%EB%A7%81-JPA-%EC%9B%B9%EC%95%B1#

 

스프링과 JPA 기반 웹 애플리케이션 개발 - 인프런

이 강좌에서 여러분은 실제로 운영 중인 서비스를 스프링, JPA 그리고 타임리프를 비롯한 여러 자바 기반의 여러 오픈 소스 기술을 사용하여 웹 애플리케이션을 개발하는 과정을 학습할 수 있습�

www.inflearn.com