개념
특징
사용
Lombok 사용을 위해 build.gradle의 dependencies에 다음 코드 추가
compileOnly 'org.projectlombok:lombok'
annotationProcessor 'org.projectlombok:lombok'
package com.example.filter.dto;
import lombok.*;
@Data // Getter, Setter 등
@NoArgsConstructor // 기본 생성자
@AllArgsConstructor // 전체 생성자
public class User {
private String name;
private int age;
}
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
@RestController
@RequestMapping("/api/user")
public class ApiController {
@PostMapping("")
public User user(@RequestBody User user) {
log.info("User : {}", user);
return user;
}
}
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
@RestController
@RequestMapping("api/temp")
public class ApiUserController {
@PostMapping("")
public User user(@RequestBody User user) {
log.info("Temp : {}", user);
return user;
}
}
package com.example.filter.filter;
import lombok.extern.slf4j.Slf4j;
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.IOException;
@Slf4j
@WebFilter(urlPatterns = "/api/user/*") // 특정 url에 Filter 걸기
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();
// 후처리 구간
// 응답 받기
String reqContent = new String(httpServletRequest.getContentAsByteArray());
String resContent = new String(httpServletResponse.getContentAsByteArray());
int httpStatus = httpServletResponse.getStatus();
// 위에서 내용을 빼가기 때문에 이 메소드 호출하여 Client가 제대로 된 응답을 받을 수 있도록 함
httpServletResponse.copyBodyToResponse();
log.info("request url : {}, requestBody : {}", url, reqContent);
log.info("response status : {}, responseBody : {}", httpStatus, resContent);
}
}
package com.example.filter;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.ServletComponentScan;
@SpringBootApplication
@ServletComponentScan 특정 url에 Filter 걸기
public class FilterApplication {
public static void main(String[] args) {
SpringApplication.run(FilterApplication.class, args);
}
}
http://localhost:8080/api/user 실행 결과
http://localhost:8080/api/tmep 실행 결과
lombok 관련 정리
@Data | Getter, Setter, toString, equals, hashCode 등 |
@NoArgsConstructor | 기본 생성자 |
@AllArgsConstructor | 전체 생성자 |
Filter 관련 정리
@Slf4j | log.info로 로그 찍기 |
implements Filter | doFilter 메소드 오버라이딩 |
chain.doFilter(req, res) | Filter가 실행되는 부분 |
전처리 구간의 형변환 | Filter 단이라 가능 |
ContentCachingRequestWrapper 클래스의 copyBodyToResponse 메소드 | Client가 제대로 된 응답을 받을 수 있도록 꺼낸 내용을 Body에 Copy |
@ServletComponentScan | Main - 특정 url에 Filter 걸기 |
@WebFilter(urlPatterns = "") | Filter - 특정 url에 Filter 걸기 |
핵심은 doFilter 이후의 후처리 | log 찍기 + copyBody |