티스토리 뷰
개요
Java EE에는 HTTP 요청에 대한 응답을 수행하는 HttpServlet
(@WebServlet)이 존재하며 이러한 서블릿 실행 전후 시점에 임의의 처리를 가능하게 해주는 Filter
(@WebFilter)가 존재한다. 필터는 체인 형태로 여러 개를 사용할 수 있다. Spring Web MVC 또한 동일한 기능의 HandlerInterceptor
를 제공한다. Filter는 로우 레벨의 처리 로직을, HandlerInterceptor는 회원 인증 검사 등의 비즈니스 레벨의 처리 로직을 작성하는데 적합하다. 이번 글에서는 HandlerInterceptor의 사용 예를 간단히 설명하고자 한다.
HandlerInterceptor 작성
package com.jsonobject.example;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@Component
public class HttpInterceptor extends HandlerInterceptorAdapter {
@Override
public boolean preHandle(
HttpServletRequest request,
HttpServletResponse response,
Object handler
) throws Exception {
// HTTP 요청 처리 전 수행할 로직 작성
return true;
}
@Override
public void postHandle(
HttpServletRequest request,
HttpServletResponse response,
Object handler,
ModelAndView modelAndView
) throws Exception {
// HTTP 요청 처리 후 수행할 로직 작성
}
}
- 인터셉터 클래스를 작성하려면
HandlerInterceptor
인터페이스를 구현해야 한다. 만약 전처리 또는 후처리만 하고자 할 경우 인터페이스의 모든 메써드를 구현하는 것은 번거롭다. 위와 같이HandlerInterceptorAdapter
추상 클래스를 상속하면 원하는 메써드만 작성할 수 있어 편리하다. - 인터셉터 클래스는
@Component
어노테이션을 통해 스프링 빈이 될 수 있다. 따라서 의존성 주입을 통한 비즈니스 로직을 처리하기 편리하다.
WebMvcConfigurer 작성
package com.jsonobject.example;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
@Configuration
public class HttpInterceptorConfig extends WebMvcConfigurerAdapter {
@Autowired
private HttpInterceptor httpInterceptor;
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(httpInterceptor)
.addPathPatterns("/**")
.excludePathPatterns("/public/**");
}
}
- 인터셉터 클래스만으로는 아무 일도 일어나지 않는다. 작성한 인터셉터가 작동할 수 있도록 등록해주어야 한다.
WebMvcConfigurer
인터페이스를 구현한@Configuration
클래스를 작성하면 된다.WebMvcConfigurerAdapter
추상 클래스를 상속하여 필요한 메써드만 깔끔하게 작성할 수 있다. - 인터셉터를 등록할 때는 인터셉터를 적용할 요청 주소의 패턴과 제외할 요청 주소의 패턴을 명시하여 선택적 적용이 가능하다.
ResponseBodyAdvice 작성
package com.jsonobject.example;
import org.springframework.core.MethodParameter;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;
@ControllerAdvice
public class HttpResponseAdvice implements ResponseBodyAdvice<Object> {
@Override
public boolean supports(
MethodParameter returnType,
Class<? extends HttpMessageConverter<?>> converterType
) {
return true;
}
@Override
public Object beforeBodyWrite(
Object body,
MethodParameter returnType,
MediaType selectedContentType,
Class<? extends HttpMessageConverter<?>> selectedConverterType,
ServerHttpRequest request,
ServerHttpResponse response
) {
// HTTP 요청 처리 후 응답을 가공하는 로직 작성
response.getHeaders().add("some-header", "some-value");
return body;
}
}
- 인터셉터가 적용된 HTTP 요청을 처리하는
@Controller
클래스의 메써드가 메시지 변환이 필요한 오브젝트를 응답한다면(@ResponseBody
,ResponseEntity
오브젝트 반환시) 인터셉터의 후처리 시점에 응답을 가공하는 작업(예를 들면 HTTP 헤더의 추가)이 불가능해진다. 이 경우ResponseBodyAdvice
인터페이스를 구현한 클래스를 작성하여 해결할 수 있다. - beforeBodyWrite 메써드에 후가공이 필요한 로직을 작성한다. 내 경우 HTTP 요청에 대한 트랜잭션 ID를 헤더에 추가하는 로직을 이 부분에 작성하였다.
참고 글
- Spring Framework Reference Documentation: Intercepting requests with a HandlerInterceptor
- Spring - Modify response headers after controller processing
다른 읽을만한 글
댓글
최근에 올라온 글
최근에 달린 댓글
- Total
- Today
- Yesterday
링크
TAG
- 평속
- JavaScript
- JHipster
- 자전거
- maven
- kotlin
- Eclipse
- Docker
- 구동계
- Spring Boot
- 로드바이크
- graylog
- chrome
- node.js
- CentOS
- jsp
- Tomcat
- Kendo UI Web Grid
- 로드 바이크
- 태그를 입력해 주세요.
- jstl
- java
- Spring MVC 3
- DynamoDB
- Kendo UI
- jpa
- 알뜰폰
- MySQL
- bootstrap
- spring
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
글 보관함