WAS, Servlet, Filter, Interceptor
WAS ๐ฐ WEB โ ์๋ธ๋ฆฟ ์ปจํ
์ด๋
WAS ๋ด๋ถ์ ๋์คํจ์น ์๋ธ๋ฆฟ ๋ด๋ถ๋์์ด ์ผ์ด๋๊ณ ์ด ์์ ์คํ๋ง์ด ๋ ์์
๋ฐ๋ผ์ ์คํ๋ง์ ๊ฐ๋ฐํ ๋ ์ฐ๋ฆฌ๋ ์๋ธ๋ฆฟ ์ปจํ
์ด๋์ ์ผ๋ถ๋ฅผ ๊ตฌํํ๋ ๊ฒ์ด๋ค.
โ WAS
WAS: Web Application Server
client ์์ฒญ์ ๋ฐ์ ์๋ฏธ ์๋ ์น ์ ํ๋ฆฌ์ผ์ด์ ์ ์คํํ๋ ์๋ฒ
โ๏ธ WAS์ web์๋ฒ๊ฐ ํ๋ ์ญํ
- ์ ์ ์ธ ํ์ผ์ ๋ฐ์ ์ฒ๋ฆฌ(ํญ์ ๊ฐ์ input, output์ด ๋์ค๋ ๊ฒ๋ค, ์ด๋ฏธ์ง, ์์ ๋ฑ)
- ๋์ ์ธ ์์ฒญ์ ์๋ธ๋ฆฟ ์ปจํ
์ด๋๋ก ์์
โ ์๋ธ๋ฆฟ ์ปจํ ์ด๋(๐ฐ ์น ์ปจํ ์ด๋)
๋ํ์ ์ธ ๊ตฌํ์ฒด: tomcat
- ํ๋กํ ์ฝ ์์ฒญ/์๋ต ์ฒ๋ฆฌ
- ์ฐ๋ ๋ ํ ๊ด๋ฆฌ
- ์คํ๋ง ์ง์ ๋ฐํ์ ์ปดํฌ๋ํธ
โ๏ธ Servlet
Servlet: ํด๋ผ์ด์ธํธ ์์ฒญ์ ์ฒ๋ฆฌ & ์๋ฒ์์ ๋์ ์ธ ์น ํ์ด์ง๋ฅผ ์์ฑํ๋๋ฐ ์ฌ์ฉ๋๋ ์ฃผ์ฒด
โ๏ธ Protocol ๊ด๋ จ Servlet
WAS๋ HTTP๋ฟ๋ง ์๋๋ผ ๋ค์ํ ํ๋กํ ์ฝ ์ง์
โ๏ธ Server framework ๊ด๋ จ Servlet
WAS๋ ์คํ๋ง๊ณผ ๊ทธ ์ธ ๋ค์ํ ํ๋ ์์ํฌ ์ง์
์คํ๋ง โก๏ธ ๋์คํจ์น ์ธ๋ธ๋ ์ด ์ฒ๋ฆฌํด์ค๋ค.
โ ์๋ธ๋ฆฟ ์ปจํ ์ด๋์ ์คํ๋ง ์ปจํ ์ด๋
โ๏ธ ์๋ฒ ์์ผ
์๋ฒ๋ ๋ฌด์กฐ๊ฑด ์๋ฒ ์์ผ์ ์ด์ด๋๊ณ ์์ด์ผ ํ๋ค.
์๋ธ๋ฆฟ ์ปจํ
์ด๋๊ฐ ์ฐ๋ค.
ํฌํธ ์ด์ด์ ์๋ฒ์์ ์ฃผ๊ณ ๋ฐ์ ์ค๋น
โ๏ธ ์ ์ถ๋ ฅ stream
stream์ ํตํด์ ๋ฐ์ดํฐ ์ฃผ๊ณ ๋ฐ๊ธฐ
โ๏ธ ์ฐ๋ ๋ ํ
์ฐ๋ ๋ ํ๋ ๋ฏธ๋ฆฌ ์์ฑํด๋๋ค.
๋ฏธ๋ฆฌ ์ฐ๋ ๋ ์ฌ์ฉํ๋ ค๊ณ ์์ฑํด ๋ pool
๋ฉํฐ ์ฐ๋ ๋ฉ ์์ํ๋ฉด ๋ฏธ๋ฆฌ ๋ง๋ค์ด ๋ ๊ฐ์ฒด๋ฅผ ์ฃผ๋ฉฐ โ์ด๊ฑฐ ์จ!โ ํ๋ค.
์ฌ์ฉ ํ ์ฐ๋ ๋ ํ์ ๋ฐํ
- WAS(๐ฐtomcat)์ด ์ผ์ง๋ค.
- ์๋ฒ ์์ผ OPEN(port 8080)
- thread pool ๋ง๋ค์ด ๋๋๋ค.
- Web browser์์ ์๋ฒ ์์ผ์ด ์ด๋ฆฐ ๊ฒ์ ํ์ธํ๊ณ HTTP GET API์์ฒญ์ ๋ณด๋ธ๋ค.
- ์ด ์์ฒญ์ Web์ด ๊ฐ์ฅ ๋จผ์ ๋ง๋๋๋ฐ, ์์ ์ด ์ฒ๋ฆฌํ ์ ์๋ ์ ์ ์ธ ๊ฒ์ด๋ฉด ์ฒ๋ฆฌ, ์ฒ๋ฆฌ ๋ชปํ๋ฉด ์๋ธ๋ฆฟ ์ปจํ
์ด๋๋ก ๋๊ธด๋ค.
- thread pool์์ thread๋ฅผ ํ ๋น๋ฐ๋๋ค.
- ์
์ถ๋ ฅ stream์ ์ฐ๋ค.
๐๐ป ๋ฐ์ดํฐ ์ฃผ๊ณ ๋ฐ์ ์ค๋น ์๋ฃ - ์์ผ ํตํด์ ์ ๋ณด ๋ฐ์
- ์ ๋ณด๊ฐ HTTP Protocol๋ก ์์ผ๋ฉด Protocol ๊ด๋ จ ์๋ธ๋ ์ปจํ
์ด๋์์ ์ฒ๋ฆฌ
- ์ด๋ค ํ๋ ์์ํฌ ์ฐ๋์ง์ ๋ฐ๋ผ server framework ์๋ธ๋ ์์ ์ฒ๋ฆฌ
- HTTP method, URI๋ณด๊ณ ํด๋นํ๋ controller์ ๋งคํ๋์ด ์ฒ๋ฆฌ
๐๐ป ๋ฐ์ดํฐ ๋ฐ๊ธฐ ๋ - ๋ฐ์ดํฐ ๋ณด๋ผ๋๋ ๋ฐ๋.
- controller๊ฐ ๋ณด๋ธ๋ค.
- HTTP์์ ์์ผ์ผ๋ก ๊ฐ์ ๋ฐ์ดํฐ ๋ณด๋ด๊ณ
- ์ฌ์ฉํ thread๋ฐํ
โ ๋์คํจ์น ์๋ธ๋ ์ ๋ด๋ถ ๋์ ํ๋ฆ
HTTP method, URI๋ณด๊ณ ์ปจํธ๋กค๋ฌ ์ ํ๊ฒ ๋๋๋ฐ,
์ปจํธ๋กค๋ฌ๋ง๋ค ์ฒ๋ฆฌ ๋ฐฉ๋ฒ์ด ๋ค๋ฅด๋ค.
โ๏ธ SSR controller โก๏ธ @Controller
โ๏ธ CSR controller
โ Spring MVC Pattern โก๏ธ @RestController
Model View Controller
๋์คํจ์น ์๋ธ๋ : ํ๋ก ํธ ์ปจํธ๋กค๋ฌ ํจํด์ ๊ตฌํํ๋ค.
๊ฐ๊ฐ์ ์ญํ ์ ๊ฐ์ฒด์๊ฒ ๋งคํํ์ฌ(์ฃผ์ด์) ์ํ
ํ๋ก ํธ ์ปจํธ๋กค๋ฌ ํจํด์ธ ์ด์ ๋ ์ด๋ค ์์ฒญ์ด ์๋ ์์์ servlet์ด ๋งคํ์ ํตํด ๊ด๋ฆฌํ๋ค.
โ WAS๋ HTTP์์ฒญ ์, Servelt Request/Response๋ฅผ ๋ง๋ ๋ค.
โ๏ธ HTTP Servelt Request
- ์์ฒญ ์ ๋ณด๋ฅผ ์๋ธ๋ฆฟ์๊ฒ ์ ๋ฌํ๊ธฐ ์ํ ๊ฐ์ฒด
- ํค๋/URL/๋ฉ์๋ ๋ฑ์ ํ์ธํ๋ ๋ฉ์๋๊ฐ ์๋ค.
- Body Stream(input)์ ์ฝ๋ ๋ฉ์๋๊ฐ ์๋ค.
- ๊ธฐ์กด์ @RequestParam์ผ๋ก ๋ฐ๋ Input๊ฐ์ HTTP Servelt Request์ผ๋ก ๋์ ๋ฐ์ ์ ์๋ค.
๐ก ์๋๋ HttpServletRequestํด์ ๋ฐ์์ค๋ ๊ฒ์ธ๋ฐ @RequestParam๊ฐ ์ผ์ ํด ์ค ๊ฒ์ด๋ค.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public class Chap109Controller {
private final ItemService itemService;
//@RequestParam
// @GetMapping("/items-prices")
// public List<Item> findItemByPrices(@RequestParam("max") Integer maxValue){ //โญ๏ธ@RequestParam
// List<Item> items= itemService.findItemEntitiesByPriceLessThanEqualOrderByPriceAsc(maxValue);
// return items;
// }
//HttpServletRequest
@GetMapping("/items-prices")
public List<Item> findItemByPrices(HttpServletRequest httpServletRequest){
Integer maxValue= Integer.valueOf(httpServletRequest.getParameter("max"));
List<Item> items= itemService.findItemEntitiesByPriceLessThanEqualOrderByPriceAsc(maxValue);
return items;
}
}
โ๏ธ HTTP Servelt Response
- ์์ฒญ์ ๋ณด๋ธ ํด๋ผ์ด์ธํธ์๊ฒ ์๋ต์ ๋ณด๋ด๋ ๊ฐ์ฒด
- ํด๋น ์๋ธ๋ฆฟ์ ํตํด ์๋ต output์ ์ ์กํ๋ค.
- ๊ธฐ์กด์ @RestController๋ก output๋ด๋ณด๋ด๋ ์์
์ HTTP Servelt Response๋ก ํ ์ ์๋ค.
๐ก ๊ธฐ์กด @PathVariable์ ์ฌ์ค HTTP Servelt Response์ getOutputStream()๋ก ๋์ํ๊ณ ์๋ ๊ฒ์ด๋ค.
1
2
3
4
5
6
7
8
9
10
11
// @DeleteMapping("/items/{id}")
// public String deleteItemById(@PathVariable String id) {
// itemService.deleteItem(id);
// return "Object with id =" + id + "has been deleted";
// }
@DeleteMapping("/items/{id}")
public void deleteItemById(@PathVariable String id, HttpServletResponse httpServletResponse) throws IOException {
itemService.deleteItem(id);
httpServletResponse.getOutputStream().println("Object with id =" + id + "has been deleted");
}
โ Servelt Container์์ Web Filter
ํ์ฉ๋์ง ์์ ์์ฒญ, ์๋ต์ด ์ค๋ฉด filter๊ฐ ๊ฑธ๋ฌ์ฃผ๊ฑฐ๋
๊ธฐ๋ก์ ๋จ๊ธฐ๋ filter๋ ์๊ณ
์ธ์ด๊ฐ ๋ฌ๋ผ ๊นจ์ง์ฑ๋ก ์ค๋ฉด filter๊ฐ encoding ์ฒ๋ฆฌํด์ฃผ๊ฑฐ๋ ๋ฑ๋ฑ์ ์ญํ ์ ํ๋ค.
Spring Container ๋ฐ์ ์์
๋ฐ๋ผ์ Spring์ ์์์ ์๋๋ค. โ
โ๏ธ doFilter()๋ฉ์๋๋ก ์๋ต/์์ฒญ ๋์์ ํ๋ค.
Request/Response ๊ฐ์ฒด์ ๊ด์ฌํ๋ค. โญ๏ธ
๊ทธ๋์ Request/Response ๋ฐ์ ๊ฐ์ ๋ฐ๊ฟ ์ ์๋ ๊ฒ์.
๐ก Filter ๊ธฐ๋ฅ
- ์ด๋ฏธ์ง/๋ฐ์ดํฐ ์์ถ ๋ฐ ๋ฌธ์์ด ์ธ์ฝ๋ฉ
- ๋ชจ๋ ์์ฒญ์ ๋ํ ๋ก๊น
- ๊ณตํต ๋ณด์ ๋ฐ ์ธ์ฆ/์ธ๊ฐ
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
//๋ชจ๋ ์์ฒญ์ ๋ํ ๋ก๊น
๋จ๊ธฐ๋ filter
@Component
@Slf4j
public class LoggingFilter extends OncePerRequestFilter { //๋๋ง์ filter์ ๋ง๋ค๋
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
String method= request.getMethod();
String uri= request.getRequestURI();
log.info("์์ฒญ์ด ๋ค์ด์์ต๋๋ค. "+ method + uri); //โญ๏ธcontroller์ ์ด ์ฝ๋๋ฅผ ์ฐ์ง ์๊ณ filter์ ํ ๋ฒ์ ์ด๋ค.
filterChain.doFilter(request, response);
//๊ธฐ์กด ์๋ filter chain์ ๋ด filter๋ ๋ผ์์ฃผ๋ผ
//โญ๏ธdoFilter์์ ์ฐ๋ฉด ๋ค์ด์ฌ ๋ Filter, ๋ค์ ์ฐ๋ฉด ๋๊ฐ ๋ Filter
log.info(method + uri + response.getStatus()+ "response");
}
}
โ Spring Container์์ Interceptor
๊ธฐ๋ณธ์ ์ผ๋ก filter์ด๋ ๋น์ทํ๊ฒ ๊ฑธ๋ฌ์ฃผ๊ฑฐ๋ ์ถ๊ฐ ๊ธฐ๋ฅ์ ์ํํด์ฃผ๋๋ฐ
filter๋ ๋ค๋ฅธ ์ ์ Spring Container์์ ์๋ค๋ ๊ฒ์ด๋ค.
Interceptor์ Spring Container์ ์์์ด๋ค. โญ๏ธ
โ๏ธ ์์ฒญ : preHandler()
โ๏ธ ์๋ต: postHandler() ๋ฉ์๋๋ก
Request/Response ๊ฐ์ฒด์ ๊ด์ฌํ์ง ์๋๋ค. โ
Request/Response ๊ฐ์ฒด์ ๊ด์ฌํ๊ณ ์ถ์ผ๋ฉด filter๋ก ํ์ธ์โฆ
โญ๏ธ ์์
filter โก๏ธ controller โก๏ธ (๋ค์ด์ค๊ธฐ ๋) โก๏ธ ๊ฒฐ๊ณผ โก๏ธ (๋๊ฐ๊ธฐ) โก๏ธ controller โก๏ธ interceptor โก๏ธ filter
๐ก Interceptor ๊ธฐ๋ฅ
- API ํธ์ถ ์๊ฐ ๋ก๊น
- ์น์
๋ฐ ์ฟ ํค ์ฒดํฌ
- ์ธ๋ถ์ ์ธ ๋ณด์ ๋ฐ ์ธ์ฆ
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
32
33
//API ํธ์ถ ์๊ฐ ๋ก๊น
ํ๋ Interceptor
@Component
@Slf4j
public class RequestTimeLoggingInterceptor implements HandlerInterceptor {
//controller ์์ฒญ ์
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
long startTime= System.currentTimeMillis(); //ํ์ฌ ์๊ฐ
request.setAttribute("request start time" , startTime);
return true;
}
//controller ์์ฒญ ๋๋ ํ
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
long startTime= (Long) request.getAttribute("request start time");
long endTime= System.currentTimeMillis();
long executeTime= endTime - startTime;
log.info("{} {} executed in {} ms", request.getMethod(), request.getRequestURI(), executeTime);
}
}
//Interceptor์ ๊ฐ์ ธ์ค๊ธฐ ์ํด configํ์ํ๋ค.
@Configuration
@RequiredArgsConstructor
public class WebConfig implements WebMvcConfigurer {
private final RequestTimeLoggingInterceptor requestTimeLoggingInterceptor;
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(requestTimeLoggingInterceptor);
}
}