스프링에서 설정하는 Interceptor 방식 두 가지

Asha·2022년 5월 20일
1

[개발자 지식]

목록 보기
2/4
post-thumbnail

안녕하세요 비전공자 국비 학원 출신의 백엔드 개발자를 취업 준비하고 있는 아샤입니다 !
취업준비를 하면서 cs 지식과 제가 안 써본 툴과 스킬을 중점으로 벨로그를 작성하려고 합니다.

두 번째 포스팅은 Interceptor에 대해서 알아보고자 합니다.
선정한 이유는 바로 오늘 제가 면접을 봤습니다..

근데 면접관님이 제가 프로젝트에 interceptor을 사용하면 언제 작동하냐고 여쭤보셨는데 그에 대한
명확한 답을 하지못해... ^^ 아 오늘 면접끝나고 공부해야겠다는 생각이 들었습니다....!

확실히 제가 사용을 했는데도 왜 사용했는지 설명을 못하니까 제 자신이 듣기에도 신뢰도가 떨어지더라구요 ㅠㅠ
비록 오늘 면접에서는 대답을 하지 못했지만... 다음에는 이제 잘 설명할 수 있기를 기대하며,,,^^


🐟 Interceptor .. ?

Interceptor : 가로챈다!

스프링에서도 말 그대로 interceptor 설정을 하면 중간에서 요청을 가로채 설정대로 처리를 하는 것을 의미합니다!
HandlerInterceptor를 상속받아 클라이언트의 요청이 컨트롤러에 가기 전에 가로채고, 응답이 클라이언트에 가기 전에 가로챕니다.

이 때 어디에서 가로채냐면 DispatcherServlet이 URI를 분석해 Mapping된 Controller를 요청하기 전, 후에 요청과 응답을 가로채서 가공할 수 있게 해줍니다!

즉 호출 시점은 DispatcherServlet에 요청이 되기 전 URL 패턴에 맞는 모든 요청에 해 부가작업을 처리할 수 있는 제공을 하는 Filter가 가장 먼저 호출이 되고 그 후 DispatcherServlet이 작동하고 이 후 Interceptor가 로직에 따라 동작할 지 안할 지가 나뉘게 됩니다.!


🗝️Filter & Interceptor 뭐가 더 먼저 작동할까?

외우기가 어렵다면 Filter는 Web Container에 의해 관리 됩니다. 그렇기 때문에 가장 먼저 동작되는 것이죠. 그리고 Filter를 거친 Interceptor는 Spring Container에 의해 관리 되기 때문에 개념만 알고 있으면 순서는 사실 당연한 것이죠!(Web > Spring)


🔑Interceptor 설정 찍먹하기

제가 프로젝트를 하면서 Interceptor를 설정한 적이 있었는데 좀 아쉬움이 남습니다..
저는 HadlerInterceptor를 상속받아 사용하는 java로 된 Interceptor와 xml에 선언해서 사용하는 Interceptor 두 가지를 모두 사용해 봤습니다!

interceptor/LoginInterceptor.java

public class LoginInterceptor extends HandlerInterceptorAdapter{
	
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
		HttpSession session = request.getSession();
		String path = request.getRequestURI();
		if(path.contains("/index")|| path.contains("/login") || path.contains("/insert") || path.contains("/findPwd") || path.contains("/callback") || path.contains("EmailConfirm")
					||path.contains("/idDup") || path.contains("/nicknameDup")) {
			return true;
		}else if(session.getAttribute("adminAuthInfoCommand") == null 
				&& session.getAttribute("memberLogin") == null) {
				//session admin로그인하고 memberLogin 둘다 없으면 main으로 redirect하도록
			response.sendRedirect(request.getContextPath()+"/index");
		}
		
		
		return true;
	}
	
	public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView mav) throws Exception {
		super.postHandle(request, response, handler, mav);
	}

..맘에 들지는 않습니다. ㅎ
이게 왜 이렇게 됐냐면 처음에 Interceptor를 염두해두고 설계한 것이 아니라 나중에 추가한 했습니다.
구현 과정에서 Interceptor를 기준으로 작동을 하지 말아야하는 정적 파일의 resources, 로그인 창, 회원가입, 비밀번호 정도로 해결이 되었으나
+소셜 로그인 api를 구현하면서 추가된 /callback, 회원가입 form에서 ajax로 처리한 /idDup , /nicknameDup이 추가가 되면서 코드가 보기 힘들어졌다!
(Interceptor 적용하고,, 잘 되던 기능이 안된다고 절망하던 팀원...미안...그리고 sendRedirect() 오류는 경험상 Interceptor 놈이 작동할 확률이 크다 error code 302)

이렇게 HandlerInterceptorAdapter를 상속받아 preHandle을 오버라이딩해 Controller로 요청하기 전에 처리를 해주었다. 하지만 해결된 줄 알았던 index.jsp 에서 넣은 이미지와 기타 파일들이 출력되지 않은 문제가 생겼다!

이쯤되면 또 Interceptor가 작동을 했구나 눈치를 챌 수 있어서 확인하러 갔는데 spring security를 적용했다면 아마 이런 보기 힘든 코드를 안 짰어도 될 것 같다.

	<interceptors>
		<interceptor>
			<mapping path="/**/" />
		    <exclude-mapping path="/**/*.css"/>
		    <exclude-mapping path="/**/*.js"/>
		    <exclude-mapping path="/**/*.png"/>
		    <exclude-mapping path="/**/*.jpg"/>
		    <exclude-mapping path="/**/*.mp4"/>
		    <exclude-mapping path="/images/**/*.*"/>
			<beans:ref bean="loginInterceptor" />
		</interceptor>		
		<beans:bean id="webContentInterceptor"
			class="org.springframework.web.servlet.mvc.WebContentInterceptor">
			<beans:property name="cacheSeconds" value="0" />
			<beans:property name="useExpiresHeader" value="true" />
			<beans:property name="useCacheControlHeader" value="true" />
			<beans:property name="useCacheControlNoStore" value="true" />
		</beans:bean>
	</interceptors>    

일단 Interceptor를 처음 적용해보는 나 조차도 이건 아닌데 라는것을 직감했다.
그래서 spring security를 적용하면 괜찮다는 말을 들어서 지금 열심히 공부중이다...!

아무튼 Interceptor를 설정하는 것에는 두 가지 방식이 있는데 우선은 java에서 HandlerInterceptorAdapter를 이용하던가, xml에 적어주는 방식이 있다!

처음부터 Interceptor를 적용을 염두해두고 있다면 예외되는 요청들을 따로 정리하여 mapping 해주면 더 좋지 않았을까 아쉬움이 남는다..!

아무튼 이렇게 반성의 시간을 가지며 모두들 좋은 코드를 짜셨으면 좋겠습니다!
항상 화이팅입니다! 🥰

profile
열심히 살 수 있을 때 열심히 살자 !

0개의 댓글