Open ywbestPark opened 1 year ago
import org.springframework.web.util.ContentCachingRequestWrapper; import org.springframework.web.util.ContentCachingResponseWrapper;
import javax.servlet.*; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.nio.charset.StandardCharsets;
public class CustomFilter implements Filter {
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
ContentCachingRequestWrapper requestWrapper = new ContentCachingRequestWrapper((HttpServletRequest) servletRequest);
ContentCachingResponseWrapper responseWrapper = new ContentCachingResponseWrapper((HttpServletResponse) servletResponse);
filterChain.doFilter(requestWrapper, responseWrapper);
String requestContent = extractRequestData(requestWrapper);
String responseContent = extractResponseData(responseWrapper);
// 추출한 데이터를 데이터베이스에 저장하는 로직을 구현합니다.
saveDataToDatabase(requestContent, responseContent);
}
private String extractRequestData(ContentCachingRequestWrapper requestWrapper) {
String requestData = "";
if (requestWrapper.getContentAsByteArray().length > 0) {
requestData = new String(requestWrapper.getContentAsByteArray(), StandardCharsets.UTF_8);
}
// 요청 데이터 추출 로직을 구현합니다.
// 예: 파라미터, 폼 데이터, 바디 데이터, 패스 변수 등을 추출합니다.
return requestData;
}
private String extractResponseData(ContentCachingResponseWrapper responseWrapper) {
String responseData = "";
if (responseWrapper.getContentAsByteArray().length > 0) {
responseData = new String(responseWrapper.getContentAsByteArray(), StandardCharsets.UTF_8);
}
// 응답 데이터 추출 로직을 구현합니다.
// 예: 바디 데이터, 헤더 등을 추출합니다.
return responseData;
}
private void saveDataToDatabase(String requestContent, String responseContent) {
// 데이터베이스에 요청 및 응답 데이터를 저장하는 로직을 구현합니다.
// 예: JPA를 사용하여 엔티티에 데이터를 매핑하고 저장합니다.
}
// init() 및 destroy() 메서드는 필요에 따라 구현할 수 있습니다.
}
[중요]
필터 추가시 아래 소스 안 넣으면 로컬에서는 오류 안나지만 리눅스 서버에서는 서버 시작도 안됨
@Override
public void init(FilterConfig filterConfig) throws ServletException {
// Do nothing
}
@Override
public void destroy() {
// Do nothing
}
[이슈] Filter에서 getInputStream()을 한번 호출해 버리면 @RequestBody DTO 사용시 SpringMVC에서 입력된 json 데이터를 DTO로 자동으로 변환해 줄때 오류 발생 함.
InputStream에서 데이터를 읽으면 해당 데이터는 소비되므로 컨트롤러에서 다시 사용할 수 없다는 점입니다.
따라서 필터에서 요청 데이터를 로깅하고 남기려면 데이터를 따로 저장하는 방식을 사용해야 합니다.
[해결책] XSSFilter를 이용하여 InputStream() 호출시 입력데이터 가지고 있다가 로그 저장하도록 함. LoggingFilter는 미사용
import org.springframework.util.StringUtils; import org.springframework.web.util.ContentCachingRequestWrapper; import org.springframework.web.util.ContentCachingResponseWrapper;
import javax.servlet.*; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.nio.charset.StandardCharsets; import java.util.Arrays; import java.util.HashMap; import java.util.Map;
public class CustomFilter implements Filter {
}