1. 소개
이 예제에서는 Spring MVC HandlerInterceptor에 초점을 맞출 것입니다.
보다 구체적으로 인터셉터를 사용하는 고급 사용 사례를 보여 드리겠습니다 . 사용자 지정 카운터를 설정하고 세션을 수동으로 추적 하여 세션 시간 제한 논리를 에뮬레이트합니다 .
Spring에서 HandlerInterceptor의 기본 사항에 대해 읽으려면 이 기사 를 확인하십시오 .
2. 메이븐 의존성
인터셉터 를 사용하려면 pom.xml 파일 의 의존성 섹션 에 다음 섹션을 포함해야 합니다.
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>5.3.13</version>
</dependency>
최신 버전은 여기 에서 찾을 수 있습니다 . 이 의존성은 Spring Web에만 적용되므로 전체(최소) 웹 애플리케이션을 위해 spring- core 및 spring-context 를 추가하는 것을 잊지 마십시오 .
3. 세션 시간 초과의 사용자 지정 구현
이 예에서는 시스템의 사용자에 대한 최대 비활성 시간을 구성합니다. 그 이후에는 애플리케이션에서 자동으로 로그아웃됩니다.
이 논리는 단지 개념 증명일 뿐입니다. 물론 세션 시간 제한을 사용하여 동일한 결과를 쉽게 얻을 수 있습니다.
따라서 사용자가 활성 상태가 아닌 경우 세션이 무효화되는지 확인하려고 합니다. 예를 들어 사용자가 로그아웃하는 것을 잊은 경우 비활성 시간 카운터는 권한이 없는 사용자가 계정에 액세스하는 것을 방지합니다. 이를 위해서는 비활성 시간에 대해 상수를 설정해야 합니다.
private static final long MAX_INACTIVE_SESSION_TIME = 5 * 10000;
테스트 목적으로 50초로 설정했습니다. 잊지 마세요, ms 단위로 계산됩니다.
이제 앱의 각 세션을 추적해야 하므로 이 Spring 인터페이스를 포함해야 합니다.
@Autowired
private HttpSession session;
preHandle() 메서드 를 진행해 봅시다 .
3.1. 프리핸들()
이 방법에는 다음 작업이 포함됩니다.
- 요청 처리 시간을 확인하기 위한 타이머 설정
- 사용자가 로그인했는지 확인( 이 문서 의 UserInterceptor 메서드 사용 )
- 사용자의 비활성 세션 시간이 최대 허용 값을 초과하는 경우 자동 로그아웃
구현을 살펴보겠습니다.
@Override
public boolean preHandle(
HttpServletRequest req, HttpServletResponse res, Object handler) throws Exception {
log.info("Pre handle method - check handling start time");
long startTime = System.currentTimeMillis();
request.setAttribute("executionTime", startTime);
}
코드의 이 부분에서 처리 실행의 시작 시간을 설정 합니다 . 이 순간부터 각 요청 처리를 완료하는 데 걸리는 시간(초)을 계산합니다. 다음 부분에서는 누군가 HTTP 세션 중에 로그인한 경우에만 세션 시간에 대한 논리를 제공합니다.
if (UserInterceptor.isUserLogged()) {
session = request.getSession();
log.info("Time since last request in this session: {} ms",
System.currentTimeMillis() - request.getSession().getLastAccessedTime());
if (System.currentTimeMillis() - session.getLastAccessedTime()
> MAX_INACTIVE_SESSION_TIME) {
log.warn("Logging out, due to inactive session");
SecurityContextHolder.clearContext();
request.logout();
response.sendRedirect("/spring-rest-full/logout");
}
}
return true;
먼저 요청에서 세션을 가져와야 합니다.
다음으로 사용자가 애플리케이션에서 작업을 수행하기 때문에 로그인한 사람과 경과 시간에 대한 콘솔 로깅을 수행합니다. session.getLastAccessedTime() 을 사용 하여 이 정보를 얻고 현재 시간에서 빼서 MAX_INACTIVE_SESSION_TIME과 비교할 수 있습니다.
시간이 허용한 것보다 길면 컨텍스트를 지우고 요청을 로그아웃한 다음 (선택적으로) Spring Security 구성 파일에 선언된 기본 로그아웃 보기에 대한 응답으로 리디렉션을 보냅니다.
처리 시간 예제에 대한 카운터를 완료하기 위해 다음 하위 섹션에서 설명하는 postHandle() 메서드도 구현합니다.
3.2. 포스트핸들()
이 메서드는 현재 요청을 처리하는 데 걸린 시간에 대한 정보를 얻기 위한 구현입니다. 이전 코드 스니펫에서 본 것처럼 Spring 모델에서 executionTime 을 설정합니다. 이제 사용할 시간입니다.
@Override
public void postHandle(
HttpServletRequest request,
HttpServletResponse response,
Object handler,
ModelAndView model) throws Exception {
log.info("Post handle method - check execution time of handling");
long startTime = (Long) request.getAttribute("executionTime");
log.info("Execution time for handling the request was: {} ms",
System.currentTimeMillis() - startTime);
}
구현은 간단합니다. 실행 시간을 확인하고 현재 시스템 시간에서 뺍니다. 모델의 값을 long 으로 캐스트하는 것을 기억하십시오 .
이제 실행 시간을 제대로 기록할 수 있습니다.
4. 인터셉터 구성
새로 생성된 Interceptor 를 Spring 구성에 추가하려면 WebMvcConfigurer를 구현하는 WebConfig 클래스 내에서 addInterceptors () 메서드 를 재정의해야 합니다.
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new SessionTimerInterceptor());
}
XML Spring 구성 파일을 편집하여 동일한 구성을 얻을 수 있습니다.
<mvc:interceptors>
<bean id="sessionTimerInterceptor" class="com.baeldung.web.interceptor.SessionTimerInterceptor"/>
</mvc:interceptors>
또한 ApplicationContext 생성을 자동화하기 위해 Listener를 추가해야 합니다 .
public class ListenerConfig implements WebApplicationInitializer {
@Override
public void onStartup(ServletContext sc) throws ServletException {
sc.addListener(new RequestContextListener());
}
}
5. 결론
이 예제은 세션 관리/타임아웃을 수동으로 수행하기 위해 Spring MVC의 HandlerInterceptor 를 사용하여 웹 요청을 가로채는 방법을 보여줍니다.
평소와 같이 모든 예제와 구성은 여기 GitHub 에서 사용할 수 있습니다 .
5.1. 시리즈의 기사
시리즈의 모든 기사: