ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Spring MVC - Interceptor
    Spring/Spring MVC 2022. 1. 3. 22:21
    반응형

    Interceptor

    • AOP를 적용한 Spring MVC의 요소
    • Interceptor는 요청이 발생하면 Controller의 해당 메서드를 호출하기 전, 후에 Interceptor하여
      다른 메서드를 호출할 수 있도록 가로 채는 개념이다.
    • 여러 메서드들이 코드가 중복 되는 부분이 있을 때 Interceptor를 이용하면 유용하다.
    • 로그인 여부 확인, 등급별 서비스, 사용 권한 확인 등에 쓰인다.

     

     Java로 설정하는 방법과 XML로 설정하는 방법이 있다.


     

    방법 1 - Java

     

    Interceptor 구현

     따로 Interceptor 패키지를 만들어줘서 관리하자.

     

    TestInterceptor1.java         

    public class TestInterceptor1 implements HandlerInterceptor{
    	@Override
    	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
    			throws Exception {
    		System.out.println("TestInterceptor1 - prehandle ");
    		return true;
    	}
    	
    //	Controller의 메소드가 호출되고 난 후에 호출
    	@Override
    	public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
    			ModelAndView modelAndView) throws Exception {
    		
    		System.out.println("TestIntercepter1 - postHandle");
    	}
    	
    //	View 처리까지 완료되면 호출
    	@Override
    	public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
    			throws Exception {
    
    		System.out.println("TestIntercepter1 - afterCompletion");
    	}
    }
    public class TestInterceptor1 implements HandlerInterceptor{
     - preHandle, postHandle, afterCompletion를 override 하기 위해 HandlerInterceptor를 상속받는다.
     - 필요한 메서드만 override하면 된다.

    preHandle
     - Controller의 메서드가 호출되기 전 호출
     - false를 반환하면 코드의 흐름이 중단된다. Controller의 메서드로 가지도 않고, postHandle, afterCompletion,
    또 다른 Intercepter들 모두 중단된다.

    postHandle
     - Controller의 메서드가 호출된 후 호출

    afterCompletion
     - View 처리까지 완료되고 응답 결과가 브라우저로 전달하기 전에 호출

     

     

    ServletAppContext.java에 Interceptor 등록

    ServletAppContext.java

    ....
    public class ServletAppContext implements WebMvcConfigurer{
    	
        .....
    	
    //	인터셉터를 등록한다.
    	public void addInterceptors(InterceptorRegistry registry) {
    		WebMvcConfigurer.super.addInterceptors(registry);
    		
    		TestInterceptor1 inter1 = new TestInterceptor1();
    		TestInterceptor2 inter2 = new TestInterceptor2();
    		TestInterceptor3 inter3 = new TestInterceptor3();
    		TestInterceptor4 inter4 = new TestInterceptor4();
    		TestInterceptor5 inter5 = new TestInterceptor5();
    		
    		InterceptorRegistration reg1 = registry.addInterceptor(inter1);
    		InterceptorRegistration reg2 = registry.addInterceptor(inter2);
    		InterceptorRegistration reg3 = registry.addInterceptor(inter3);
    		InterceptorRegistration reg4 = registry.addInterceptor(inter4);
    		InterceptorRegistration reg5 = registry.addInterceptor(inter5);
    		
    		reg1.addPathPatterns("/test1");
    		reg2.addPathPatterns("/test1");
    		reg3.addPathPatterns("/test2"); 
    		// 둘다 적용 - 방법1
    //		reg4.addPathPatterns("/test1");
    //		reg4.addPathPatterns("/test2");
    		// 방법2
    		reg4.addPathPatterns("/test1", "/test2");
    		
    //		reg5.addPathPatterns("/sub1/test3", "/sub1/test4");
    		reg5.addPathPatterns("/sub1/*");
    		
    //		설정된 경로중 제외할 경로
    		reg5.excludePathPatterns("/sub1/test3");
    		
    		
    	}
    }
    public void addInterceptors(InterceptorRegistry registry) {
            WebMvcConfigurer.super.addInterceptors(registry);
     - Interceptor 등록을 위해 addInterceptors 메서드를 override 해주면 된다.

    TestInterceptor1 inter1 = new TestInterceptor1();
     - Interceptor 등록을 위해 위에서 작성한 TestInterceptor1 객체 생성

    InterceptorRegistration reg1 = registry.addInterceptor(inter1);
     - Interceptor 등록

    reg1.addPathPatterns("/test1");
     - 등록한 interceptor가 적용할 URI 설정

    Interceptor를 적용할 URI 설정 방법 
     - addPathpatterns를 이용하여 여러 URI 설정
            reg4.addPathPatterns("/test1");
            reg4.addPathPatterns("/test2");
     - addPathPattorns를 이용하여 여러 URI 설정 방법2
            reg4.addPathPatterns("/test1", "/test2");
            reg4.addPathPatterns("/sub1/*");
     - excludePathPatterns()를 이용하여 설정된 특정 URI를 제외
            reg5.excludePathPatterns("/sub1/test3");

     결과 화면
    /test1 요청 시

    /test2 요청 시
    /sub1/test3 요청 시
     실행된 Interceptor가 없다.

    /sub1/test4 요청 시

     


     

    방법 2 - XML

     

    Interceptor 등록하는 방법만 다르므로 다른 부분은 제외하겠다.

     

    Interceptor 구현

    servlet-context.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <beans:beans xmlns="http://www.springframework.org/schema/mvc"
    			 ....>
    			 					 
    	<!-- 스캔한 패지키 내부의 클래스 중 Controller 어노테이션을 가지고 있는 클래스들을 Controller로 로딩하도록 한다 -->
    	<annotation-driven/>
    	
    	<!-- 스캔할 bean들이 모여있는 패키지를 지정한다. -->
    	<context:component-scan base-package="kr.co.softcampus.controller"/>
    	
    	<!-- Controller의 메서드에서 반환하는 문자열 앞 뒤에 붙힐 경로 정보를 셋팅한다. -->
    	<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>
    	
    	<!-- 정적파일(이미지, 사운드, 동영상, JS, CSS 등등) 경로 셋팅 -->
    	<resources mapping="/**" location="/resources/"/>
    	
    	<!-- Interceptor 들을 Bean으로 등록한다. -->
    	<beans:bean class='kr.co.softcampus.interceptor.TestInterceptor1' id='inter1'/>
    	
    	<interceptors>
    		<interceptor>
    			<mapping path="/test1"/>
    			<beans:ref bean='inter1'/>
    		</interceptor>
    		<interceptor>
    			<mapping path="/test2"/>
    			<beans:bean class='kr.co.softcampus.interceptor.TestInterceptor2'/>
    		</interceptor>
    		<interceptor>
    			<mapping path="/test2"/>
    			<beans:ref bean="inter1"/>
    		</interceptor>
    		<interceptor>
    			<mapping path="/**"/>
    			<exclude-mapping path="/*"/>
    			<beans:bean class='kr.co.softcampus.interceptor.TestInterceptor3'/>
    		</interceptor>
    	</interceptors>
    			 
    </beans:beans>
    <beans:bean class='kr.co.softcampus.interceptor.TestInterceptor1' id='inter1'/>
     - 여러 경로에 Interceptor가 필요한 경우 bean을 주입하고 필요할 때마다 가져온다.

    <interceptor>     
          <mapping path="/test2"/>
          <beans:bean class='kr.co.softcampus.interceptor.TestInterceptor2'/>
    </interceptor>
     - 한 경로에만 Interceptor가 필요한 경우 이 안에서만 사용하도록 bean을 주입할 수 있다.


     한 요청 주소에 대해 Interceptor 1개밖에 등록을 못하므로 불편함이 있다.

     

     

     

     

    반응형

    댓글

Designed by Tistory.