목차
Interceptor의 개념
쇼핑몰 사이트를 만들 경우, 장바구니, 찜하기, 주문 페이지에 들어가려면 반드시 로그인이 되어있어야 한다.
이때 아래 코드와 같이 각 맵핑 메소드마다 session을 체크해 접속을 체크할 수도 있다.
@GetMapping("/member/regist.do")
public String regist(HttpSession sess) {
/* 로그인 여부 체크 */
if(sess.getAttribute("loginSess") == null) return null;
return "member/write";
}
그러나 이 경우 장바구니, 찜하기, 주문 페이지 등 로그인을 요구하는 모든 페이지에서 Session을 체크하는 코드를 추가해야 한다.
이렇게 모든 메소드에 Session체크를 하는 부분을 다 코딩해 넣지 않고도 AOP개념을 활용해 Session을 체크하는 하나의 코드만 만든 후, 모든 요청이 들어오기 전에 먼저 Session을 체크한 후, 요청을 처리할 수 있게 하는 것이 Interceptor이다.
Interceptor 만들기
Interceptor클래스 만들기
Interceptor클래스를 만든다.
Interceptor는 HandlerInterceptor인터페이스를 구현해 만든다.
HandlerInterceptor 인터페이스의 3가지 메소드
- preHandle() : url이 컨트롤러에 도달하기 전에 수행
- postHandle() : url이 컨트롤러에 도달한 후에 수행
- afterCompletion() : 뷰를 실행한 후에 수행
Interface는 대개 preHandle()함수를 주로 사용한다.
preHandle()함수에서 로그인 여부를 체크해 요청을 거절하면 요청은 컨트롤러에 도달하지 않는다.
public class UserLoginInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request,
HttpServletResponse response,
Object handler) throws Exception {
/* session에서 login여부를 확인 */
HttpSession sess = request.getSession();
UserVO login = (UserVO)sess.getAttribute("loginInfo");
if (login == null) {
/* 로그인 정보가 없을 경우 경고를 띄우고 로그인 하는 곳으로 이동 */
response.setContentType("text/html; charset=utf-8");
PrintWriter out = response.getWriter();
out.print("<script>");
out.print("alert('로그인 후 사용가능합니다.');");
out.print("location.href='/user/login.do';");
out.print("</script>");
out.close();
return false; /* Controller로 이동 차단 */
}
return true; /* 로그인 정보가 있을 경우 Controller로 이동 */
}
}
Interceptor Bean객체 등록
Config파일에 Interceptor객체 등록
// 인터셉터
@Bean
public UserLoginInterceptor userLoginIntercepton() {
return new UserLoginInterceptor();
}
Config파일에서 Interceptor 주입
@Override
public void addInterceptors(InterceptorRegistry registry) {
/* 빈 객체 주입 및 url 설정 */
registry.addInterceptor(userLoginIntercepton()) // 빈 객체 주입
/* user 아래로 오는 모든 요청에 대해 로그인 여부를 검사하되 */
.addPathPatterns("/user/**")
/* 아래 요청들은 로그인 여부 검사에서 제외 */
.excludePathPatterns("/user/join.do")
.excludePathPatterns("/user/login.do")
.excludePathPatterns("/user/idCheck.do")
.excludePathPatterns("/user/emailCheck.do")
.excludePathPatterns("/user/regist.do");
}
여러개의 Interceptor Bean을 등록/설정하기
아래 코드와 같이 registry에 여러개의 interceptor를 추가해주면 된다.
// 인터셉터
@Bean
public UserLoginInterceptor userLoginIntercepton() {
return new UserLoginInterceptor();
}
@Bean
public SellerLoginInterceptor sellerLoginIntercepton() {
return new SellerLoginInterceptor();
}
@Bean
public CategoryInterceptor categoryInterceptor() {
return new CategoryInterceptor();
}
@Override
public void addInterceptors(InterceptorRegistry registry) {
// url 설정
registry.addInterceptor(userLoginIntercepton())
.addPathPatterns("/user/**")
.excludePathPatterns("/user/join.do")
.excludePathPatterns("/user/login.do")
.excludePathPatterns("/user/idCheck.do")
.excludePathPatterns("/user/emailCheck.do")
.excludePathPatterns("/user/regist.do");
registry.addInterceptor(sellerLoginIntercepton())
.addPathPatterns("/seller/**")
.excludePathPatterns("/seller/login.do")
.excludePathPatterns("/seller/join.do")
.excludePathPatterns("/seller/idCheck.do")
.excludePathPatterns("/seller/emailCheck.do")
.excludePathPatterns("/seller/regist.do");
registry.addInterceptor(categoryInterceptor())
.addPathPatterns("/")
.addPathPatterns("/user/**")
.addPathPatterns("/product/**");
}
Interceptor를 통해 jsp에 데이터 전달하기
public class CategoryInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request,
HttpServletResponse response,
Object handler)
throws Exception {
/* Interceptor에서 request객체를 통해 데이터를 삽입 */
request.setAttribute("ProductCategoryVO", new ProductCategoryVO());
return true;
}
}
위와 같이 Interceptor를 통해 request객체에 데이터를 삽입할 경우 해당 Interceptor를 거쳐서 도달한 모든 jsp에서 해당 데이터를 사용할 수 있게된다.
<!--
Controller에서 따로 ProductCategoryVO를 보내지 않아도
${ProductCategoryVO}를 사용할 수 있다
-->
<li>
<a>강아지</a>
<ul>
<c:forEach var="category2"
items="${ProductCategoryVO.category[0]}" varStatus="status">
<li>
<a href="/product/search.do?category1=0&category2=${status.index }">
${category2 }
</a>
</li>
</c:forEach>
</ul>
</li>
<li>
<a>고양이</a>
<ul>
<c:forEach var="category2"
items="${ProductCategoryVO.category[1]}" varStatus="status">
<li>
<a href="/product/search.do?category1=1&category2=${status.index }">
${category2 }
</a>
</li>
</c:forEach>
</ul>
</li>
<li>
<a>기타</a>
<ul>
<c:forEach var="category2"
items="${ProductCategoryVO.category[2]}" varStatus="status">
<li>
<a href="/product/search.do?category1=2&category2=${status.index }">
${category2 }
</a>
</li>
</c:forEach>
</ul>
</li>
'컴퓨터공학 > 스프링' 카테고리의 다른 글
Spring의 처리 흐름 (0) | 2023.12.11 |
---|---|
DB 접속정보 git에 공유되지 않도록 설정하기 (0) | 2023.12.10 |
[Slf4j] 스프링의 디버깅 도구 Slf4j Library (1) | 2023.12.10 |
[log4j.xml] 스프링의 디버깅 로그 자세히 띄우기 (1) | 2023.12.10 |
테스트 도구 Junit (0) | 2023.12.07 |