본문 바로가기
WEB/Spring

[Spring] Spring Interceptor /Filter + 예제 실습

by 댕꼬 2022. 4. 24.

Spring Interceptor/Filter


인터셉터( Interceptor )

 

Interceptor는 HandlerInterceptor를 통해서 컨트롤러에 들어오는 요청 HttpRequest와 컨트롤러가 응답하는 HttpResponse를 가로채는 역할을 한다.

로깅, 모니터링 정보수집, 접근제어처리 등의 실제 Business Logic과는 분리되어 처리해야 하는 기능들을 넣고싶을 때 유용하며, Interceptor는 여러개 설정할 수 있으나 순서에 주의해야 한다.

 

 

 

HandlerInterceptor 제공 메서드

 

HandlerInterceptor method
boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)

: Controller 실행 전 , false 를 반환하면 request를 바로 종료
void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,ModelAndView mav)

: Controller 실행 후 호출
void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exceoption ex)

: Controller 응답 후 호출, 예외가 발생해도 실행

 

 

Interceptor 설정하기

 

servlet-context.xml파일에 다음과 같이 설정한다.

인터셉트는 설정뿐만 아니라 메서드 구현이 필요하다 (예제파일 LoggingInterceptor.java참고)

 


필터(Filter)

 

Filter는 Dispatcher에 요청이 전달되기 전/후에 url패턴에 맞는 모든 요청에 대해 부가작업을 처리할 수 있는 기능을 제공한다.

 

 

Filter 설정하기

web.xml파일에 다음과 같이 설정한다.

 


 

Interceptor와 Filter의 차이

 

1. 호출 시점

Filter는 DispatcherServlet이 실행되기 전 , Interceptor는 DispatcherServlet이 실행된 후 동작

(아래 그림 참조)

 

2. 설정 파일

Filter는 web.xml 파일에 작성 /Interceptor는 spring-servlet.xml 파일에 작성

 

3. 구현 방식

Filter는 설정만 하면 구현 가능하지만, Interceptor는 설정은 물론 메서드 구현이 필요

 

출처 : https://stargatex.wordpress.com/2015/12/08/spring-mvc-request-lifecycle/

 

 

 

Spring Framework기반 사용자정보 관리 애플리케이션


한글깨짐현상을 해결하고, 컨트롤러가 호출되기 전/후 로그 출력

 

요구사항

 

- 사용자 정보 한글 입력 시 한글깨짐현상을 해결하기 위해 필터를 사용 ( 인코딩은 UTF-8로 한다)

- 인터셉터 구현을 위해 LoggingInterceptor.java 클래스를 생성

- 컨트롤러 실행 전 요청url과 method의 종류를 디버그로그로 남긴다.

- 컨트롤러 실행 후에 연결된 View이름을 디버그로그로 남긴다.

(필터 -> web.xml 에 설정 / 인터셉터 -> servlet-context.xml에 설정 )

 

 

LoggingInterceptor.java

package com.ssafy.hw.interceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

// 구현할 인터페이스 
public class LoggingInterceptor implements HandlerInterceptor  {
	
	// 로그를 남기기위해 Logger 얻기
	private static Logger logger = LoggerFactory.getLogger(LoggingInterceptor.class);
	
	// 컨트롤러 호출 전 처리
	@Override
	public boolean preHandle (HttpServletRequest request, HttpServletResponse response, Object handler)
			throws Exception {

		logger.debug("request url : " +request.getRequestURI());
		logger.debug("request method : " + request.getMethod());
		
		return true;
	}
	
	// 컨트롤러 호출 후 처리
	@Override
	public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
			ModelAndView modelAndView) throws Exception {

		logger.debug("response : " + modelAndView.getViewName());
	}
	
}

 

web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://java.sun.com/xml/ns/javaee https://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">

	<!-- The definition of the Root Spring Container shared by all Servlets 
		and Filters -->
	<context-param>
		<param-name>contextConfigLocation</param-name>
		<param-value>/WEB-INF/spring/root-context.xml</param-value>
	</context-param>

	<!-- Creates the Spring Container shared by all Servlets and Filters -->
	<listener>
		<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
	</listener>

	<!-- Processes application requests -->
	<servlet>
		<servlet-name>appServlet</servlet-name>
		<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
		<init-param>
			<param-name>contextConfigLocation</param-name>
			<param-value>/WEB-INF/spring/appServlet/servlet-context.xml</param-value>
		</init-param>
		<load-on-startup>1</load-on-startup>
	</servlet>

	<servlet-mapping>
		<servlet-name>appServlet</servlet-name>
		<url-pattern>/</url-pattern>
	</servlet-mapping>

	<!-- 한글 처리를 위해 encoding filter를 등록한다. -->
	<filter>
		<filter-name>encoding</filter-name>
		<filter-class>org.springframework.web.filter.CharacterEncodingFilter
		</filter-class>
		<init-param>
			<param-name>encoding</param-name>
			<!-- 인코딩 방식 -->
			<param-value>UTF-8</param-value>
		</init-param>
	</filter>>
	
	<filter-mapping>
		<filter-name>encoding</filter-name>
		<!-- 모든 경로에 적용 -->
		<url-pattern>/*</url-pattern>
	</filter-mapping>


</web-app>

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="/resources/**" location="/resources/" />

	<!-- 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="/WEB-INF/views/" />
		<beans:property name="suffix" value=".jsp" />
	</beans:bean>

	<context:component-scan
		base-package="com.ssafy.hw.controller" />

	<!-- 인터셉터 빈으로 등록 -->
	<interceptors>
		<interceptor>
			<mapping path="/**" />
			<beans:bean id="commonInterceptor"
				class="com.ssafy.hw.interceptor.LoggingInterceptor">
			</beans:bean>
		</interceptor>
	</interceptors>

</beans:beans>

 

실행화면

 

이전과 달리 한글깨짐현상이 해결된것을 확인할 수 있다.

필터 설정 후 결과화면
필터 설정 전 결과화면

 

 

프로젝트를 실행하여 

메인화면 -> 등록화면 (사용자정보입력) -> 등록결과화면으로 이동하였다.

그 결과 각 화면별로 콘솔창에 요청url과 요청메소드, view이름이 출력된것을 확인할 수 있다. 

 

 

프로젝트구조

댓글