ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 핸들러 인터셉터
    백기선(인프런 강의)/스프링 웹 MVC 2020. 9. 6. 16:18
    반응형

    HandlerInterceptor

    • 핸들러 맵핑에 설정할 수 있는 인터셉터
    • 핸들러를 실행하기 전, 후(아직 랜더링 전) 그리고 완료(랜더링까지 끝난 이후) 시점에 부가 작업을 하고 싶은 경우에 사용할 수 있다.
    • 여러 핸들러에서 반복적으로 사용하는 코드를 줄이고 싶을 때 사용할 수 있다.
      • 로깅, 인증 체크, Locale 변경 등...

     

     

    boolean preHandle(request, response, handler)

    • 핸들러 실행하기 전에 호출 됨
    • “핸들러"에 대한 정보를 사용할 수 있기 때문에 서블릿 필터에 비해 보다 세밀한 로직을 구현할 수 있다.
    • 리턴값으로 계속 다음 인터셉터 또는 핸들러로 요청,응답을 전달할지(true) 응답 처리가 이곳에서 끝났는지(false) 알린다.

     

     

    void postHandle(request, response, modelAndView)

    • 핸들러 실행이 끝나고 아직 뷰를 랜더링 하기 이전에 호출 됨
    • “뷰"에 전달할 추가적이거나 여러 핸들러에 공통적인 모델 정보를 담는데 사용할 수도 있다.
    • 이 메소드는 인터셉터 역순으로 호출된다.
    • 비동기적인 요청 처리 시에는 호출되지 않는다.

     

     

    void afterCompletion(request, response, handler, ex)

    • 요청 처리가 완전히 끝난 뒤(뷰 랜더링 끝난 뒤)에 호출 됨
    • preHandler에서 true를 리턴한 경우에만 호출 됨
    • 이 메소드는 인터셉터 역순으로 호출된다.
    • 비동기적인 요청 처리 시에는 호출되지 않는다.

     

     

    vs 서블릿 필터

    • 서블릿 보다 구체적인 처리가 가능하다.
    • 서블릿은 보다 일반적인 용도의 기능을 구현하는데 사용하는게 좋다.

     

     

    예제

    핸들러 구현

    @RestController
    public class SampleController {
    
    	// preHandle
    	// 요청처리
    	// postHandler
    	// 뷰 랜더링
    	// afterCompletion
    	
    	@GetMapping("/hello")
    	public String hello() {
    		return "hello ";
    	}
    }
    

     

    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    import org.springframework.web.servlet.HandlerInterceptor;
    import org.springframework.web.servlet.ModelAndView;
    
    public class AnotherInterceptor implements HandlerInterceptor {
    	
    	@Override
    	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
    			throws Exception {
    		System.out.println("preHandle 2");
    		return true;
    	}
    
    	@Override
    	public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
    			ModelAndView modelAndView) throws Exception {
    		System.out.println("postHandle 2");
    	}
    
    	@Override
    	public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
    			throws Exception {
    		System.out.println("afterCompletion 2");
    	}
    }

     

    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    import org.springframework.web.servlet.HandlerInterceptor;
    import org.springframework.web.servlet.ModelAndView;
    
    public class GreetingInterceptor implements HandlerInterceptor {
    	
    	@Override
    	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
    			throws Exception {
    		System.out.println("preHandle 1");
    		return true;
    	}
    
    	@Override
    	public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
    			ModelAndView modelAndView) throws Exception {
    		System.out.println("postHandle 1");
    	}
    
    	@Override
    	public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
    			throws Exception {
    		System.out.println("afterCompletion 1");
    	}
    }

     

    핸들러 등록

    import org.springframework.context.annotation.Configuration;
    import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
    import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
    
    @Configuration
    public class WebConfig implements WebMvcConfigurer {
    	
    	@Override
    	public void addInterceptors(InterceptorRegistry registry) {
    		// add 한 순서대로 적용이된다.
    		registry.addInterceptor(new GreetingInterceptor()).order(0);
    		registry.addInterceptor(new AnotherInterceptor());
    		
    		/*
    		 * 아래와같이 순서와 path를 지정할 수 있다.
    		 */
    //		registry.addInterceptor(new GreetingInterceptor()).order(0);
    //		registry.addInterceptor(new AnotherInterceptor()).addPathPatterns("/jinseok").order(-1);
    	}
    }

     

    테스트

    import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
    import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
    import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
    
    import org.junit.jupiter.api.Test;
    import org.junit.runner.RunWith;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
    import org.springframework.test.context.junit4.SpringRunner;
    import org.springframework.test.web.servlet.MockMvc;
    
    @RunWith(SpringRunner.class)
    @WebMvcTest
    public class SampleControllerTest {
    
    	@Autowired
    	MockMvc mockMvc;
    
    	@Test
    	public void hello() throws Exception {
    		this.mockMvc.perform(get("/hello"))
    			.andDo(print())
    			.andExpect( content().string("hello"));
    	}
    }

     

     

    참고

    반응형
Designed by Tistory.