1. 인터셉터(Interceptor)

    • 인터셉터는 Dispatcher Servlet에서 Handler(Controller)로 요청을 보낼 때,
      그리고 Hanlder에서 Dispatcher Servlet으로 응답을 보낼 때 동작한다.

    • 인터셉터는 org.springframework.web.servlet.HandlerInterceptor
      인터페이스를 구현하고,
      org.springframework.web.servlet.handler.HandlerInterceptoradapter
      클래스를 상속받는다.

    • 인터셉터를 등록하는 방법으로는 두 가지가 있다.

      • Java Config를 사용하면 WebMvcConfiguereradapter가 가지고 있는
        addInterceptors 메소드를 오버라이딩하여 등록할 수 있다.

      • xml을 이용할 경우

        <mvc:interceptors>

        를 이용하여 등록할 수 있다.

  • Interceptor를 그림으로 나타낼 경우 다음과 같다.

    20200520(1)

    출처 : https://cphinf.pstatic.net/mooc/20180222_261/1519262329628q8DQN_JPEG/1.jpg

     




    Interceptor 사용 예제


    -> WebMvcContextConfigurerAdapter를 상속받는 클래스에서 일단 등록.

    @Configuration
    @EnableWebMvc
    @ComponentScan(basePackages = { ... })
    public class WebMvcContextConfiguration extends WebMvcConfigurerAdapter {
    
    ...
        @Override
        public void addInterceptors(InterceptorRegistry registry) {
            registry.addInterceptor(new LogInterceptor());
        }
    //등록할 때에는 InterceptorRegistry를 이용한다.
    //LogInterceptor는 우리가 만든 인터셉터 클래스이다.
    }


    -> LogInterceptor 클래스

    public class LogInterceptor extends HandlerInterceptorAdapter {
    
        //public void postHandle(request, response, Object, ModelAndView)
        @Override
        public void postHandle(
                HttpServletRequest request,
                HttpServletResponse response, 
                Object handler, 
                ModelAndView modelAndView) throws Exception {
            System.out.println(
                "postHandle : " + handler.toString() + "가 종료되었습니다."); 
            System.out.println(
                modelAndView.getViewName() + "을 view로 사용합니다.");
        }
    
        //public boolean preHandle(request, response, Object)
        @Override
        public boolean preHandle(
                HttpServletRequest request, 
                HttpServletResponse response, 
                Object handler) throws Exception {
            System.out.println(
                "pre handle : " + handler.toString() + "를 호출했습니다.");
            return true;
            //false 리턴시 요청받은 controller 수행 x
        }
    
    }

     




    아규먼트 리졸버Argument Resolver

    • 사용 목적 : 컨트롤러의 메소드 인자로 사용자가 지정한 임의의 값을 넣고 싶을 때 사용.
      예를 들어 세션에 저장되어 있는 값 중 특정 이름의 값을 메소드 인자로 전달할 수 있다.

    • 작성방법

      1. org.springframework.web.method.support.HandlerMethodArgumentResolver
        를 구현한 클래스를 작성한다.
      2. supportsParameter 메소드를 오버라이딩 한 후,
        원하는 타입의 인자가 있는지 검사한다.
        있는 경우 true가 리턴되도록 한다.

    • 등록방법

      1. WebMvcConfigurerAdapter를 상속받은 Java Config 파일에서
        addArgumentsResolver 메소드를 오버라이딩 한 후
        원하는 아규먼트 리졸버 클래스 객체를 등록한다.

      2. xml 파일에 등록하려는 경우

        <mvc:anntation.driven>
            <mvc:argument-resolvers>
                <bean class = "우리가 설정한 AgumentResolver 클래스">
                </bean>
            </mvc:argument-resolvers>
        </mvc:anntation.driven>



    • 사용예제

      • HeaderInfo클래스

        public class HeaderInfo {
            private Map<String, String> map;
        
            public HeaderInfo() {
                map = new HashMap<>();
            }
        
            public void put(String name, String value) {
                map.put(name, value);
            }
        
            public String get(String name) {
                return map.get(name);
            }
        }
        



      • (같은 패키지 내의) HeaderMapArgumentResolver 클래스

        //implements HandlerMethodArgumentResolver 필수.
        public class HeaderMapArgumentResolver 
            implements HandlerMethodArgumentResolver {
        
            //아래 메소드가 true를 반환해야 
            //controller들이 인자로 HeaderInfo를 사용 가능.
            @Override
            public boolean supportsParameter(MethodParameter parameter) {
                return parameter.getParameterType() == HeaderInfo.class;
            }
        
            @Override
            public Object resolveArgument(MethodParameter parameter, 
                    ModelAndViewContainer mavContainer,
                    NativeWebRequest webRequest, 
                    WebDataBinderFactory binderFactory)
                            throws Exception {
                HeaderInfo headerInfo = new HeaderInfo();
                Iterator<String> headerNames =
                    webRequest.getHeaderNames();
                //webRequest.getHeaderNames는 Iterator<String>형을 반환.
                while (headerNames.hasNext()) {
                    String headerName = headerNames.next();
                    String headerValue = webRequest.getHeader(headerName);
                    System.out.println("while headernames : " 
                                       + headerName + ',' + headerValue);
                    headerInfo.put(headerName, headerValue);
                }
                   //아래에서 반환한 headerInfo는 바로 위의 supportsParameter로.
                return headerInfo;
            }
        }



      • 등록하기.

        @Configuration
        @EnableWebMvc
        @ComponentScan(basePackages = {"..."})
        public class WebMvcContextConfiguration extends WebMvcConfigurerAdapter {
            ...;
        
            @Override
            public void addArgumentResolvers(
                    List<HandlerMethodArgumentResolver> argumentResolvers){
                System.out.println("아규먼트 리졸버 등록.");
                argumentResolvers.add(new HeaderMapArgumentResolver());
            }
        }



      • 결과 확인

            @GetMapping(path = "/list")
            public String list(
                    @RequestParam(...,
                        HeaderInfo headerInfo){
        
                System.out.println("---------------");
                System.out.println(headerInfo.get("user-agent"));
                System.out.println("----------------");
            }




 

  • 네이버 블러그 공유하기
  • 네이버 밴드에 공유하기
  • 페이스북 공유하기
  • 카카오스토리 공유하기
// custom