SPRING
2018.09.23 / 16:13

Spring Boot¿¡¼­ Interceptor »ç¿ëÇϱâ

hangawee
Ãßõ ¼ö 210

ÀÎÅͼÁÅÍ?

Spring ¶Ç´Â Spring Boot ÇÁ·¹ÀÓ¿öÅ©·Î À¥ ¾îÇø®ÄÉÀ̼ÇÀ» °³¹ßÇÏ´Ù º¸¸é ¾Æ·¡¿Í °°Àº ¿ä±¸»çÇ×ÀÌ »ý±â°Ô µË´Ï´Ù.

  1. ƯÁ¤ url ÁøÀÔ ½Ã ·Î±×ÀÎÀÌ µÈ(Àΰ¡µÈ) »ç¿ëÀÚ°¡ Á¢±ÙÀ» ÇØ¾ß ÇÔ
  2. ƯÁ¤ url ÁøÀÔ ½Ã Jwt¿Í °°Àº ÅäÅ«À» °Ë»çÇØ¾ß ÇÔ
  3. ƯÁ¤ urlÀÇ °æ¿ì °èÁ¤ÀÇ ±ÇÇÑ¿¡ µû¶ó Á¢±ÙÀ» ¸·¾Æ¾ß ÇÔ (¹°·Ð ÀÌ ºÎºÐÀº view´Ü¿¡¼­ ó¸®ÇÒ ¼öµµ ÀÖ½À´Ï´Ù.)

À§ ¿ä±¸»çÇ×ÀÇ Æ¯Â¡Àº Æ¯Á¤ url ÁøÀÔ ½Ã ¾î¶² ÀÛ¾÷À» ¼öÇàÇØ¾ß ÇÏ´Â °Í ÀÔ´Ï´Ù.
À̸§ÀÇ ÀÇ¹Ì¿Í °°ÀÌ ¹«¾ð°¡¸¦ ÁøÇàÇÒ ¶§ ƯÁ¤ ÀÛ¾÷À» ¼öÇàÇÏ´Â °ÍÀÌ ÀÎÅͼÁÅÍÀÔ´Ï´Ù.
Java À¥ ÇÁ·Î±×·¡¹Ö¿¡¼­´Â ÀÌ·± ÀÛ¾÷À» ÇÏ´Â ±â¼ú·Î´Â Servlet FilterInterceptorAOP°¡ ÀÖ½À´Ï´Ù.

ÀÌ ¼¼°¡Áö ±â¼ú¿¡ ´ëÇÑ Â÷À̸¦ ¸ÕÀú °£·«ÇÏ°Ô »ìÆ캸°í Æ÷½ºÆÃÀ» ÁøÇàÇϵµ·Ï ÇÏ°Ú½À´Ï´Ù.
(AOPÀÇ °æ¿ì ¼­ºí¸´ ÇÊÅÍ¿Í ÀÎÅͼÁÅÍ¿Í ¼ºÇâÀÌ ¸¹ÀÌ ´Ù¸£±â¿¡ AOP´Â ÇâÈÄ º°µµ Æ÷½ºÆÿ¡¼­ ´Ù·ç°Ú½À´Ï´Ù.)


ÀÎÅͼÁÅÍ¿Í ¼­ºí¸´ ÇÊÅÍÀÇ Â÷ÀÌÁ¡

¸ÕÀú ¼³¸í¿¡ ¾Õ¼­ »çÁøÀ» Çϳª º¸¸é¼­ ¼³¸í µå¸®°Ú½À´Ï´Ù.

À§ »çÁøÀº Spring request lifecycleÀ» µµ½ÄÈ­ ÇÑ °ÍÀÔ´Ï´Ù.
»çÁø¿¡¼­ ¾Õ »ç¿ëÀÚÀÇ ¿äû¿¡ º¸¸é ÇÊÅÍ(Filter)¿Í µð½ºÆÐÃÄ ¼­ºí¸´ÀÌ º¸ÀÏ°Ì´Ï´Ù.

Servlet Filter´Â Dispatcher ServletÀÇ ¾Õ´Ü¿¡¼­ µé¾î¿À´Â ¿äû Á¤º¸¸¦ ó¸®ÇÕ´Ï´Ù.
Interceptor´Â Dispatcher ServletÀÇ µÚÀÇ Handler ¿µ¿ª¿¡¼­ ¿äû Á¤º¸¸¦ ó¸®ÇÕ´Ï´Ù.
±×¸®°í Servlet FilterÀÇ °æ¿ì J2EEÀÇ Ç¥ÁØ ½ºÆå¿¡ Á¤ÀÇ°¡ µÇ¾îÀÖ½À´Ï´Ù¸¸, Interceptor´Â Spring ÇÁ·¹ÀÓ¿öÅ©¿¡¼­ ÀÚüÀûÀ¸·Î Á¦°øÇÏ´Â ±â´ÉÀÔ´Ï´Ù.
¶ÇÇÑ Servlet Filter´Â µð½ºÆÐó ¼­ºí¸´ Àü¿¡ È£ÃâÀÌ µÇ¹Ç·Î Spring ÇÁ·¹ÀÓ¿öÅ©¿Í ¹«°üÇÑ °ÍÀ» ó¸®ÇÒ ¼ö ÀÖ½À´Ï´Ù.

Á¤¸®ÇÏ¿© Spring¿¡¼­ È帧 ¼ø¼­¸¦ º¸ÀÚ¸é ¾Æ·¡¿Í °°½À´Ï´Ù.

»ç¿ëÀÚ ¿äû(Request) -> Servlet Filter -> Dispatcher Servlet -> Interceptor -> Controller

µÑÀÇ Â÷ÀÌÁ¡¿¡ ¼³¸íÀº ÀÌ°ÍÀ¸·Î ¸¶¹«¸®ÇÏ°í, Spring Bootȯ°æ¿¡¼­ ÀÎÅͼÁÅ͸¦ Àû¿ëÇÏ´Â ¹æ¹ý¿¡ ´ëÇÏ¿© ¾Ë¾Æº¸µµ·Ï ÇÏ°Ú½À´Ï´Ù.


Spring Boot¿¡¼­ Interceptor Àû¿ëÇϱâ

À̹ø ¿¹½ÃÀÇ È¯°æÀº ´ÙÀ½°ú °°½À´Ï´Ù.

  • Spring Boot 1.5.8
  • Java Config

Spring Boot¿¡¼­ Àû¿ëÇÏ·Á¸é ´ÙÀ½ÀÇ °úÁ¤À» °ÅÃļ­ Àû¿ëÇÕ´Ï´Ù.


1. HandlerInterceptorAdapter¸¦ »ó¼Ó¹ÞÀº Ŭ·¡½º ±¸Çö

ÀÎÅͼÁÅÍ ±¸ÇöÀ» Çϱâ À§Çؼ­´Â HandlerInterceptorAdapter Ãß»ó Ŭ·¡½º¸¦ »ó¼Ó¹Þ¾Æ ±¸ÇöÇØ¾ß ÇÕ´Ï´Ù.

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
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@Slf4j
public class TestInterceptor extends HandlerInterceptorAdapter {

@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
log.info("Interceptor > preHandle");
return true;
}

@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
log.info("Interceptor > postHandle");
}

@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object object, Exception arg3) throws Exception {
log.info("Interceptor > afterCompletion" );
}
}

HandlerInterceptorAdapter Ãß»ó Ŭ·¡½º¸¦ »ó¼Ó¹Þ¾Æ ±¸ÇöÇÕ´Ï´Ù.
Àú Ãß»ó Ŭ·¡½º¿¡´Â ¾Æ·¡¿Í °°Àº ¸Þ¼­µå°¡ ¼±¾ðµÇ¾î ÀÖ°í ´ÙÀ½°ú °°Àº ÀÛ¾÷À» ¼öÇàÇÕ´Ï´Ù.

  • PreHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
    • ÄÁÆ®·Ñ·¯(Áï RequestMappingÀÌ ¼±¾ðµÈ ¸Þ¼­µå ÁøÀÔ) ½ÇÇà Á÷Àü¿¡ µ¿ÀÛ.
    • ¹Ýȯ °ªÀÌ trueÀÏ °æ¿ì Á¤»óÀûÀ¸·Î ÁøÇàÀÌ µÇ°í, falseÀÏ °æ¿ì ½ÇÇàÀÌ ¸ØÃä´Ï´Ù.(ÄÁÆ®·Ñ·¯ ÁøÀÔÀ» ÇÏÁö ¾ÊÀ½)
    • Àü´ÞÀÎÀÚ Áß Object handler´Â Çڵ鷯 ¸ÅÇÎÀÌ Ã£Àº ÄÁÆ®·Ñ·¯ Ŭ·¡½º °´Ã¼ÀÔ´Ï´Ù.
  • PostHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView)
    • ÄÁÆ®·Ñ·¯ ÁøÀÔ ÈÄ view°¡ ·£´õ¸µ µÇ±â Àü ¼öÇàÀÌ µË´Ï´Ù.
    • Àü´ÞÀÎÀÚÀÇ modelAndViewÀ» ÅëÇØ È­¸é ´Ü¿¡ µé¾î°¡´Â µ¥ÀÌÅÍ µîÀÇ Á¶ÀÛÀÌ °¡´ÉÇÕ´Ï´Ù.
  • afterComplete(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
    • ÄÁÆ®·Ñ·¯ ÁøÀÔ ÈÄ view°¡ Á¤»óÀûÀ¸·Î ·£´õ¸µ µÈ ÈÄ Á¦ÀÏ ¸¶Áö¸·¿¡ ½ÇÇàÀÌ µÇ´Â ¸Þ¼­µåÀÔ´Ï´Ù.
  • afterConcurrentHandlingStarted(HttpServletRequest request, HttpServletResponse response, Object handler)
    • Servlet 3.0ºÎÅÍ ºñµ¿±â ¿äûÀÌ °¡´ÉÇØÁü¿¡ µû¶ó ºñµ¿±â ¿äû ½Ã PostHandle¿Í afterCompletion¸Þ¼­µå¸¦ ¼öÇàÇÏÁö ¾Ê°í ÀÌ ¸Þ¼­µå¸¦ ¼öÇàÇÏ°Ô µË´Ï´Ù. (Spring¿¡¼­ Á¦°øÇÔ)

Àú °°Àº °æ¿ì ÁøÇàÇÏ´Â ÇÁ·ÎÁ§Æ®¿¡¼­ ºñµ¿±â´Â »ç¿ëÇÏÁö ¾Ê¾Æ¼­ afterConcurrentHandlingStarted ¸Þ¼­µå¸¦ ±¸ÇöÇÏÁö ¾Ê¾ÒÁö¸¸, ºñµ¿±â¸¦ »ç¿ëÇÏ°Ô µÈ´Ù¸é ÇØ´ç ¸Þ¼­µå¸¦ ÀûÀýÇÏ°Ô ±¸ÇöÇÏ¿© »ç¿ëÇÏ¸é µÉ °Í °°½À´Ï´Ù.


2. WebMvcConfigurerAdapter¸¦ »ó¼Ó¹ÞÀº ¼³Á¤ Ŭ·¡½º ±¸Çö

Àú °°Àº °æ¿ì ´ë´Ù¼ö ¼³Á¤À» java·Î ±¸ÇöÀ» ÇÏ¿©, ¾Æ·¡¿Í °°ÀÌ WebMvcConfigurerAdapter¸¦ »ó¼Ó¹Þ¾Æ ¼³Á¤À» ÇÏ¿´½À´Ï´Ù.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import com.mhlab.cb.component.interceptors.SessionCheckInterceptor;
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 WebMvcConfig extends WebMvcConfigurerAdapter {
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new TestInterceptor())
.addPathPatterns("/*")
.excludePathPatterns("/test/**/")
.excludePathPatterns("/users/login"); //·Î±×ÀÎ ÂÊÀº ¿¹¿Ü󸮸¦ ÇÑ´Ù.
}
}

addInterceptors ¸Þ¼­µå¸¦ ±¸ÇöÀ» ÇÒ ¶§ À§¿Í °°ÀÌ ±¸ÇöÀ» Çϸç, ÀÎÅͼÁÅÍ ±¸Çö ½Ã ¸Þ¼­µå üÀÌ´×ÀÌ µÇ¾î Àִµ¥ ÀÌ´Â ´ÙÀ½°ú °°½À´Ï´Ù.
addInterceptor´Â µî·ÏÇÒ ÀÎÅͼÁÅ͸¦ ¼³Á¤Çϸç, addPathPatterns´Â Àû¿ëÇÒ url ÆÐÅÏÀ» ¼³Á¤ÇÕ´Ï´Ù.
¿¹½Ãó·³ /* ·Î Ç¥½ÃÇÒ °æ¿ì ¸ðµç url¿¡ ´ëÇÏ¿© ÀÎÅͼÁÅ͸¦ È£ÃâÇÏ°Ô µË´Ï´Ù.
¶ÇÇÑ Ã¼ÀÌ´×À» ÀÌ¿ëÇÏ¿© ¿¬¼ÓÀûÀ¸·Î ´Ù¸¥ Ãß°¡ ÆÐÅϵµ µî·ÏÇÒ ¼ö ÀÖ½À´Ï´Ù.
excludePathPatternsÀÇ °æ¿ì ÀÎÅͼÁÅ͸¦ Á¦¿ÜÇÒ url ÆÐÅÏÀ» µî·ÏÇÏ´Â ¸Þ¼­µå·Î½á ÇØ´ç url·Î Á¢±Ù ½Ã¿¡´Â ÀÎÅͼÁÅ͸¦ Àû¿ëÇÏÁö ¾Ê°Ô µË´Ï´Ù.


Á¤¸®

À§ ³»¿ëÀ» ÅëÇØ ÀÎÅͼÁÅÍ¿¡ ´ëÇØ °£·«ÇÏ°Ô ¾Ë¾Æº¸¾Ò½À´Ï´Ù.
À̸¦ ÀÀ¿ëÇÑ °ÍÀº 12¿ù 4ÀÏ ¿¬±¸ÀÏÁö Æ÷½ºÆÿ¡¼­ SessionCheckInterceptor¸¦ ÅëÇؼ­ Jwt °ËÁõÀ» ÇÏ´Â °Í¿¡¼­ º¼ ¼ö ÀÖ¾ú½À´Ï´Ù.
Àú Æ÷½ºÆ®¿¡¼­´Â »ó¼¼ÇÏ°Ô´Â ±¸ÇöµÇ¾îÀÖÁö ¾ÊÁö¸¸ Äڵ带 º¸¸é ´ÙÀ½°ú °°½À´Ï´Ù.

1
2
3
4
5
6
7
8
9
10
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
log.info("Interceptor > preHandle");
if(hasSessionInAccount(request.getSession())) { return true; }//¼¼¼Ç¿¡ °èÁ¤ Á¤º¸°¡ Á¸ÀçÇÏ´Â °æ¿ì
else {
try { response.sendRedirect("/users/login/nosession"); }
catch (IOException ie ) {} //¸¸¾à ¸®´ÙÀÌ·º¼Ç µµÁß ¿¡·¯°¡ ³­ °æ¿ì
return false;
} //¼¼¼Ç Á¤º¸°¡ Á¸ÀçÇÏÁö ¾Ê´Â °æ¿ì
}

ÀÌó·³ ÀÎÅͼÁÅ͸¦ È°¿ëÇÑ´Ù¸é À¯¿ëÇÏ°Ô »ç¿ëÇÒ ¼ö ÀÖ½À´Ï´Ù.
´ÙÀ½ Æ÷½ºÆÿ¡¼­´Â AOP¿¡ ´ëÇÏ¿© Æ÷½ºÆÃÀ» ÁøÇàÇغ¸µµ·Ï ÇÏ°Ú½À´Ï´Ù.