IT/Spring

Interceptor

iamhyeon 2024. 10. 23. 21:59

< Interceptor >   핸들러 인터셉터  Handler Interceptor

 

- 웹 브라우저가 보내는 컨트롤러의 실행 요청을 중간에 가로채서 어떠한 일을 수행하게 하는 기능
- 모든 웹 페이지가 공통적으로 동일하게 실행해야 하는 기능들을 구현할 수 있다

 

- 컨트롤러에 들어오는 요청 HttpRequest와 컨트롤러가 응답하는 HttpResponse를 가로채는 역할

- 웹 어플리케이션 내에서 특정한 URL 호출을 가로채는 역할

- 요청과 응답을 가로채서 원하는 동작을 추가하는 역할

 

- 요청을 받아들이기 전, 세션에서 로그인 한 사용자가 있는지 보고 없다면 로그인 페이지로 redirect 시킬 수 있다

- 주기적으로 결과 페이지에 등장하는 데이터들을 인터셉터에서 응답을 가로채 데이터를 추가한 다음 보낼 수 있다

 

- 클라이언트의 요청이 컨트롤러에 가기 전에 가로채고, 응답이 클라이언트에게 가기전에 가로챈다. 

- 인터셉터는 DispatcherServlet이 컨트롤러를 요청하기 전,후에 요청과 응답을 가로채서 가공할 수 있도록 해준다

- 예를 들어 로그인 기능이 있을 때, 로그인을 한 사람만 보이는 페이지가 있고, 로그인 한 사람만 글을 작성할 수 있다고 하면,

- 페이지 컨트롤러에서도 로그인 확인 로직이 들어가고, 글 작성 컨트롤러에서도 로그인 확인 로직이 들어가야 한다

- 인터셉터를 사용하면 컨트롤러에 로직이 로그인 확인 로직이 없어도 컨트롤러에 들어가기전에 인터셉터에서 로그인 확인을 하고 컨트롤러로 보낸다

- 하나의 인터셉터로 프로젝트 내의 모든 요청에 로그인 여부를 확인할 수 있다

 


 

< Spring Interceptor의 동작 시점 >
1. 컨트롤러 메서드가 실행되기 직전
2. View로 forward 되기 직전
3. 컨트롤러 메서드가 실행 완료된 직후


< 컨트롤러가 실행되기 직전 >
- 모든 웹 페이지의 실행 정보와 접속한 클라이언트의 정보를 로그로 기록한다

- 로그인 여부를 판별하여 회원 전용 페이지에 접근할 수 있는가를 판단한다

 

< 컨트롤러가 실행된 직후 >
- 페이지 실행 시간을 측정하여 이 페이지에 얼마나 머물렀는가를 로그로 남겨 컨텐츠의 인기도를 측정할 수 있는 데이터를 남긴다


@Slf4j

- Lombok 어노테이션은 클래스에 로거 인스턴스를 제공하여 로깅을 가능하게 한다

- LogBack이 바로 SL4J의 Native구현체
- SLF4J를 사용하여 로깅 처리를 하면 실제 로그는 LogBack에서 출력하게 된다
- LogBack : log4j를 토대로 새롭게 만든 Logging 라이브러리
- 클래스를 생성할 때마다 항상 로그를 남기기 위해 Logger 변수를 선언해야 했는데 Lombok의 @Slf4j 어노테이션을 사용하면  자동으로 log 변수를 선언하여 편리하게 log를 찍을 수 있다
- @Slf4j 선언하여 사용할 경우 변수명이 log로 고정된다는 특징이 있다
- 로깅에 대한 추상 레이어를 제공하는 것이고 interface의 모음이다.
- 어플리케이션은 SJF4J를 사용함으로써, 로깅 라이브러리를 어떤 것을 사용하던지 같은 방법으로 로그를 남길 수 있게한다
- 로그 라이브러리를 교체하더라도, 어플리케이션의 코드는 변경될 필요가 없다


@Component

- 클래스를 Spring 컴포넌트로 등록하여 컴포넌트 스캔 시 인식되도록 한다

- @Component 어노테이션은 클래스에 선언하는 어노테이션이다

- 이 어노테이션을 선언해주는 것만으로도 해당 클래스를 스프링 빈(bean) 객체로 사용할 수 있다
- Spring MVC역시 Spring context에서 동작하기 때문에 사용할 모든 클래스를 빈으로 등록해야 할 필요가 있다

- Controller 역할을 하는 클래스 역시 마찬가지다. 그런데 문제는 왜 Controller에는 @Component가 아닌 @Controller 어노테이션을 붙이냐는 것이다.
- @Component는 해당 클래스를 스프링 빈으로 사용할 수 있게 해준다


Spring에서는 어노테이션을 통해 각 클래스의 역할을 명확하게 한다

@Component: 일반적인 빈으로 등록할 때 사용한다. 특별한 역할이 없는 클래스에 사용한다
@Controller: 웹 요청을 처리하는 컨트롤러 클래스를 명시한다
@Service: 비즈니스 로직을 처리하는 서비스 클래스를 명시한다
@Repository: 데이터베이스와의 상호작용을 담당하는 리포지토리 클래스를 명시한다
이렇게 각 어노테이션을 사용하여 클래스의 역할을 명확히 하고, Spring이 각 클래스를 적절히 관리하도록 돕는다


▼ MyWebConfig.java

package com.hyeon.interceptor; 
 
import org.springframework.context.annotation.Configuration; 
import org.springframework.web.servlet.config.annotation.InterceptorRegistration; 
import org.springframework.web.servlet.config.annotation.InterceptorRegistry; 
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

import com.hyeon.interceptor.interceptors.MyInterceptor; 
 
@Configuration
@SuppressWarnings("null")
public class MyWebConfig implements WebMvcConfigurer {

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        
        // 직접 정의한 MyInterceptor를 Spring에 등록
        InterceptorRegistration ir = registry.addInterceptor(new MyInterceptor());

        // 해당 경로는 인터셉터가 가로채지 않는다
        ir.excludePathPatterns("/hello", "/world", "/error", "/robots.txt", "/favicon.ico", "assets/**");
    } 
    
}

 

@Configuration

- 이 클래스가 Spring의 설정 클래스임을 나타낸다

- Spring 컨테이너에서 이 클래스를 읽어들이고 설정 정보를 적용한다

 

WebMvcConfigurer

- 이 인터페이스를 구현하면, Spring MVC의 설정을 커스터마이즈할 수 있다

- 인터셉터, 뷰 리졸버, 포맷터 등을 추가하는 메서드를 오버라이드 할 수 있다

 

addInterceptors()

- 이 메서드는 InterceptorRegistry를 통해 인터셉터를 등록하는 메서드이다

- MyInterceptor라는 커스텀 인터셉터를 생성하여 등록한다

- 이로 인해 요청이 들어올 때마다 MyInterceptor의 메서드가 호출된다

 

ir.excludePathPatterns("~~",....)

- 인터셉터가 가로채지 않아야 하는 경로를 설정

- 이 경로로 들어오는 요청은 MyInterceptor의 로직을 거치지 않고 바로 처리된다 

 

 

=> MyInterceptor를 Spring의 인터셉터로 등록한다
=> 특정 경로는 인터셉터의 적용 대상에서 제외하여, 이 경로로 오는 요청은 인터셉터의 영향을 받지 않는다

 

 

 


refer to

https://gngsn.tistory.com/153#google_vignette

https://to-dy.tistory.com/21

https://m.blog.naver.com/ygj01069/222422798246

 

 

 

 

 

반응형

'IT > Spring' 카테고리의 다른 글

Spring 파일 업로드 경로 맵핑  (0) 2024.11.21
File Upload  (3) 2024.11.21
Spring 프로젝트 구성  (0) 2024.10.16
Spring 프로젝트 생성하기  (2) 2024.10.15
Spring framework  (0) 2024.10.14