본문 바로가기
Today I Learned 2024. 6. 14.

(24.06.14)[9주차] Servlet 객체 활용하기

 

AOP 관점 지향 프로그램에 있어서 부가기능 에서 요청 또는 응답의 정보를 객체화 해서 관련 정보를 얻을 수 있는 방법을 찾아보다가 좋은 방법으로 Servlet 객체를 직접 활용하는 방법을 찾아 공부하면서 정리를 했다.


Spring에서 Servlet 객체 활용하기

  • AOP 에서 "부가기능" 으로 모든 Controller가 실행되기 전, Controller에게 요청 Request 된 HTTP Method와 URL 을 log로 찍고 싶은 기능을 넣어야 할 때 사용

DispatcherServlet의 작동

  • 지금까지 알 고 있는 것은 Tomcat에서의 Servlet - DispatcherServlet이 Controller 패턴 방식으로 API를 요청하는 것을알 고 있었음 
    • 그렇다면, 그렇게 작동될 때 전달되는 여러 요청들의 정보를 객체로 전달 하고 있지 않을까? -> 그 객체를 따로 가지고 와서 요청 정보를 따로 get해서 확인할 수 있지 않을까?
@Before("controller()")
    public void logRequestInfo() {

        // 요청 ContextHolder에서 서블릿 객체 속성 캐스팅해 구현체로 가지고 오기
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();

        // 요청 null check
        if (attributes == null) {
            log.info("Request 정보가 없습니다.");
        }

        // 서블릿 객체의 속성 중 HttpServletRequest 요청 정보 가지고 오기
        HttpServletRequest request = attributes.getRequest();

        // Request URL log
        String url = request.getRequestURL().toString();
        log.info("Request URL : " + url);

        // Request Mothod log
        String method = request.getMethod().toString();
        log.info("Request HTTP Method : " + method);
    }
  • Servlet 객체 가 실제로 존재 를 하게 되고 실제로도 AOP 등에서 꼭 사용되어야할 때 활용을 할 수 있도록 Spring Boot 에서는 구성이 되어있음
  • 모든 Servlet 객체들은 RequestContextHolder를 통해 필요한 ServletRequestAttributes  객체를 얻기 -> 필요한 객체를 따로 얻을 수 있음
    •  RequestContextHolder : Spring Framework 에서 지금 현재 Request 된 정보를 관리하는 유틸리티 클래스 즉, RequestAttributes 객체를 관리하고 있는 클래스
      • 각 쓰레드의 저장소에 RequestAttributes 즉 요청 정보를 담고 있는 인터페이스의 객체를 저장
      • 따라서,  get 메서드를 통해서 지금 요청된 정보를 담고있는 RequestAttributes 객체를 얻을 수 있음
    • ServletRequestAttributes 클래스 : Spring Framework에서 RequestAttributes 인터페이스를 구현한 구현체 -> 따라서 캐스팅을 한번 해준것  HttpServletRequest, HttpServletResponse 객체가 래핑되어있는 클래스
      • RequestAttributes 인터페이스 : HTTP 요청, 응답, 쓰레드 바운드 데이트 등 일반적인 Request 속성을 캡슐화하는 역할을 하는 인터페이스
  • ServletRequestAttributes 클래스에는 HttpServletRequest를 얻어와서, 구체적인 Request 정보등을 얻을 수 있음

 

ServletRequestAttributes 주요 메서드

(IntelliJ에서 참고)

  • getRequest() : HttpServletRequest 반환
  • getResponse() : HttpServletResponse 반환
  • getSession(boolean create) : 현재 세션(Object)을 반환, true 설정시, 없을 경우 새로운 세션 만듬
    • obtainSession() : 현재 세션(Object)을 반환, 없을 경우 무조건 새로운 세션 만듬

HttpServletRequest  주요 메서드 ** 중요

  • Request에 대한 정보 ,  Attributes 들을 get을 통해서 얻을 수 있음
  • 대부분 String 또는 StringBuffer 타입으로 얻을 수 있어 쉽게 활용할 수 있음

(IntelliJ에서 참고)

  • StringBuffer url = request.getRequestURL();
  • String method = request.getMethod();
  • String username = request.getParameter("username");
    • Parameter도 얻을 수 있음
  • Object attributeValue = request.getAttribute("attributeName");
    • DTO의 필드로 생각하면 편함
  • Cookie[] cookies = request.getCookies();
  • String headerName = request.getHeader("Name");
    • 헤더에서 특정 값을 가져올 수도 있음
    • String accessToken = request.getHeader("Authorization"); 이렇게 사용되면 AccessToken값도 가지고 올 수 있음

정리

  1. RequestContextHolder 에서 현재 Request에 대한 내용이 있는 RequestAttributes 를 가지고 옴
  2. RequestAttribute를 구현하기 위한 ServletRequestAttributes  로 캐스팅
  3. ServletRequestAttributes 구현체 에서 Request정보(HttpServletRequest)를  get
  4. Request 정보에서 getRequestUrl, getMethod 를 통해 요구한 요청 URL과 HTTP Method를 얻을 수 있음
 
 

구현체가 지원되는지 배경지식이 없었기 때문에 하나하나 IntelliJ에서 찾아보고, 그리고 확인하면서 학습하다 보니 양은 많지 않지만, AOP는 많이 사용하는 방법이기 때문에 반드시 인지할 수 있도록!