핸들러 인터셉터로 스프링 모델 매개 변수 변경

1. 소개

이 튜토리얼에서는 Spring MVC HandlerInterceptor 에 초점을 맞출 것 입니다. 더 구체적으로, 요청을 처리하기 전과 후에 Spring MVC의 모델 매개 변수를 변경합니다.

HandlerInterceptor의 기본 에 대해 읽고 싶다면 이 기사를 확인하십시오.

2. Maven 종속성

인터셉터 를 사용하려면 pom.xml 파일 의 종속성 섹션에 다음 섹션을 포함해야 합니다.

 org.springframework spring-web 5.2.8.RELEASE  

최신 버전은 여기에서 찾을 수 있습니다.

이 종속성은 Spring Web에만 적용되므로 전체 웹 애플리케이션에 대한 pring-corespring-context 및 선택한 로깅 라이브러리 를 추가하는 것을 잊지 마십시오 .

3. 맞춤형 구현

HandlerInterceptor 의 사용 사례 중 하나는 생성 된 각 뷰에서 사용할 수있는 공통 / 사용자 특정 매개 변수를 모델에 추가하는 것입니다.

이 예에서는 사용자 정의 인터셉터 구현을 사용하여 로깅 된 사용자의 사용자 이름을 모델 매개 변수에 추가합니다. 더 복잡한 시스템에서는 사용자 아바타 경로, 사용자 위치 등과 같은보다 구체적인 정보를 추가 할 수 있습니다.

새로운 Interceptor 클래스 를 정의하는 것부터 시작하겠습니다 .

public class UserInterceptor extends HandlerInterceptorAdapter { private static Logger log = LoggerFactory.getLogger(UserInterceptor.class); ... }

preHandle ()postHandle () 메서드 만 구현하고자하므로 HandlerInterceptorAdapter를 확장 합니다.

앞서 언급했듯이 로그인 한 사용자의 이름을 모델에 추가하려고합니다. 먼저 사용자가 로그인했는지 확인해야합니다. SecurityContextHolder 를 확인하여이 정보를 얻을 수 있습니다 .

public static boolean isUserLogged() { try { return !SecurityContextHolder.getContext().getAuthentication() .getName().equals("anonymousUser"); } catch (Exception e) { return false; } }

의 HttpSession가 설립되어 있지만, 아무도에 기록되어, 봄 보안 컨텍스트에서 사용자 이름이 같음 anonymousUser . 다음으로 preHandle () 구현을 진행합니다 .

3.1. preHandle () 메서드

요청을 처리하기 전에 모델 매개 변수에 액세스 할 수 없습니다. 사용자 이름을 추가하려면 HttpSession 을 사용 하여 매개 변수를 설정 해야합니다 .

@Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object object) throws Exception { if (isUserLogged()) { addToModelUserDetails(request.getSession()); } return true; }

요청을 처리하기 전에이 정보 중 일부를 사용하는 경우 이는 매우 중요합니다. 보시다시피 사용자가 로그인했는지 확인한 다음 세션을 가져 와서 요청에 매개 변수를 추가합니다.

private void addToModelUserDetails(HttpSession session) { log.info("=============== addToModelUserDetails ========================="); String loggedUsername = SecurityContextHolder.getContext().getAuthentication().getName(); session.setAttribute("username", loggedUsername); log.info("user(" + loggedUsername + ") session : " + session); log.info("=============== addToModelUserDetails ========================="); }

SecurityContextHolder 를 사용 하여 loggingUsername 을 얻었 습니다 . 표준 사용자 이름 대신 이메일을 얻기 위해 Spring Security UserDetails 구현을 재정의 할 수 있습니다 .

3.2. 메소드 p ostHandle ()

요청을 처리 한 후 모델 매개 변수를 사용할 수 있으므로 값을 변경하거나 새 매개 변수를 추가하기 위해 액세스 할 수 있습니다. 이를 위해 재정의 된 postHandle () 메서드를 사용합니다.

@Override public void postHandle( HttpServletRequest req, HttpServletResponse res, Object o, ModelAndView model) throws Exception { if (model != null && !isRedirectView(model)) { if (isUserLogged()) { addToModelUserDetails(model); } } }

구현 세부 사항을 살펴 보겠습니다.

먼저 모델이 null 이 아닌지 확인하는 것이 좋습니다 . 그것은 우리가 NullPointerException 을 만나는 것을 막을 것입니다 .

또한 View 가 Redirect View 의 인스턴스가 아닌지 확인할 수 있습니다 .

요청이 처리 된 후 리디렉션 된 후 매개 변수를 추가 / 변경할 필요가 없습니다. 즉시 새 컨트롤러가 처리를 다시 수행합니다. 뷰가 리디렉션되는지 확인하기 위해 다음 방법을 도입합니다.

public static boolean isRedirectView(ModelAndView mv) { String viewName = mv.getViewName(); if (viewName.startsWith("redirect:/")) { return true; } View view = mv.getView(); return (view != null && view instanceof SmartView && ((SmartView) view).isRedirectView()); }

마지막으로 사용자가 로그인되었는지 다시 확인하고, 그렇다면 Spring 모델에 매개 변수를 추가합니다.

private void addToModelUserDetails(ModelAndView model) { log.info("=============== addToModelUserDetails ========================="); String loggedUsername = SecurityContextHolder.getContext() .getAuthentication().getName(); model.addObject("loggedUsername", loggedUsername); log.trace("session : " + model.getModel()); log.info("=============== addToModelUserDetails ========================="); }

Please note that logging is very important, as this logic works “behind the scenes” of our application. It is easy to forget that we are changing some model parameters on each View without logging it properly.

4. Configuration

To add our newly created Interceptor into Spring configuration, we need to override addInterceptors() method inside WebConfig class that implements WebMvcConfigurer:

@Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(new UserInterceptor()); }

We may achieve the same configuration by editing our XML Spring configuration file:

From this moment, we may access all user-related parameters on all generated views.

Please notice, if multiple Spring Interceptors are configured, the preHandle() method is executed in the order of configuration whereas postHandle() and afterCompletion() methods are invoked in the reverse order.

5. Conclusion

This tutorial presents intercepting web requests using Spring MVC's HandlerInterceptor in order to provide user information.

In this particular example, we focused on adding logged user's details in our web application to model parameters. You may extend this HandlerInterceptor implementation by adding more detailed information.

All examples and configurations are available here on GitHub.

5.1. Articles in the Series

All articles of the series:

  • Introduction to Spring MVC Handler Interceptors
  • 핸들러 인터셉터로 스프링 모델 매개 변수 변경 (이것)