개발 이론/Spring

[Spring] Spring MVC Webconfig와 Interceptors, Argument Resolvers

dal_been 2023. 11. 26. 18:28
728x90

최근에 개인 프로젝트하면서 스프링 시큐리티 필터말고 인터셉처를 통해서 인증관련된 기능을 구현하고 있다.

어떠한 이유로 스프링 시큐리티를 사용안한다기보다는 부트캠프 미션때 이미 스프링 시큐리티를 간단하게 써본적이있어서 한번 인터셉터를 통해 구현해보고 싶었다.

스프링 시큐리티와 인터셉터가 뭐가 다르냐고 물어본다면 이미 정리해둔 내용이 있다

https://haebing.tistory.com/85

 

또 arguementResolver가 정확히 몰라서 간단하게 정의와 코드로 정리해둔 내용이 있다

https://haebing.tistory.com/87

 

 

WebConfig파일

 

프로젝트 한번 해봤다하면 WebConfig파일은 한번씩 봤을 것이다.

한마디로 정리하면 웹 구성에 대해 지정하는 내용이 담겨있는 파일이다

 

 스프링부트에서 제공하는 WebMvcConfigurer 인터페이스를 구현하면 설정과 관련된 부분을 분리해서 관리가능하다.

 

 

WebMvcConfigurer 인터페이스

 

스프링 MVC구성을 사용자 정의에 따라 구성가능하게 해주는 인터페이스다

 

Handler Adapter, Interceptor, ArgumentResolver, Message Converter등등 내가 원하는 대로 구성할 수 있다.

 

정말 다양하기 때문에 interceptors와 argument resolvers를 공부해볼거다. 왜냐면 프로젝트에 사용중인 아이들이라서...ㅎㅎ

 

 

Interceptor와 ArgumentResolver

 

인터셉터와 argumentresolver에 대한 자세한 내용들은 인터넷에 쳐보면 정말 많다. 그래서 간단하게만 알아보고 spring이 요청을 argumentresolver와 interceptor를 어떻게 처리하는지 알아볼 것이다.

 

 

1. Spring ArgumentResolver

 

어떠한 요청이 컨트롤러로 들어왔을때 요청에 들어온 값을 원하는 객체로 만들어내는 기능을 하는 ArgumentResolver이다.

 

이 기능이 필요한 이유는 내가 로그인이 된 상태라고 생각해보자. 대부분은 토큰을 통해서 해당 사용자가 유호한지 확인하고 id를 꺼내서 어떤 것을 수행할 것이다. 만약 여기서 argumentResolver를 사용하지 않느다면 매번 검증관련된 메서드를 실행해야한다. 

 

이를 해결하기 위해 HandlerMethodArgumentResolver를 구현함으로써 ArgumentResolver를 사용할 수 있다.

 

public interface HandlerMethodArgumentResolver {

	boolean supportsParameter(MethodParameter parameter);


	@Nullable
	Object resolveArgument(MethodParameter parameter, @Nullable ModelAndViewContainer mavContainer,
			NativeWebRequest webRequest, @Nullable WebDataBinderFactory binderFactory) throws Exception;

}

 

이 두메서드를 통해서 Parameter앞에 특정 어노테이션 붙여서 supportsParameter로 해당 인자에 어노테이션이 붙여있는지 확인하고 resolveArgument로 parameter가 원하는 형태로 정보를 바인딩하여 반환해준다

 

이렇게 하면 반복되는 메서드를 방지할 수 있고 검증에 대한 책임을 controller나 service에서 직접적으로 하지 않아도 된다

 

 

2. Sprinng Interceptor

 

간단하게 얘기하자면 필터 역할과 조금 비슷하다. 다만 실행되는 위치가 다르다. 이에 대해서는 위의 블로그 url를 들어가보면 있다.

그렇지만 어떤 역할을 하는지 간단하게 얘기해보자면 어떤 사이트에서 관리자가 있고 고객이 있다고 생각하자. 어떤 url에는 관리자만 들어갈 수 있다고 생각했을때 고객이 해당 url에서 어떤 일을 수행하는 것을 방지해준다고 생각하면 된다.

 

만약 interceptor없이 구현하게 된다면 또 관련된 인증 메서드, controller나 service에서 검증관련 기능을 수행하고 있을 것이다.

하지만 interceptor를 통해서 해결가능하다

 

interceptor는 prehandle, posthandle, afterCompletion을 통해서 기능을 수행한다

 

스프링 인터셉터는 스프링 mvc가 제공하는 기능이기 때문에 디스패터 서블릿 이후에 등장하여 수행하게 된다.

 

public interface HandlerInterceptor {

	default boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
			throws Exception {

		return true;
	}


	default void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
			@Nullable ModelAndView modelAndView) throws Exception {
	}

	default void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler,
			@Nullable Exception ex) throws Exception {
	}

}

 

 

Spring 요청 처리 과정

 

나도 프로젝트에 적용하면서 ArgumentResolver가 언제 적용되는 건데?? interceptor은 대충알겠는데.. 라는 고민을 했다. 그래서 이리저리 검색하다보다 찾아본 결과

 

간단하게 동작 방식을서려애보자면

 

요청이 들어옴

-> 필터 작동(스프링 시큐리티도 해당, 필터를 구현할 수 도 있음)

-> DispatcherServlet에 전달됨(스프링의 핵심 객체로 client의 요청을 받고 응답을 주는 모든 역할 담당)

-> DispatcherServlet은 HandlerMapping을 통해 요청을 처리할 Controller를 찾는다.

     만약 여기서 Interceptor가 체크해야할 url이라면 preHandler메서드를 실행한다

-> DispatcherServlet은 Controller를 실행해줄 HandlerAdapter를 찾는다. 

    여기서 Adapter가 handler를 실행하기 위해 필요한 파라미터 생성 Resolver를 실행한다

-> HandlerAdapter는 Controller를 샐행한 후에 인터셉터의 postHandle를 실행한다

-> DispatcherServlet은 실행결과를 ViewResolver에 전달한다

-> View로 전달된후 인터셉터의 aftercompletion이 실행한다

-> 이후 Client에 정보를 전달한다

 

 

그래서 생각해본게 인터셉터나 리졸버를 통해서 컨트롤러에 과한 책임을 덜어주고 중복되는 로직을 방지해주는 역할을 해주는 것같다. 

 

 

 

 

인프런_김영한님의 스프링 MVC2 자료를 참고하였습니다