Spring Interceptor

vencott·2021년 5월 19일
0

sinc 인턴교육

목록 보기
18/18

Interceptor(인터셉터)

컨트롤러로 들어오는 Http 요청을 가로채는 역할

HandlerInterceptorAdapter 상속을 이용해서 구현

// TestInterceptor.java 
package com.sinc.intern.util.interceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

public class TestInterceptor extends HandlerInterceptorAdapter {

	@Override
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
			throws Exception {
		System.out.println("test interceptor preHandle ~~~~");
		return super.preHandle(request, response, handler);
	}

	@Override
	public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
			ModelAndView modelAndView) throws Exception {
		System.out.println("test interceptor postHandle ~~~~");
		super.postHandle(request, response, handler, modelAndView);
	}

}

servlet-context에 설정

interceptor.do로 들어오면 bean을 연결

// servlet-context.xml
	<beans:bean id="sample"
		class="com.sinc.intern.util.interceptor.TestInterceptor" />

	<interceptors>
		<interceptor>
			<mapping path="/interceptor.do" />
			<beans:ref bean="sample" />
		</interceptor>
	</interceptors>

컨트롤러에서 매핑

// HomeCtrl.java
	@RequestMapping("/interceptor.do")
	public String interceptor() {
		System.out.println("ctrl interceptor");
		return null;
	}

console

test interceptor preHandle ~~~~
ctrl interceptor
test interceptor postHandle ~~~~

더 자세한 정보 출력

// TestInterceptor.java
	@Override
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
			throws Exception {
		System.out.println("test interceptor preHandle ~~~~");
		HandlerMethod method = (HandlerMethod) handler;
		Method methodObj = method.getMethod();
		System.out.println("Bean: " + method.getBean().getClass());
		System.out.println("Method: " + methodObj);
		return super.preHandle(request, response, handler);
	}
    
// console
test interceptor preHandle ~~~~
Bean: class com.sinc.intern.HomeController
Method: public java.lang.String com.sinc.intern.HomeController.interceptor()
ctrl interceptor
test interceptor postHandle ~~~~

인터셉터를 프로젝트에 적용

로그인 세션 분리

login을 HttpSession에서 Model 방식으로 변경

-> 세션처럼 정보 유지 X

// LoginCtrl.java
    @RequestMapping(value = "/login.do", method = RequestMethod.POST)
	public String login(UserDTO dto, Model model) {
		System.out.println("user login dto: " + dto);
		Object user = service.login(dto);
		if (user != null) {
			model.addAttribute("loginUserModel", user);
		}
		return "redirect:/main.do";
	}

post 처리만 필요

LoginInterceptor.java
package com.sinc.intern.user.util;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.ui.ModelMap;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

public class LoginInterceptor extends HandlerInterceptorAdapter {

	@Override
	public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
			ModelAndView modelAndView) throws Exception {
		System.out.println("login interceptor postH ~~~");
		super.postHandle(request, response, handler, modelAndView);
	}

}

servlet-context에 인터셉터 등록

// servlet-context.java
<beans:bean id="login" class="com.sinc.intern.user.util.LoginInterceptor" />
        
<interceptor>
	<mapping path="/login.do" />
	<beans:ref bean="login" />
</interceptor>

디버깅

// LoginInterceptor.java
	@Override
	public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
			ModelAndView modelAndView) throws Exception {
		System.out.println("login interceptor postH ~~~");

		ModelMap modelMap = modelAndView.getModelMap();
		System.out.println(modelMap.get("loginUserModel"));
		super.postHandle(request, response, handler, modelAndView);
	}
    
// console
ctrl main
user loginForm
user login dto: UserDTO [id=jslim, pwd=jslim]
user service login
user dao loginRow: UserDTO [id=jslim, pwd=jslim]
user dao conn: org.mybatis.spring.SqlSessionTemplate@3b12f467
dao loginRow result: UserVO [id=jslim, pwd=jslim, name=임정섭, point=1000.0, dept=EMART, imgSrc=images.png]
login interceptor postH ~~~
UserVO [id=jslim, pwd=jslim, name=임정섭, point=1000.0, dept=EMART, imgSrc=images.png]
ctrl main

인터셉터에서 세션에 로그인 정보 심어서 전달

// LoginInterceptor.java
	@Override
	public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
			ModelAndView modelAndView) throws Exception {
		System.out.println("login interceptor postH ~~~");

		ModelMap modelMap = modelAndView.getModelMap();
		Object obj = modelMap.get("loginUserModel");
		if (obj != null) {
			HttpSession session = request.getSession();
			session.setAttribute("loginUser", obj);
		}

		super.postHandle(request, response, handler, modelAndView);
	}

세션 유무를 체크하는 인터셉터

로그인 세션이 없으면 글 작성 못하게 제한

// SessionChkInterceptor.java
package com.sinc.intern.user.util;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

public class SessionChkInterceptor extends HandlerInterceptorAdapter {

	@Override
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
			throws Exception {
		System.out.println("session interceptor preH ~~~");
		HttpSession session = request.getSession();
		if (session.getAttribute("loginUser") == null) {
			System.out.println("session is null");
			// 사용자의 요칭이 GET일경우 그 쿼리를 유지
			String uri = request.getRequestURI();
			String query = request.getQueryString();
			String path = uri;
			if (request.getMethod().equalsIgnoreCase("get")) {
				path = uri + "?" + query;
			} else {
				query = "";
			}
			session.setAttribute("dest", path);
			// 끝
			response.sendRedirect("/loginForm.do");
			return false;
		}
		return true;
	}

}
// servlet-context.xml
<beans:bean id="check"
		class="com.sinc.intern.user.util.SessionChkInterceptor" />

<interceptor>
	<mapping path="/registerForm.do" />
	<beans:ref bean="check" />
</interceptor>
// console
ctrl main
board ctrl list
board service list
board dao listRow
dao listRow result: [BoardVO [seq=2, title=안녕하세요, content=zzzz, writer=jslim, regdate=2020-02-07, viewcnt=17], BoardVO [seq=3, title=뭐라고???, content=ㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋ, writer=jslim, regdate=2020-02-07, viewcnt=0]]
session interceptor preH ~~~
session is null
user loginForm

글 작성과 로그인 분기

  • 사용자가 메인에서 로그인 하고 글 작성하는 경우
  • 비 로그인 상태로 글 작성했다가 로그인 페이지로 넘어간 경우

컨트롤러에서 메인으로 redirect 제거(리턴타입 void로)

// LoginCtrl.java
	@RequestMapping(value = "/login.do", method = RequestMethod.POST)
	public void login(UserDTO dto, Model model) {
		System.out.println("user login dto: " + dto);
		Object user = service.login(dto);
		if (user != null) {
			model.addAttribute("loginUserModel", user);
		}
	}

인터셉터에서 페이지 분기

// LoginInterceptor.java
	@Override
	public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
			ModelAndView modelAndView) throws Exception {
		System.out.println("login interceptor postH ~~~");

		ModelMap modelMap = modelAndView.getModelMap();
		Object obj = modelMap.get("loginUserModel");
		if (obj != null) {
			HttpSession session = request.getSession();
			session.setAttribute("loginUser", obj);

			// 사용자가 직접 로그인 하고 글 작성 or 글 작성을 눌렀다가 로그인
			Object destObj = session.getAttribute("dest");
			response.sendRedirect(destObj != null ? (String) destObj : "/main.do");
		}
	}

로그아웃

세션 날리기

// LogoutInterpretor.java
package com.sinc.intern.user.util;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

public class LogoutInterpretor extends HandlerInterceptorAdapter {

	@Override
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
			throws Exception {
		System.out.println("logout interpretor preH ~~~");
		HttpSession session = request.getSession(false);
		session.invalidate();
		return super.preHandle(request, response, handler);
	}

}
// servlet-context.xml
<beans:bean id="logout" class="com.sinc.intern.user.util.LogoutInterceptor" />

<interceptor>
	<mapping path="/logout.do" />
	<beans:ref bean="logout" />
</interceptor>

출처: SHINSEGAE I&C 인턴십

profile
Backend Developer

0개의 댓글