티스토리 뷰
반응형
    
    
    
  목적
Filter 활용
예제소스
https://github.com/devHjlee/devHjBlog/tree/main/filter-interceptor-aop
Filter

- 필터는 디스패처서블릿에 요청이 전달되기 전/후 에 url 패턴에 맞는 모든 요청에 대해 부가작업을 처리 할 수 있는 기능을 제공합니다.
- javax.servlet.Filter는 Java Servlet API의 일부로, 웹 애플리케이션에서 들어오는 요청과 해당 응답을 가로채고 조작하는 데 사용되는 인터페이스입니다. 필터는 요청 전후에 특정 작업을 수행하거나 응답을 수정하는 데 유용합니다. 주요 목적은 애플리케이션의 공통된 작업을 중앙에서 관리하고 코드 중복을 피하는 것입니다.
- 필터는 웹 애플리케이션의 요청 및 응답 처리 파이프라인에서 동작하며, 여러 필터가 연속적으로 체인으로 연결될 수 있습니다. 각 필터는 요청이나 응답에 대해 작업을 수행한 후 체인의 다음 필터로 제어를 전달하거나, 체인의 끝에 도달하면 최종적으로 서블릿에게 제어를 전달합니다.
- 일반적인 필터 작업에는 다음과 같은 것들이 있을 수 있습니다:
- 요청/응답 로깅: 요청 및 응답 내용을 기록하거나 모니터링하는 용도로 사용할 수 있습니다.
- 인증 및 권한 부여: 요청에 대한 인증 및 권한 부여 작업을 수행할 수 있습니다.
- 데이터 변환: 요청 데이터나 응답 데이터를 변환하거나 형식을 조작할 수 있습니다.
- 캐싱: 응답을 캐시하여 성능을 향상시킬 수 있습니다.
- 예외 처리: 예외 상황에 대한 처리를 수행할 수 있습니다.
 
- javax.servlet.Filter인터페이스를 구현하는 필터 클래스는- doFilter()메서드를 오버라이드해야 합니다. 이 메서드에서 실제 필터링 작업을 수행하고, 요청을 변경하거나 응답을 조작한 후- FilterChain객체의- doFilter()메서드를 호출하여 체인의 다음 필터로 제어를 전달합니다.
- Dispatcher Servlet에 요청이 전달되기 전 / 후에 url 패턴에 맞는 모든 요청에 대해 부가 작업을 처리할 수 있는 기능을 제공
- 필터는 Request와 Response를 조작할 수 있지만, 인터셉터는 조작 불가능
- 주요 메소드
- init() - 필터 인스턴스 초기화 시 실행되는 메서드
- doFilter() - 클라이언트의 요청/응답 처리 시 실행되는 메서드
- destroy() - 필터 인스턴스가 제거될 때 실행되는 메서드
 
- Spring 을 통한 다양한 구현방법
- @Configuration + FilterRegistrationBean : 예시 작성
- @Component
- @WebFilter + @ServletComponentScan
- @WebFilter + @Component(주의사항 : https://velog.io/@bey1548/WebFilter)
 
개발환경
- IDE : IntelliJ
- Jdk : OpenJdk 11
- maven
- spring boot : 2.7.11
- 프로젝트 구조
 

FilterConfig
@Configuration  
public class FilterConfig {  
    @Bean  
    public FilterRegistrationBean<CorsFilter> corsFilter() {  
        FilterRegistrationBean<CorsFilter> registrationBean = new FilterRegistrationBean<>(new CorsFilter());  
        registrationBean.setUrlPatterns(Arrays.asList("/*")); // 필터 적용 url        registrationBean.setOrder(1); // 필터 적용 순서  
        return registrationBean;  
    }  
    @Bean  
    public FilterRegistrationBean<CustomRequestFilter> customRequestFilter() {  
        FilterRegistrationBean<CustomRequestFilter> registrationBean = new FilterRegistrationBean<>(new CustomRequestFilter());  
        registrationBean.setUrlPatterns(Arrays.asList("/*")); // 필터 적용 url        registrationBean.setOrder(2); // 필터 적용 순서  
        return registrationBean;  
    }  
    @Bean  
    public FilterRegistrationBean<CustomResponseFilter> customResponseFilter() {  
        FilterRegistrationBean<CustomResponseFilter> registrationBean = new FilterRegistrationBean<>(new CustomResponseFilter());  
        registrationBean.setUrlPatterns(Arrays.asList("/*")); // 필터 적용 url        registrationBean.setOrder(3); // 필터 적용 순서  
        return registrationBean;  
    }  
}  Filter
@Slf4j  
public class CustomRequestFilter implements Filter {  
    @Override  
    public void init(FilterConfig filterConfig) throws ServletException {  
        // 초기화할 때 실행  
        log.info("Custom Request init START");  
    }  
    @Override  
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain)  
            throws IOException, ServletException {  
        HttpServletRequest req = (HttpServletRequest) request;  
        // GET 방식 요청 중 '/filterData' 경로에 대해서만 파라미터 변경  
        if (req.getMethod().equals("GET") && req.getRequestURI().equals("/filterData")) {  
            // 요청을 위한 커스텀 래퍼(wrapper) 생성  
            CustomRequestWrapper requestWrapper = new CustomRequestWrapper(req){  
                @Override  
                public String getServerName() {  
                    return "test.com";  
                }  
            };  
            // 원하는 대로 파라미터 수정  
            requestWrapper.setParameter("name", req.getParameter("name"));  
            requestWrapper.setParameter("age", req.getParameter("age"));  
            requestWrapper.setParameter("user", "1");  
            // 수정된 요청으로 계속 진행  
            log.info("CustomRequestFilter Start");  
            filterChain.doFilter(requestWrapper, response);  
            log.info("CustomRequestFilter End");  
        } else {  
            // 다른 요청에 대해서는 기존 요청 그대로 전달  
            filterChain.doFilter(request, response);  
        }  
    }  
    @Override  
    public void destroy() {  
        // 종료될 때 실행  
        log.info("Custom Request init Destory");  
    }  
}Wrapper
public class CustomRequestWrapper extends HttpServletRequestWrapper {  
    private final Map<String, String[]> modifiedParameters;  
    public CustomRequestWrapper(HttpServletRequest request) {  
        super(request);  
        this.modifiedParameters = new HashMap<>(request.getParameterMap());  
    }  
    @Override  
    public String getParameter(String name) {  
        String[] values = modifiedParameters.get(name);  
        return (values != null && values.length > 0) ? values[0] : null;  
    }  
    @Override  
    public Map<String, String[]> getParameterMap() {  
        return Collections.unmodifiableMap(modifiedParameters);  
    }  
    @Override  
    public Enumeration<String> getParameterNames() {  
        return Collections.enumeration(modifiedParameters.keySet());  
    }  
    @Override  
    public String[] getParameterValues(String name) {  
        return modifiedParameters.get(name);  
    }  
    public void setParameter(String name, String value) {  
        modifiedParameters.put(name, new String[]{value});  
    }  
}Test Controller
@Slf4j  
@RestController  
public class HelloController {  
    @GetMapping("/filterData")  
    public ResponseEntity<Map<String, Object>> filterData(HttpServletRequest request, @RequestParam String name, @RequestParam int age) {  
        Map<String, Object> resMap = new HashMap<>();  
        resMap.put("name", name);  
        resMap.put("age", age);  
        log.info(request.getServerName());  
        return new ResponseEntity<Map<String,Object>>(resMap, HttpStatus.OK);  
    }  
    @GetMapping("/noFilterData")  
    public ResponseEntity<Map<String, Object>> noFilterData(@RequestParam String name, @RequestParam int age) {  
        Map<String, Object> resMap = new HashMap<>();  
        resMap.put("name", name);  
        resMap.put("age", age);  
        return new ResponseEntity<Map<String,Object>>(resMap, HttpStatus.OK);  
    }  
} 실행 결과
- http://localhost:8080/filterData?name=a&age=1 호출
- CustomRequestFilter doFilter 를 통해 요청값의 ServerName 을 변경하고 user 파라미터를 추가하였다
- CustomResponseFilter doFilter 를 통해 응답값의 파라미터중 user 의 값을 1에서 Y 로 변경하였다.


참고
- https://velog.io/@ksk7584/Filter%EB%A5%BC-%EB%93%B1%EB%A1%9D%ED%95%98%EB%8A%94-4%EA%B0%80%EC%A7%80-%EB%B0%A9%EB%B2%95
- https://mangkyu.tistory.com/221
- Chat GPT
인터셉터 : https://devhj.tistory.com/60
반응형
    
    
    
  'Spring' 카테고리의 다른 글
| Spring Cache (0) | 2024.03.16 | 
|---|---|
| WebSocket Client 라이브러리 (0) | 2023.09.14 | 
| Spring ControllerAdvice 활용 (0) | 2023.05.04 | 
| Spring Event 활용 (0) | 2023.03.21 | 
| JPA+QueryDsl 게시판 CRUD 구현(2) (0) | 2023.03.09 | 
반응형
    
    
    
  
                      공지사항
                      
                  
                
                  
                  
                    최근에 올라온 글
                    
                
                  
                  
                    최근에 달린 댓글
                    
                
                  
                  - Total
- Today
- Yesterday
                    링크
                    
                
                  
                  
                    TAG
                    
                
                  
                  - spring boot jpa crud
- quartz spring batch
- Enum equals
- cursor ai 프로젝트
- cursor ai 프롬프트
- 스케줄링 시스템
- JdbcBatchItem
- quartz 실무 적용
- spring boot jpa
- Spring Actuator
- Spring boot Actuator
- cursor ai
- 배치 관리 ui
- cursorAI
- kafka redis
- kafka oubox
- spring security
- kafka srping event
- tomcat gzip
- cursor ai crud
- SpringBatch 5.1.1
- CompositeItemWriter
- Enum ==
- 잡 스케줄링
- custom Item writer
- 배치 모니터링
- oubox pattern
- Enum Equals ==
- no `meta.properties` found in
- actuator prometheus grafana
| 일 | 월 | 화 | 수 | 목 | 금 | 토 | 
|---|---|---|---|---|---|---|
| 1 | 2 | 3 | 4 | |||
| 5 | 6 | 7 | 8 | 9 | 10 | 11 | 
| 12 | 13 | 14 | 15 | 16 | 17 | 18 | 
| 19 | 20 | 21 | 22 | 23 | 24 | 25 | 
| 26 | 27 | 28 | 29 | 30 | 31 | 
                    글 보관함
                    
                
            