Filter란?
Web Application에서 관리되는 영역으로써 Spring Boot Framework에서 Client로부터 오는 요청/응답에 대해서 최초/최종 단계의 위치에 존재하며 이를 통해서 요청/응답의 정보를 변경하거나 Spring에 의해서 데이터가 변환되기 전의 순수한 Client의 요청/응답 값을 확인 할 수 있다. 또한, 유일하게 ServletRequest,ServletResponse의 객체를 변환 할 수 있다.
주로 Spring Boot Framework에서는 Request/Response의 Logging용도로 활용하거나 인증과 관련된 Logic들을 해당 Filter에서 처리한다.
즉, 이를 선/후처리 함으로써 Service business logic과 분리 시킨다.
package com.example.filter.controller;
import com.example.filter.dto.User;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@Slf4j //로그 남길대 사용 (Lombok)
@RestController
@RequestMapping("/api/user")
public class ApiController {
@PostMapping("")
public User user(@RequestBody User user){
log.info("User: {}",user);
return user;
}
}
package com.example.filter.filter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.web.util.ContentCachingRequestWrapper;
import org.springframework.web.util.ContentCachingResponseWrapper;
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedReader;
import java.io.IOException;
@Slf4j
@WebFilter(urlPatterns = "/api/user/*")
public class GlobalFilter implements Filter {
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
//전처리
ContentCachingRequestWrapper httpServletRequest=new ContentCachingRequestWrapper((HttpServletRequest) request);
ContentCachingResponseWrapper httpServletResponse=new ContentCachingResponseWrapper((HttpServletResponse)response);
chain.doFilter(httpServletRequest,httpServletResponse);
String url=httpServletRequest.getRequestURI();
//후처리
//req
String reqcontent =new String( httpServletRequest.getContentAsByteArray());
log.info("request url:{} ,requestBody:{}", url,reqcontent);
String resContent=new String(httpServletResponse.getContentAsByteArray());
int httpStatuse = httpServletResponse.getStatus();
httpServletResponse.copyBodyToResponse();
log.info("response statuse:{} , responseBody : {}",httpStatuse,resContent);
}
}
package com.example.filter.controller;
import com.example.filter.dto.User;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@Slf4j //로그 남길대 사용 (Lombok)
@RestController
@RequestMapping("/api/temp")
public class ApiUserController {
@PostMapping("")
public User user(@RequestBody User user){
log.info("Temp: {}",user);
return user;
}
}
package com.example.filter.dto;
import lombok.*;
@Data //Getter,Setter,tostring 과정 생략 가능(Lombok)
@NoArgsConstructor //기본 생성자
@AllArgsConstructor //전체 생성자
public class User {
private String name;
private int age;
}
package com.example.filter;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.ServletComponentScan;
@SpringBootApplication
@ServletComponentScan
public class FilterApplication {
public static void main(String[] args) {
SpringApplication.run(FilterApplication.class, args);
}
}