Spring3 Intercepter 사용하기
개발언어/Java, Spring 2017. 6. 5. 10:35
Interceptor는 주로 컨트롤러 호출 전에 요청을 가로채서 별도의 처리를 해주기 위해 사용하는 기능입니다.
인터셉터는 언제 사용하지?
인터셉터가 사용되는 가장 대표적인 예는 로그인 기능입니다.
로그인 체크가 필요한 요청시 인터셉터를 설정하여 세션이 없을 경우,
로그인 페이지로 돌려보내는 기능입니다.
우선, 로그인을 구현할 때 인터셉터를 사용하지 않으면
아래 그림처럼 같은 소스코드를 복사-붙이기(CV) 해주어야 하는 번거로운 작업이 발생합니다.
물론 향후 유지보수시에도 조잡해지고 어려워지겠지요.
<인터셉터를 설정하지 않은 로그인 체크 구현>
하지만, 인터셉터 기능을 구현함으로써 이 과정을 아주 간단히 할 수 있습니다!
Spring3에 인터셉터 설정 사용하기
1. Interceptor 패키지를 만들고 그 안에 Interceptor 컨트롤러를 생성합니다.
<Intercepter.java>
public class Intercepter extends HandlerInterceptorAdapter { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { // Admin Session을 확인해서 null이면 "/", 아니면 진행합니다. try{ if(request.getSession().getAttribute("user") == null ){ response.sendRedirect("/"); return false; } } catch (Exception e) { e.printStackTrace(); } return true; } @Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { super.postHandle(request, response, handler, modelAndView); } @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { super.afterCompletion(request, response, handler, ex); } @Override public void afterConcurrentHandlingStarted(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { super.afterConcurrentHandlingStarted(request, response, handler); } }
HandlerInterceptorAdapter 상속받아 오버라이드 하는 함수의 설명을 간단히 하겠습니다.
- preHandle : 컨트롤러 이벤트 호출 전에 실행
- postHadle : 컨트롤러 이벤트 호출 후 View 페이지 출력 전 실행
- afterCompletion : Controller+View 페이지 모두 출력 후 실행
로그인 기능은 컨트롤러가 실행전 확인해야 하므로 preHandle 메서드를 사용하겠습니다.
2. Intercepter 관련 설정을 추가합니다. <mvc-config.xml>
<mvc:interceptors> <mvc:interceptor> <mvc:mapping path="/loginCheck" /> <!-- 여러가지 컨트롤러를 추가 가능 <mvc:mapping path="/admin_write"/> <mvc:mapping path="/admin_update"/> <mvc:mapping path="/admin_delete"/> --> <bean class="com.devks.interceptor.Interceptor" /> </mvc:interceptor> </mvc:interceptors>
- <mvc:interceptors>...</mvc:interceptors>: 여러개의 인터셉터를 정의할 수 있습니다.
(ex. 등급별 로그인 처리와 같은)
- <mvc:interceptor>...<mvc:interceptor> : <mvc:mapping>을 이용해 단일 인터셉터를 다수 컨트롤러로 관리가능
(ex. Admin 로그인 후 글작성/수정/삭제기능 등)
3. TestController에 테스트를 위한 RequestMapping을 등록합니다.
로그인 폼(index.jsp)에서 로그인 요청(/login)을 발생시키면,
아래 컨트롤러에서 session에 user란 key로 id와 name을 세팅하는 구조입니다.
아이디와 비밀번호가 일치하면 /loginCheck Redirect하고,
mvc_config.xml에서 설정한 인터셉터 설정에 따라 Interceptor.java 로직을 타게 됩니다.
(여기에선 admin/1234)
@RequestMapping("/login") public String login(HttpServletRequest request){ String returnURL = ""; // 웹페이지에서 받은 아이디, 패스워드 일치시 admin Session key 생성 if(request.getParameter("id").equals("admin") && request.getParameter("password").equals("1234")){ Map<String, Object> map = new HashMap<String, Object>(); map.put("user_id", "admin"); map.put("user_name", "관리자"); request.getSession().setAttribute("user", map); returnURL ="redirect:/loginCheck"; // 일치하지 않으면 로그인 페이지 재이동 } else { returnURL = "redirect:/"; } return returnURL; } /** * 로그인 체크 * @return */ @RequestMapping("/loginCheck") public String admin_main(){ return "login_check"; }
4. 체크를 위한 View(Request, Response) Page를 생성합니다.
<index.jsp> : 로그인 페이지
<form action="/login" method="post"> <input type="text" name="id" /> <input type="password" name="password" /> <input type="submit" value="로그인" /> </form>
<login_check.jsp> : 로그인 결과 페이지 (로그인 되어 있지 않으면 인터셉터에 의해 index.jsp로 전환)
<h3>Login TEST</h3> 사용자 아이디: ${sessionScope.user.user_id } <br/> 사용자 이름: ${sessionScope.user.user_name }
실행 결과 확인하기
1. http://localhost:8080/loginCheck 를 바로 실행
→ Session 정보가 없으니 Interceptor에 의해 index.jsp(로그인 폼)으로 튕김을 확인
2. http://localhost:8080/ 로 접속해 index.jsp에서 admin/1234 입력
→ Session 정보가 있으니 Interceptor를 무사통과(?) 하고 login_check.jsp로 전환됨을 확인
'개발언어 > Java, Spring' 카테고리의 다른 글
Spring 개발 - 2. Spring Project 생성/GitHub 연동 (0) | 2017.11.07 |
---|---|
Spring 개발 - 1. 개발환경구성(JDK, STS, Maven, Tomcat) (0) | 2017.11.07 |
Spring3 JSON 사용하기(JACKSON) (0) | 2017.06.04 |
(RESTful) 이미지 등 Resource 파일 인식하기 위한 설정 (0) | 2017.06.02 |
MultipartResolver 설정을 통한 파일전송 (0) | 2017.05.29 |