Servlet Filter(์๋ธ๋ฆฟ ํํฐ)
by rlaehddnd0422์๊ตฌ์ฌํญ์ ๋ณด๋ฉด ๋ก๊ทธ์ธ ํ ์ฌ์ฉ์๋ง ์ํ ๊ด๋ฆฌ ํ์ด์ง์ ๋ค์ด๊ฐ ์ ์์ด์ผ ํ๋๋ฐ, ๋ก๊ทธ์ธ์ ํ์ง ์์๋ URL์ ํตํด ์ํ ๊ด๋ฆฌ ํ์ด์ง์ ์ ๊ทผํ ์ ์์ต๋๋ค.
- http://localhost:8080/items
์ํ ๊ด๋ฆฌ ์ปจํธ๋กค๋ฌ์์ ๋ก๊ทธ์ธ ์ฌ๋ถ๋ฅผ ์ฒดํฌํ๋ ๋ก์ง์ ํ๋ํ๋ ์์ฑํ๋ฉด ๋๊ฒ ์ง๋ง, ๋ฑ๋ก, ์์ , ์ญ์ , ์กฐํ ๋ฑ๋ฑ ์ํ๊ด๋ฆฌ์ ๋ชจ๋ ์ปจํธ๋กค๋ฌ ๋ก์ง์ ๊ณตํต์ผ๋ก ๋ก๊ทธ์ธ ์ฌ๋ถ๋ฅผ ํ์ธํด์ผ ํฉ๋๋ค. ์๋ก์ด ๋ก์ง์ด ์๊ธฐ๊ธฐ๋ผ๋ ํ๋ค๋ฉด ๋ ๋ก๊ทธ์ธ ์ฌ๋ถ๋ฅผ ์ฒดํฌํ๋ ๋ก์ง๊น์ง ์๊ฐํด์ ์ง์ผํฉ๋๋ค. ์์ฒญ ๊ท์ฐฎ์ ์ผ์ ๋๋ค.
์ ํ๋ฆฌ์ผ์ด์ ์ฌ๋ฌ ๋ก์ง์์ ๊ณตํต์ผ๋ก ๊ด์ฌ์ด ์๋ ๊ฒ์ ๊ณตํต ๊ด์ฌ์ฌ ๋ผ๊ณ ํฉ๋๋ค.
๊ณตํต ๊ด์ฌ์ฌ๋ ์คํ๋ง์ AOP - @Around ๋ฅผ ์ด์ฉํด์ ํด๊ฒฐํ ์๋ ์์ง๋ง, ์น๊ณผ ๊ด๋ จ๋ ๊ณตํต ๊ด์ฌ์ฌ๋ ์๋ธ๋ฆฟ ํํฐ๋ ์คํ๋ง ์ธํฐ์ ํฐ๋ฅผ ์ฌ์ฉํ๋ ๊ฒ์ด ์ข์ต๋๋ค.
์๋ธ๋ฆฟ ํํฐ
ํํฐ๋ ์๋ฐ ํ์ค ์คํ์์ ์ ๊ณตํ๋ ๊ธฐ์ ์ ๋๋ค.
ํํฐ๋ฅผ ์ ์ฉ ์
HTTP Request โถ๏ธ WAS โถ๏ธ ํํฐ โถ๏ธ ์๋ธ๋ฆฟ โถ๏ธ ์ปจํธ๋กค๋ฌ
์ค๊ฐ์ ํํฐ๋ฅผ ๊ฑฐ์ณ์ ์ปจํธ๋กค๋ฌ๋ก ๊ฐ๊ฒ ๋ฉ๋๋ค. ( ์ฌ๊ธฐ์ ์๋ธ๋ฆฟ์ DispatcherServlet ( FrontController ) )
ํํฐ์์ ๊ฑธ๋ฆฌ๊ฒ ๋๋ฉด ์ ์ ํ์ง ์์ ์์ฒญ์ด๋ผ ํ๋จํด ์๋ธ๋ฆฟ์ ํธ์ถํ์ง ์๊ฒ ๋ฉ๋๋ค.
+ ํํฐ๋ ์ฒด์ธ์ผ๋ก ๊ตฌ์ฑ๋๋๋ฐ, ์ค๊ฐ์ ํํฐ๋ฅผ ์์ ๋กญ๊ฒ ์ถ๊ฐํ ์ ์์ต๋๋ค.
HTTP Request โถ๏ธ WAS โถ๏ธ ํํฐ1 โถ๏ธ ํํฐ2 โถ๏ธ ํํฐ3 โถ๏ธ ์๋ธ๋ฆฟ โถ๏ธ ์ปจํธ๋กค๋ฌ
ํํฐ ์ธํฐํ์ด์ค
public interface Filter {
public default void init(FilterConfig filterConfig) throws ServletException {}
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException;
public default void destroy() {}
}
- init() : ํํฐ ์ด๊ธฐํ ๋ฉ์๋, ์๋ธ๋ฆฟ ์ปจํ ์ด๋๊ฐ ์์ฑ๋ ๋ ํธ์ถ๋ฉ๋๋ค.
- doFilter() : ํํฐ์ ๋ก์ง์ ๊ตฌํํ๋ ๋ถ๋ถ์ผ๋ก ๋ก์ง ๊ตฌํ ์ดํ chain.doFilter(request,response) ํ์
- destroy() : ํํฐ ์ข ๋ฃ ๋ฉ์๋, ์๋ธ๋ฆฟ ์ปจํ ์ด๋๊ฐ ์ข ๋ฃ๋ ๋ ํธ์ถํฉ๋๋ค.
์ฐ์ ๋จผ์ ์์ฒญ์ ๋ํด ๋ก๊ทธ๋ฅผ ๋จ๊ธฐ๋ ๋จ์ํ ํํฐ๋ฅผ ํํฐ ์ธํฐํ์ด์ค๋ฅผ ๊ตฌํํด์ ์ฌ์ฉํด๋ณด๋๋ก ํ๊ฒ ์ต๋๋ค.
@Slf4j
public class LogFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
log.info("log filter init");
}
@Override
public void destroy() {
log.info("log filter destroy");
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
log.info("log filter doFilter");
HttpServletRequest httpRequest = (HttpServletRequest) request; // ๋ค์ด ์บ์คํ
String requestURI = httpRequest.getRequestURI();
String uuid = UUID.randomUUID().toString();
try
{
log.info("REQUEST [{}][{}]",uuid,requestURI);
chain.doFilter(request,response);
}catch(Exception e){
throw e;
}finally {
log.info("RESPONSE [{}][{}]",uuid,requestURI);
}
}
}
- init()๊ณผ destroy()๋ ์ธํฐํ์ด์ค์ default๋ก ์ ์ธ๋์ด ์๊ธฐ ๋๋ฌธ์ ๊ตณ์ด ๊ตฌํํด ์ฃผ์ง ์์๋ ๋ฉ๋๋ค.
- ์ค์ํ ๋ถ๋ถ์ doFilter(ServletRequest request , ServletResponse response, FilterChain chain) ์ ๋๋ค.
- ServletRequest, ServletResponse๋ HttpServletRequest์ ์์ ์ธํฐํ์ด์ค๋ก HTTP ์์ฒญ,์๋ต์ด ์๋ ๊ฒฝ์ฐ๊น์ง ๊ณ ๋ คํด์ ๋ง๋ ์ธํฐํ์ด์ค์ ๋๋ค.
- HTTP๋ฅผ ์ฌ์ฉํ๋ฉด HttpServletRequest, HttpServletResponse๋ก ๋ค์ด ์บ์คํ ํด์ ์ฌ์ฉํ๋ฉด ๋ฉ๋๋ค.
- try์์ ์์ฒญ์ ๋ํ URI์ UUID๋ฅผ ์ป์ด ๋ก๊ทธ์ ๋จ๊ฒจ์ค๋๋ค. ( ์์ธ๋ฐ์ ์ ๋ณ๋์ ์์ธ์ฒ๋ฆฌ๋ฅผ ํด์ฃผ์ง ์์์ต๋๋ค )
- ์ฌ๊ธฐ์ chain.doFilter(request,response)๊ฐ ์ค์ํฉ๋๋ค.
- ๋ค์ ํํฐ๊ฐ ์์ผ๋ฉด ํํฐ๋ฅผ ํธ์ถ. ํํฐ๊ฐ ์์ผ๋ฉด ์๋ธ๋ฆฟ์ ํธ์ถ. ๋ง์ฝ ์ด ๋ก์ง์ ํธ์ถํ์ง ์๋๋ค๋ฉด ๋ค์ ๋จ๊ณ๋ก ์งํํ์ง ์๊ธฐ ๋๋ฌธ์ ํ์์ ์ผ๋ก ์์ฑํด ์ฃผ์ด์ผ ํฉ๋๋ค.
ํํฐ๋ฅผ ์ ์ฉํ๋ ค๋ฉด ์ด๋ป๊ฒ ํด์ผ ํ ๊น์?
1. @Component๋ก ์๋ ๋ฑ๋ก
@Component
@WebFilter("urlPatterns='/*")
public class LogFilter implements Filter {
์๋ ๋น์ผ๋ก ๋ฑ๋กํ๋ ๋ฐฉ๋ฒ๋ ์์ง๋ง @WebFilter๋ฅผ ์ฌ์ฉํ์ง ์์ผ๋ฉด urlPattern์ ์ง์ ํ ์ ์๊ธฐ ๋๋ฌธ์ ๊ธฐ๋ณธ์ ์ผ๋ก ๋ชจ๋ url ํจํด์ ์ ์ฒด์ ์ ์ฉ์ด ๋ฉ๋๋ค. ๋จ์ ์ ํํฐ๊ฐ ์ฌ๋ฌ๊ฐ์ธ ๊ฒฝ์ฐ ์์์ง์ ์ด ๋ถ๊ฐ๋ฅํฉ๋๋ค.
2. FilterRegistrationBean์ ์ฌ์ฉํด์ ๋ฑ๋ก
- ์๋์ผ๋ก ๋ฑ๋ก @Configuration์ @Bean์ผ๋ก FilterRegistrationBean์ ๋ฑ๋กํ๋ฉด ๋ฉ๋๋ค.
@Configuration
public class WebConfig {
@Bean
public FilterRegistrationBean logFilter()
{
FilterRegistrationBean<Filter> filterFilterRegistrationBean = new FilterRegistrationBean<>();
filterFilterRegistrationBean.setFilter(new LogFilter());
filterFilterRegistrationBean.setOrder(1);
filterFilterRegistrationBean.addUrlPatterns("/*");
return filterFilterRegistrationBean;
}
- setFilter(new LogFilter())๋ก ๋ฑ๋กํ ํํฐ ์ง์ .
- setOrder(1): ํํฐ๋ ์ฒด์ธ์ผ๋ก ๋์ํ๊ธฐ ๋๋ฌธ์ ์์๊ฐ ํ์ํฉ๋๋ค. ๋ฎ์์๋ก ๋จผ์ ๋์
- addUrlPatterns(): ํํฐ๋ฅผ ์ ์ฉํ URL ํจํด์ ์ง์ . ํ๋ฒ์ ์ฌ๋ฌ ํจํด๋ ์ง์ ํ ์ ์์ต๋๋ค.
๊ทธ ์ธ์ ํํฐ ์ค์ ๋ฐฉ๋ฒ์ ์๋๋ฅผ ์ฐธ๊ณ ํ์๋ฉด ์ข์ ๊ฒ ๊ฐ์ต๋๋ค.
https://jronin.tistory.com/124
์ด์ ํํฐ๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ๋ก๊ทธ์ธํ ์ฌ์ฉ์๋ง URL์ ํตํด ์ํ ๊ด๋ฆฌ ํ์ด์ง์ ์ ๊ทผํ ์ ์๋๋ก ํ๊ณ , ๋ก๊ทธ์ธ ๋์ง ์์ ์ฌ์ฉ์๋ ์ํ ํ์ด์ง์ ์ ๊ทผํ์ง ๋ชปํ๋๋ก ์ค์ ํด๋ณด๊ฒ ์ต๋๋ค.
private static final String[] whiteList = {"/","/members/add","/login","/logout","/css/*"};
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
{
HttpServletRequest httpRequest = (HttpServletRequest) request;
HttpServletResponse httpResponse = (HttpServletResponse) response;
String requestURI = httpRequest.getRequestURI();
try {
log.info("์ธ์ฆ ์ฒดํฌ ํํฐ ์์ {}",requestURI);
if(isLoginCheckPath(requestURI))
{
log.info("์ธ์ฆ ์ฒดํฌ ๋ก์ง ์คํ {}", requestURI);
HttpSession session = httpRequest.getSession(false);
if(session == null || session.getAttribute(SessionConst.LOGIN_MEMBER)==null)
{
log.info("๋ฏธ์ธ์ฆ ์ฌ์ฉ์ ์์ฒญ {} ", requestURI);
// ๋ก๊ทธ์ธ์ผ๋ก ๋ฆฌ๋ค์ด๋ ํธ
httpResponse.sendRedirect("/login?redirectURL="+requestURI);
return; // ์ค์
}
}
chain.doFilter(request,response); // ํ์!
}catch..finally ..
}
private boolean isLoginCheckPath(String requestURI)
{
return !PatternMatchUtils.simpleMatch(whiteList,requestURI);
}
ํ์ดํธ ๋ฆฌ์คํธ(ํ์๊ฐ์ , ๋ก๊ทธ์ธ, ๋ก๊ทธ์์, css)์ ์๋ URI๋ฅผ ์ ์ธํ ๋ชจ๋ URI์ ์ ์ฉ์์ผ ์ธ์ ์ ๊ธฐ๋ฐ์ผ๋ก ๋ก๊ทธ์ธ ํ ๊ฒฝ์ฐ(์ธ์ ์ ๊ฐ์ง๊ณ ์๋ ๊ฒฝ์ฐ) ์๋ง ์ํ ๊ด๋ฆฌ ํ์ด์ง์ ์ ๊ทผํ ์ ์๋๋ก ํํฐ๋ฅผ ์ค์ ํ์ต๋๋ค.
- ์ธ์ ์ด ์๊ฑฐ๋, ์ธ์ ์ "loginMember"์ loginMember๊ฐ ์กด์ฌํ์ง ์๋ ๊ฒฝ์ฐ ๋ฏธ์ธ์ฆ ์ฌ์ฉ์ ์์ฒญ์ผ๋ก ํ๋จํด ๋ก๊ทธ์ธ ํ๋ฉด์ผ๋ก ๋ฆฌ๋ค์ด๋ ์ ํฉ๋๋ค.
- ์ด ๋ ํ๋ผ๋ฏธํฐ ์ฟผ๋ฆฌ๋ก requestURI๋ฅผ ๋ก๊ทธ์ธ ์ปจํธ๋กค๋ฌ์ @RequestParam์ผ๋ก ๋๊ฒจ์ ๋ก๊ทธ์ธ ์ฑ๊ณต ์ดํ requestURI๋ก ์๋์ผ๋ก ์ด๋ํ๋๋ก ์ค์ .
@PostMapping("/login")
public String loginV4(@Valid @ModelAttribute LoginForm loginForm, BindingResult bindingResult,
@RequestParam(defaultValue = "/") String redirectURL,
HttpServletRequest request, HttpServletResponse response)
{
...
// ์ฑ๊ณต์ฒ๋ฆฌ ...
// ์ธ์
์ฒ๋ฆฌ ...
retrun "redirect:" + redirectURL;
}
- ๊ทธ ์ดํ return;
- ์ธ์ฆ ์ฌ์ฉ์์ ๊ฒฝ์ฐ : finally๊น์ง ์ํํ์ง๋ง
- ๋ฏธ์ธ์ฆ ์ฌ์ฉ์์ ๊ฒฝ์ฐ return ํด ์ค์ผ๋ก์จ ๋ค์์ผ๋ก ์งํ๋์ง ์๊ณ ๋.
ํํฐ ๋ฑ๋ก
@Configuration
public class WebConfig {
@Bean
public FilterRegistrationBean logFilter()
{
FilterRegistrationBean<Filter> filterFilterRegistrationBean = new FilterRegistrationBean<>();
filterFilterRegistrationBean.setFilter(new LogFilter());
filterFilterRegistrationBean.setOrder(1);
filterFilterRegistrationBean.addUrlPatterns("/*");
return filterFilterRegistrationBean;
}
@Bean
public FilterRegistrationBean loginCheckFilter()
{
FilterRegistrationBean<Filter> filterFilterRegistrationBean = new FilterRegistrationBean<>();
filterFilterRegistrationBean.setFilter(new LoginCheckFilter());
filterFilterRegistrationBean.setOrder(2);
filterFilterRegistrationBean.addUrlPatterns("/*");
return filterFilterRegistrationBean;
}
}
๐ฉ Flow
HTTP Request โถ๏ธ WAS โถ๏ธ ๋ก๊ทธ๋ฅผ ๋จ๊ธฐ๋ ํํฐ โถ๏ธ ๋ก๊ทธ์ธ ์ฒดํฌ ํํฐ โถ๏ธ ์๋ธ๋ฆฟ โถ๏ธ ์ปจํธ๋กค๋ฌ
์ด๋ ๊ฒ ๊ณตํต ๊ด์ฌ์ฌ๋ฅผ ์๋ธ๋ฆฟ ํํฐ๋ฅผ ์ฌ์ฉํด ํด๊ฒฐํด๋ณด์์ต๋๋ค.
'๐ Backend > MVC Pattern' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
ArgumentResolver ํ์ฉ (0) | 2023.03.24 |
---|---|
์คํ๋ง ์ธํฐ์ ํฐ(Interceptor) (0) | 2023.03.24 |
๋ก๊ทธ์ธ ์ฒ๋ฆฌ - ์ฟ ํค, ์ธ์ (0) | 2023.03.23 |
Bean Validation - ๊ฒ์ฆ ์ด๋ ธํ ์ด์ ์ฌ์ฉ (0) | 2023.03.22 |
์ค๋ฅ ์ฝ๋์ ๋ฉ์์ง ์ฒ๋ฆฌ (0) | 2023.03.21 |
๋ธ๋ก๊ทธ์ ์ ๋ณด
Study Repository
rlaehddnd0422