일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- Spring
- 백엔드
- 프로그래밍
- Programming
- OOP
- 전략패턴
- 클래스다이어그램
- 코딩
- jpa
- redis
- 서버개발
- 웹개발
- backend
- caching
- 봇
- 연관관계
- cache
- spring data jpa
- 개발
- Web
- 다자인패턴
- 의존관계
- java
- 디자인패턴
- Sprign
- IT
- 객체지향
- 집합관계
- 자바
- 웹
- Today
- Total
괴발나라
[Spring 🌱] 컨트롤러 메서드에 매핑되기 전에 Request URI 조작하기 본문
웹 애플리케이션을 개발하다 보면 URL을 암호화하여 클라이언트와 주고받아야 하는 경우가 있다.
클라이언트에서 URL 을 암호화하여 HTTP API를 호출하면 서버에서 그 URL을 복호화하여 처리해야 한다.
많은 시도 끝에 한가지 방법을 알아내어 공유하고자 한다.
URL 복호화를 Spring Interceptor 혹은 HandlerMethodArguementResolver 혹은 Converter 로 처리하려고 했으나,
다음과 같은 문제가 있었다.
- 암호화된 것은 문자열(String)일텐데, 컨트롤러 메서드에서는 그 파라미터의 타입이 Integer인 경우 NumberFormatException 이 발생한다.
- 이는 Interceptor, HandlerMethodArguementResolver , Converter 에 도달하기 전에 발생하는 문제이기 때문에
Request 핸들링 레이어에서 최상위에 있는 Filter로 처리해야 했다.
Filter를 구현하면, doFilter() 메서드를 이용해 ServletRequest의 정보를 얻어낼 수 있다.
하지만 ServletRequest 객체를 조작할 수는 없기 때문에, 스프링에서 제공하는 HttpServletRequestWrapper를 상속하여 사용했다.
코드를 직접 까보지는 않았지만,
Request URL 을 참고하여 그 요청을 처리할 특정 컨트롤러의 메서드를 찾을 때
HttpServletRequest의 getRequestURI() 메서드를 사용하는 듯 하다.
그래서 HttpServletRequestWrapper로 ServletRequest 를 감싸고,
getRequestURI() 메서드를 오버라이딩하여 URL 복호화 문제를 해결했다.
@Slf4j
@Component
@Order(0)
public class CustomFilter implements Filter {
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
// 클라이언트로부터 온 ServletRequest 객체를 HttpServletRequestWrapper를 상속한 클래스로 감싼 후 다음 필터로 보낸다.
chain.doFilter(new CustomRequestWrapper((HttpServletRequest) request), response);
}
// HttpServletRequestWrapper 를 상속함
private static class CustomRequestWrapper extends HttpServletRequestWrapper {
public CustomRequestWrapper(HttpServletRequest request) {
super(request);
}
@Override
public String getRequestURI() {
// 요청 URL 을 복호화하여 리턴한다.
return decryptUrl(super.getRequestURI());
}
}
}
주의할 점은 다음과 같다.
나는 처음에 request.getAttribute(HandlerMapping.URI_TEMPLATE_VARIABLES_ATTRIBUTE)
메서드를 이용해 URL 파라미터 (PathVariable)를 얻은 후,
그것에 대하여 복호화 처리를 하려고 했으나,
요청이 처리될때, 즉 Controller에 도착하기 전까지는 위의 메서드가 null을 반환하고
Controller에서 요청 처리 후 응답 시에만 위의 메서드가 제대로된 값을 반환하는 것을 확인하였다.
정확한 이유는 아직 알지 못한다.