230223 Spring Boot 인터셉터-메뉴핸들러
메뉴핸들러
핸들러에서 mapper(db)와 연결이 가능.
로그인된 정보에 따라 맞는 메뉴를 들고 나간다.
작동원리를 db연결이 아니라 uri 보내기로 확인. 이해를 위해.
uri가 있으면 해당 메뉴가 활성화된 상태로 그대로 두도록. (메뉴하이라이트)
$()를 하면 얻어온 순수한태그를 제이쿼리적용가능하게 바뀐다.
제이쿼리 반복은 .each()
제이쿼리는 contains() 대신 includes().
UserAuthHandler.java
package com.codehistory.myweb.util.interceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.springframework.web.servlet.HandlerInterceptor;
public class UserAuthHandler implements HandlerInterceptor{
/*
* 1. HandlerInterceptor를 상속받습니다.
*
* preHandle()-컨트롤러 진입전에 실행
* postHandle()-컨트롤러 수행 후에 실행
* afterCompletion()-화면으로 가기 직전에 수행
*
* 2. 인터셉터클래스를 bean으로 등록
*/
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
System.out.println("인터셉터실행");
//현재세션을 얻음
HttpSession session=request.getSession();
String user_id=(String)session.getAttribute("user_id");
if(user_id==null) {//로그인이 안됨
response.sendRedirect(request.getContextPath()+"/user/login"); //로그인페이지로 리다이렉션. 절대경로로 적는다.
return false;//컨트롤러를 실행하지 않음
}
return true; //컨트롤러가 그대로 실행
}
}
WebConfig.java
package com.codehistory.myweb.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import com.codehistory.myweb.util.interceptor.MenuHandler;
import com.codehistory.myweb.util.interceptor.UserAuthHandler;
@Configuration//스프링 설정파일
public class WebConfig implements WebMvcConfigurer{
//프리핸들러
@Bean
public UserAuthHandler userAuthHandler() {
return new UserAuthHandler();
}
//포스트핸들러
@Bean
public MenuHandler menuHandler() {
return new MenuHandler();
}
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(userAuthHandler())
.addPathPatterns("/main")
.addPathPatterns("/product/*")
.addPathPatterns("/user/*")
.excludePathPatterns("/user/login")
.excludePathPatterns("/user/join");
// .addPathPatterns("/**")
// .excludePathPatterns("/user/login")
// .excludePathPatterns("/user/join")
// .excludePathPatterns("/js/*")
// .excludePathPatterns("/css/*").excludePathPatterns("/img/*");
// REST API 패스에서 제외..?
// 경로를 ("/**")로 하면 js, css, img, rest api패스까지 다 설정해줘야 한다. 따라서 /**로 하지 말고 필요한 페이지를 지정하기.
registry.addInterceptor(menuHandler())
.addPathPatterns("/main")
.addPathPatterns("/product/*")
.addPathPatterns("/user/*");
}
}
addpathPatterns를 사용할 때, 경로를 /**로 하면 전부 인터셉터를 탄다.
문제는 js, css, img, rest api패스까지 다 exludePathPatterns로 설정해줘야 함.
따라서 /**가 아닌 필요한 페이지들을 각각 지정하기.
프리핸들러에서 로그인한 아이디를 세션을 통해 받아 컨트롤러를 실행할지 안할지를 결정한다.
MenuHandler.java
package com.codehistory.myweb.util.interceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import com.codehistory.myweb.product.service.ProductMapper;
public class MenuHandler implements HandlerInterceptor{
@Autowired
private ProductMapper productMapper;
//메뉴핸들러
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
ModelAndView modelAndView) throws Exception {
String uri = request.getRequestURI();
request.setAttribute("uri", uri);
}
}
원래는 가져온 prouctMapper를 통해 db와 연결한다.
포스트핸들러에서 request객체를 통해 받은 uri를 setAttribute로 담는다.
basicLayout.html에서
<script th:inline="javascript">
console.log(JSON.parse('[[${uri}]]'));
/*
메뉴선택유지-메뉴하이라이트
sub_menu에 display:block.
sub_menu->a링크에 on클래스.
sub_menu_toggle>a에 sub_menu_select클래스.
*/
var menu=JSON.parse('[[${uri}]]'); //postHandler에서 보내주는 uri
$(".sub_menu a").each(function(index,item){
//item - a태그임
//jquery적용
//href에 uri값이 들어있는지 확인
if($(item).attr("href").includes(menu)){
$(item).addClass("on");
$(item).closest(".sub_menu").css("display","block");
$(item).closest(".sub_menu").prev().addClass("sub_menu_select");
}
});
//반복문을 안돌리고 $('a[href*='+'[[${uri}]]'+']').addClass() 로 처리할 수도 있다.
//*로 조건을 만족하는 모든 a태그 가져옴.
/*
$('a[href*='+'[[${uri}]]'+']').addClass("on");
$('a[href*='+'[[${uri}]]'+']').closest(".sub_menu").css("display","block");
$('a[href*='+'[[${uri}]]'+']').closest(".sub_menu").prev().addClass("sub_menu_select");
*/
</script>
</th:block>
</html>
각주의 세가지 과정을 해줘야 한다.
each()문을 통해 반복을 돌려 a태그를 찾아내고 속성값에 넘어온 [[${uri}]]가 포함되어 있는지 include를 통해 검사해서 과정을 처리했는데,
선택자로 원하는 태그를 찾아서 처리해도 된다.
postHandler로 메뉴활성화를 한다. 컨트롤러를 타고 나서 uri를 페이지에 보내고 페이지에서 활성화가 이루어진다.