Spring의 인터셉터는 URI 매칭을 기반으로 작동합니다.
하지만 Restful API 서버를 개발할 때, 동일한 URI에 대해 서로 다른 HTTP 메서드를 사용해야 하는 경우가 있습니다.
예:
GET /memosPOST /memos
POST /memos에만 사용자 인증을 적용하는 인터셉터를 개발하는 경우, 다음 절차를 수행해야 합니다.
- 인터셉터를 생성합니다.
WebMvcConfigurer구현체의addInterceptor()에서/memos에 대해 인터셉터를 등록합니다.- 인터셉터 내부에서 Http Method가 GET인 경우 핸들링하지 않도록 구현합니다.
구현 예시:
public class AuthInterceptor extends HandlerInterceptorAdapter {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
if (request.getMethod().equals("GET") && request.getRequestURI().equals("/memos")) {
return true;
}
// authentication logic
return true;
}
}
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new AuthInterceptor()).addPathPatterns("/memos");
}
}
저는 이런 방식이 Restful 애플리케이션을 개발하는 데에 복잡성을 증가시킬 것이라고 생각했습니다. 인터셉터 내부에서 API 구조를 알아야 하기 때문입니다. 이런 불편함을 해소하기 위해, URI 기반 매칭 대신 URI와 HTTP 메서드를 기반으로 매칭하는 RestInterceptor 라이브러리를 만들었습니다.
repositories {
...
maven { url "https://jitpack.io" }
}
dependencies {
...
implementation 'com.github.Dh3356:rest_interceptor:v{version}'
// example: implementation 'com.github.Dh3356:rest_interceptor:v0.1'
}
// Since 1.0.3
repositories {
...
maven { url "https://jitpack.io" }
}
dependencies {
...
implementation 'com.github.cookie-meringue:rest_interceptor:v{version}'
// example: implementation 'com.github.cookie-meringue:rest_interceptor:v1.0.3'
}
@Slf4j
@Component
public class RestTestInterceptor extends RestInterceptor {
@Override
protected boolean doInternal(HttpServletRequest request, HttpServletResponse response, Object handler) {
log.info("Hello, world!");
return true;
}
}
@Configuration
@RequiredArgsConstructor
public class WebConfig implements WebMvcConfigurer {
private final RestTestInterceptor testInterceptor;
@Override
public void addInterceptors(InterceptorRegistry registry) {
// Create RestInterceptorRegistry from InterceptorRegistry
RestInterceptorRegistry restInterceptorRegistry = new RestInterceptorRegistry(registry);
restInterceptorRegistry.addInterceptor(testInterceptor)
.addRestPatterns(RestPattern.of("/memos", HttpMethod.GET)); // GET /memos
restInterceptorRegistry.build(); // Deprecated Since v1.0
}
}