본문 바로가기

Spring

Spring Interceptor 적용하기

728x90

스프링에서는 요청에 공통적으로 처리할 수 있는 3가지 개념이 있다.

  • Filter
  • Interceptor
  • AOP

이 세가지는 어떤 타이밍에 처리하는지에 따라 나뉘는데 그 중 Interceptor에 대한 간단한 개념과 설정에 대해 말하려고한다.

 

 

Dispatcher Servlet

인터셉터 전에 먼저 Dispatcher Servlet에 대해 조금 알아야 이해하기 쉽다.

그림이 눈에 안들어올 수 있는데 자세히 집중을 해봐야한다.

태초에는 컨트롤러의 개념x 스프링 개념x  웹 애플리케이션을 만들기 위해선 요청 서블릿을 직접 생성해서 응답을 해야했고, 서블릿에 url을 매핑하려면 서블릿이 많이 늘어날 수 밖에 없었다.

 

dispatcher servlet은 요청마다 이 서블릿들을 매핑해주는 서블릿 관리자같은 개념이다. 지금의 스프링에서는 컨트롤러의 개념이 있기 때문에 쉽게 요청마다 컨트롤러를 매핑해주는 고마운 친구라고 생각하면 된다.

 

 

Interceptor

위 그림에서는 HandlerInterceptor로 표기되어있는데 간단하게 순서를 글로 써보면

요청 -> 필터 -> Dispatcher Servlet -> 인터셉터 -> 컨트롤러 

컨트롤러 -> 인터셉터 -> Dispatcher Servlet -> 필터 -> 응답

으로 구성되어있다. (중간에 View는 생략)

때문에 인터셉터는 컨트롤러 단위로 전, 후로 공통 동작 로직을 처리하는 것이라고 이해하면 된다.

 

 

Interceptor 설정

스프링에서 인터셉터 설정은 정말 쉽다.

인터셉터를 상속받은 클래스 파일을 생성하고 context.xml에 등록만 해주면 끝이다.

 

나의 경우는 인터셉터 패키지를 하나 만들어서 그 안에 클래스 파일을 생성해주었다.

 

 

인터셉터 클래스 생성

package com.poozim.jobcall.interceptor;

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

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

public class DefaultInterceptor extends HandlerInterceptorAdapter{

	private static final Logger log = LoggerFactory.getLogger(DefaultInterceptor.class);
	
	@Override
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
			throws Exception {
		log.info("==============================preHandle이에요");
		return super.preHandle(request, response, handler);
	}

	@Override
	public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
			ModelAndView modelAndView) throws Exception {
		log.info("==============================postHandle이에요");
		super.postHandle(request, response, handler, modelAndView);
	}

}

PreHandler는 컨트롤러 전, PostHandler는 컨트롤러 후에 실행되는 메서드다.

 

 

servlet-context.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/mvc"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:beans="http://www.springframework.org/schema/beans"
	xmlns:context="http://www.springframework.org/schema/context"
	xsi:schemaLocation="http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd
		http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd
		http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">

	<!-- DispatcherServlet Context: defines this servlet's request-processing infrastructure -->
	
	<!-- Enables the Spring MVC @Controller programming model -->
	<annotation-driven />

	<!-- Handles HTTP GET requests for /resources/** by efficiently serving up static resources in the ${webappRoot}/resources directory -->
	<resources mapping="/**" location="/" />

	<!-- Resolves views selected for rendering by @Controllers to .jsp resources in the /WEB-INF/views directory -->
	<beans:bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
		<beans:property name="prefix" value="/jsp/" />
		<beans:property name="suffix" value=".jsp" />
	</beans:bean>
	
	<context:component-scan base-package="com.poozim.jobcall" />
	
	<interceptors>
		<interceptor>
			<mapping path="/**"/>
			<exclude-mapping path="/css/**"/>
			<exclude-mapping path="/fonts/**"/>
			<exclude-mapping path="/images/**"/>
			<exclude-mapping path="/scripts/**"/>
			<exclude-mapping path="*.jsp"/>
			<exclude-mapping path="*.js"/>
			<exclude-mapping path="*.html"/>
			<exclude-mapping path="*.css"/>
			<beans:bean id="DefaultInterceptor" class="com.poozim.jobcall.interceptor.DefaultInterceptor" />
		</interceptor>
	</interceptors>
	
</beans:beans>

<interceptors>의 내용만 보면 된다.

나는 모든 요청에 적용할 기본 DefaultInterceptor를 적용하기 때문에 mapping path에 /**로 넣어주었다.

보통 ~~~.do 라던지 ~~~.json 이라던지 등의 url에 구분하는 값이 있다면 그것을 적어주는게 좋다.

 

나는 /**여서 모든 요청에 인터셉터가 로직을 처리하기 때문에 이미지나 스크립트 같은 정적 리소스에도 자꾸 인터셉터 메서드가 실행되기 때문에,  exclude 처리를 해주었다.

 

 

결과

테스트로 메인페이지 url인 경우 메에에에에인을 콘솔에 출력하도록 넣었다.

잘나온다.

728x90