스프링 프로젝트를 진행하는 도중 인터셉터 사용법에 대해서 공부를 진행하게 되었다.
먼저 인터셉터는
한 기능을 다양한 곳에서 구현하고 싶을 때 많이 사용하는 것 같다.
예를 들어서
네이버에서 어느 창을 들어가든 왼쪽 상단에 Naver 라는 로고가 보이고
그 로고를 누르게 된다면
네이버 메인 홈페이지로 이동하게 된다.
그리고 이 기능을 네이버의 모든 곳에서 사용하게 하고 싶다.(웹툰, 지식인 등등)
그럴 때 인터셉터를 사용하는 것 같다.
나는 게시판의 상단부분인 탭바를 인터셉터로 처리할 것이다.
(저 탭바는 모든곳에서 보이게 할 것이다)
이럴 경우에 모든 JSP마다 똑같은 코드를 작성하는것은 비효율적이므로
한곳에다 코드를 만들고
그 코드를 사용해서 구현하는 방식을 선택했다.
그러기 위해서는 인터셉터를 알아야 한다.
public class TopMenuInterceptor implements HandlerInterceptor{
//인터셉터에서는 자동주입을 통해 Bean을 주입받지 못한다
//때문에 객체사용시 여기서 Bean주입말고 생성자를 통해 Bean을 주입해주자
private TopMenuService topMenuService;
//@Autowired 이거없어도 생성자 하나면 자동으로 Autowired된다.
public TopMenuInterceptor(TopMenuService topMenuService) {
this.topMenuService = topMenuService;
}
@Override
// preHandle 메세지를 통해서 모든 곳에서 반응할 수 있도록 해줌(인터셉터 기능 중 하나)
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
// TODO Auto-generated method stub
List<BoardInfoBean> topMenuList = topMenuService.getTopMenuList();
//리퀘스트 영역에 들어가게 지정해줌
request.setAttribute("topMenuList", topMenuList);
//다음단계로 나아갈 수 있도록 preHandle return을 true로 지정해준다
return true;
}
}
인터셉터를 자용하려면
일단 HandlerInterceptor를 implements 한 클래스를 생성해준다.
그리고 이곳에 내가 사용할 Service를 선언해준다(Mapper부터 이어져있는 DB와 연결된 것)
인터셉터는 중요한것이 생성자를 통해서 @Autowired를 해주어야 한다는 것이다.
그래야지만 사용이 가능하다고 한다.
그 다음 인터셉터를 구현한 클래스에
preHandle 메소드를 자동완성 해주자.
preHandle은 Controller로 흐름이 이동전에
먼저 실행된다고 한다.
반환은 true, false가 있는데
false면 controller 요청을 하지 않고 true이면 요청을 하게 된다.
필자는 위 코드처럼 PreHandle 메소드 안에서
Service를 통해 상단바를 가져왔고 그것을 request영역에 주입을 시켜주었다.
그 다음 주목할 것은 바로 ServletAppContext이다.
왜냐하면 인터셉터를 사용하려면
이곳에다가 인터셉터를 사용하겠다고 일종을 선언을 해줘야하기 때문이다.
그것은 바로 addInterceptors 메소드를 통해서 진행한다.
@Override
public void addInterceptors(InterceptorRegistry registry) {
// 바로밑에줄은 addInterceptors(스프링메소드)를 생성하면 자동으로 생기는것
WebMvcConfigurer.super.addInterceptors(registry);
//여기서부터 우리가 작성해야 하는 코드
//바로밑에줄 new의 괄호안에는 위에서 @Autowired받은것으로 인터셉터 @Autowired를 생성자로 해야하는 것에서부터 시작함
TopMenuInterceptor topMenuInterceptor = new TopMenuInterceptor(topMenuservice);
InterceptorRegistration reg1 = registry.addInterceptor(topMenuInterceptor);
//모든 요청주소에 반응하도록 /** 으로 경로를 쳐준다
reg1.addPathPatterns("/**");
}
우리는 메소드의 2번째 코드줄부터 작성해주면 된다.
new 메소드의 파라미터에 topMenuservice가 있는것은 저것을 선언한 ServletAppContex 상단에
@Autowired로 선언을 해주었고
(애초에 위에서 언급했듯이 생성자를 통해서 @Autowired를 해주었기 때문에 파라미터가 필요하다)
마지막줄에는 반응할 주소를 추가해주면 된다.
/**는 이하폴더에 전부다 추가하겠다는 뜻이다.
이후 내가 상단탭바로 구성할 JSP인
top_menu.jsp에
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<c:set var='root' value="${pageContext.request.contextPath }/"/>
<!-- 상단 메뉴 부분 -->
<nav class="navbar navbar-expand-md bg-dark navbar-dark fixed-top shadow-lg">
<a class="navbar-brand" href="${root }main">SoftCampus</a>
<button class="navbar-toggler" type="button" data-toggle="collapse"
data-target="#navMenu">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navMenu">
<ul class="navbar-nav">
<%--TopMenuInterceptor.java에서 리퀘스트영역에 topMenuList를 담아서 보냄 --%>
<c:forEach var="obj" items="${topMenuList }">
<li class="nav-item">
<%--board_info_idx가 있어야지만 어느 게시판인지 알 수 있으므로 지정해준다 --%>
<a href="${root }board/main?board_info_idx=${obj.board_info_idx}" class="nav-link">${obj.board_info_name }</a>
</li>
</c:forEach>
</ul>
<ul class="navbar-nav ml-auto">
<li class="nav-item">
<a href="${root }user/login" class="nav-link">로그인</a>
</li>
<li class="nav-item">
<a href="${root }user/join" class="nav-link">회원가입</a>
</li>
<li class="nav-item">
<a href="${root }user/modify" class="nav-link">정보수정</a>
</li>
<li class="nav-item">
<a href="${root }user/logout" class="nav-link">로그아웃</a>
</li>
</ul>
</div>
</nav>
이렇게 forEach문을 통해서 구현을 해주면 이 JSP는 우리가 위 사진에서 확인한 탭바가 구성이된다.
이후 이것을 사용할 ex)main.jsp 뭐 수정페이지 이런곳에서
top_menu.jsp를 임포트해주면 되는 것이다.
인터셉터 설정경로가 /** 이기 때문에
모든곳에서 다 반응해서 탭바가 정상적으로 나오게 될 것이다.
댓글 영역