์คํ๋ง MVC 2ํธ์ ๊ฐ์ ๋ด์ฉ์ ์ ๋ฆฌํ ํฌ์คํ ์ ๋๋ค.
๊ณตํต ๊ด์ฌ ์ฌํญ
'๋ก๊ทธ์ธ ์ฒ๋ฆฌ(1) - ์ฟ ํค, ์ธ์ '์์ ์ ์ํ ์๊ตฌ์ฌํญ์ ๋ฐ๋ฅด๋ฉด ๋ก๊ทธ์ธ์ ํ ์ฌ์ฉ์๋ง ์ํ ๊ด๋ฆฌ ํ์ด์ง์ ๋ค์ด๊ฐ ์ ์์ด์ผ ํ๋ค.
ํ์ง๋ง ์ํ ๊ด๋ฆฌ ํ์ด์ง์ URL์ ์ง์ ํธ์ถํ๋ฉด ๋ก๊ทธ์ธ์ ํ์ง ์์ ์ฌ์ฉ์๋ ์ ์ํ ์ ์๋ค๋ ๋ฌธ์ ์ ์ด ์กด์ฌํ๋ค.
์ํ ๊ด๋ฆฌ ์ปจํธ๋กค๋ฌ์์ ๋ก๊ทธ์ธ ์ฌ๋ถ๋ฅผ ์ฒดํฌํ๋ ๋ก์ง์ ์ผ์ผ์ด ์์ฑํ ์๋ ์์ง๋ง, ๋ฑ๋ก/์์ /์ญ์ /์กฐํ ๋ฑ ๋ชจ๋ ์ปจํธ๋กค๋ฌ ๋ก์ง์ ๊ณตํต์ผ๋ก ๋ก๊ทธ์ธ ์ฌ๋ถ๋ฅผ ํ์ธํด์ผ ํ๋ฉฐ ๋ก๊ทธ์ธ๊ณผ ๊ด๋ จ๋ ๋ก์ง์ด ๋ณ๊ฒฝ๋ ๋๋ง๋ค ์์ฑํ ๋ชจ๋ ๋ก์ง์ ๋ค ์์ ํด์ผ ํ๋ ๊ฐ๋ฅ์ฑ์ด ์กด์ฌํ๋ค.
์ด๋ ๊ฒ ์ ํ๋ฆฌ์ผ์ด์ ์ฌ๋ฌ ๋ก์ง์์ ๊ณตํต์ผ๋ก ๊ด์ฌ์ด ์๋ ๋ถ๋ถ์ '๊ณตํต ๊ด์ฌ์ฌ'๋ผ๊ณ ํ๋๋ฐ, ํด๋น ์ํฉ์์์ ๊ณตํต ๊ด์ฌ์ฌ๋ '์ธ์ฆ'์ด๋ค.
์ด๋ฌํ ๊ณตํต ๊ด์ฌ์ฌ๋ ์คํ๋ง์ AOP๋ก๋ ํด๊ฒฐํ ์ ์์ง๋ง, ์น๊ณผ ๊ด๋ จ๋ ๊ณตํต ๊ด์ฌ์ฌ๋ ์๋ธ๋ฆฟ ํํฐ ๋๋ ์คํ๋ง ์ธํฐ์ ํฐ๋ฅผ ์ฌ์ฉํ๋ ๊ฒ์ด ์ข๋ค. ์น ๊ด๋ จ ๊ณตํต ๊ด์ฌ์ฌ๋ฅผ ์ฒ๋ฆฌํ ๋ ๋๊ฐ HTTP์ ํค๋๋ URL์ ์ ๋ณด๊ฐ ํ์ํ๋ฐ, ์๋ธ๋ฆฟ ํํฐ์ ์คํ๋ง ์ธํฐ์ ํฐ๋ HttpServletRequest๋ฅผ ์ ๊ณตํ๊ธฐ ๋๋ฌธ์ด๋ค.
์๋ธ๋ฆฟ ํํฐ
ํํฐ๋ ์๋ธ๋ฆฟ์ด ์ง์ํ๋ ์๋ฌธ์ฅ์ผ๋ก ์๋์ ๊ฐ์ ํน์ฑ์ ๊ฐ์ง๋ค.
1. ํํฐ ํ๋ฆ
HTTP ์์ฒญ โ WAS โ ํํฐ โ ์๋ธ๋ฆฟ โ ์ปจํธ๋กค๋ฌ
2. ํํฐ ์ ํ
๋ก๊ทธ์ธ ์ฌ์ฉ์: HTTP ์์ฒญ โ WAS โ ํํฐ โ ์๋ธ๋ฆฟ โ ์ปจํธ๋กค๋ฌ
๋น ๋ก๊ทธ์ธ ์ฌ์ฉ์: HTTP ์์ฒญ โ WAS โ ํํฐ(์ ์ ํ์ง ์์ ์์ฒญ์ด๋ผ ํ๋จ, ์๋ธ๋ฆฟ ํธ์ถ X)
3. ํํฐ ์ฒด์ธ
HTTP ์์ฒญ โ 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() {}
}
์๋ธ๋ฆฟ ํํฐ - ์ธ์ฆ ์ฒดํฌ
ํํฐ๋ฅผ ๊ฐ๋ฐํ ๋๋ Filter ์ธํฐํ์ด์ค๋ฅผ ๊ตฌํํ๋ ๋ฐฉ์์ผ๋ก ์งํํ๋ฉด ๋๋ค.
1. ํํฐ ๊ฐ๋ฐ
@Slf4j
public class LoginCheckFilter implements Filter {
private static final String[] whitelist = {"/", "/members/add", "/login", "/logout", "/css/*"}; //์ธ์ฆ ๋์์์ ์ ์ธํ ๊ฒฝ๋ก
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
HttpServletRequest httpRequest = (HttpServletRequest) request;
String requestURI = httpRequest.getRequestURI();
HttpServletResponse httpResponse = (HttpServletResponse) response;
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 (Exception e) {
throw e;
} finally {
log.info("์ธ์ฆ ์ฒดํฌ ํํฐ ์ข
๋ฃ {}", requestURI);
}
}
//ํ์ดํธ ๋ฆฌ์คํธ ์ฌ๋ถ ๊ตฌ๋ถ
private boolean isLoginCheckPath(String requestURI) {
return !PatternMatchUtils.simpleMatch(whitelist, requestURI);
}
}
2. ํํฐ ๋ฑ๋ก - FilterRegistrationBean
์ด์ฉ
@Configuration
public class WebConfig {
@Bean
public FilterRegistrationBean logFilter() {
...
}
@Bean
public FilterRegistrationBean loginCheckFilter() {
FilterRegistrationBean<Filter> filterRegistrationBean = new FilterRegistrationBean<>();
filterRegistrationBean.setFilter(new LoginCheckFilter()); //๋ก๊ทธ์ธ ํํฐ ๋ฑ๋ก
filterRegistrationBean.setOrder(2); //๋ ๋ฒ์งธ ์์
filterRegistrationBean.addUrlPatterns("/*"); //๋ชจ๋ ์์ฒญ์ ๋ก๊ทธ์ธ ํํฐ ์ ์ฉ
return filterRegistrationBean;
}
}
์คํ๋ง ์ธํฐ์ ํฐ
์คํ๋ง ์ธํฐ์ ํฐ๋ ์๋ธ๋ฆฟ ํํฐ์ ๊ฐ์ด ์น๊ณผ ๊ด๋ จ๋ ๊ณตํต ๊ด์ฌ ์ฌํญ์ ํด๊ฒฐํ ์ ์๋ ๊ธฐ์ ์ด๋ค.
์ฐจ์ด์ ์ด ์๋ค๋ฉด ์๋ธ๋ฆฟ ํํฐ๋ ์๋ธ๋ฆฟ์ด ์ ๊ณตํ๋ ๊ธฐ์ ์ด์ง๋ง, ์คํ๋ง ์ธํฐ์ ํฐ๋ ์คํ๋ง MVC๊ฐ ์ ๊ณตํ๋ ๊ธฐ์ ์ด๋ผ๋ ์ , ์ ์ฉ๋๋ ์์์ ๋ฒ์ ๋ฐ ์ฌ์ฉ๋ฐฉ๋ฒ์ด ๋ค๋ฅด๋ค๋ ์ ์ด ์๋ค.
1. ์คํ๋ง ์ธํฐ์
ํฐ ํ๋ฆ
HTTP ์์ฒญ โ WAS โ ํํฐ โ ์๋ธ๋ฆฟ โ ์คํ๋ง ์ธํฐ์
ํฐ โ ์ปจํธ๋กค๋ฌ
2. ์คํ๋ง ์ธํฐ์
ํฐ ์ ํ
๋ก๊ทธ์ธ ์ฌ์ฉ์: HTTP ์์ฒญ โ WAS โ ํํฐ โ ์๋ธ๋ฆฟ โ ์คํ๋ง ์ธํฐ์
ํฐ โ ์ปจํธ๋กค๋ฌ
๋น ๋ก๊ทธ์ธ ์ฌ์ฉ์: HTTP ์์ฒญ โ WAS โ ํํฐ โ ์๋ธ๋ฆฟ โ ์คํ๋ง ์ธํฐ์
ํฐ(์ ์ ํ์ง ์์ ์์ฒญ์ด๋ผ ํ๋จ, ์ปจํธ๋กค๋ฌ ํธ์ถ X)
3. ์คํ๋ง ์ธํฐ์
ํฐ ์ฒด์ธ
HTTP ์์ฒญ โ WAS โ ํํฐ โ ์๋ธ๋ฆฟ โ ์ธํฐ์
ํฐ1 โ ์ธํฐ์
ํฐ2 โ ์ธํฐ์
ํฐ3 โ ์ปจํธ๋กค๋ฌ
public interface HandlerInterceptor { //์คํ๋ง ์ธํฐ์
ํฐ ์ธํฐํ์ด์ค
//์ปจํธ๋กค๋ฌ ํธ์ถ ์ ํธ์ถ
default boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {}
//์ปจํธ๋กค๋ฌ(ํธ๋ค๋ฌ ์ด๋ํฐ) ํธ์ถ ํ ํธ์ถ
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 {}
}
์ ์์ ์ธ ํ๋ฆ์ ์ปจํธ๋กค๋ฌ ํธ์ถ ์ preHandle()
, ์ปจํธ๋กค๋ฌ ํธ์ถ ํ postHandle()
, ์์ฒญ ์ดํ afterCompletion()
์ด ํธ์ถ๋๋ ๊ฒ์ด ๋ง์ง๋ง ์ปจํธ๋กค๋ฌ์์ ์์ธ๊ฐ ๋ฐ์ํ ๊ฒฝ์ฐ์ ํ๋ฆ์ ๋ค์๊ณผ ๊ฐ๋ค.
preHandle()
์ด ์ปจํธ๋กค๋ฌ ํธ์ถ ์ ํธ์ถ๋๊ณ , ์ปจํธ๋กค๋ฌ์์ ์์ธ๊ฐ ๋ฐ์ํ๋ฉด postHandle()
์ ํธ์ถ๋์ง ์๋๋ค. ํ์ง๋ง afterCompletion()
์ ์์ธ ๋ฐ์ ์ฌ๋ถ์ ๊ด๊ณ์์ด ํญ์ ํธ์ถ๋๋ค. ์์ธ๊ฐ ๋ฐ์ํ ๊ฒฝ์ฐ์๋ @Nullable Exception ex
ํ๋ผ๋ฏธํฐ๋ฅผ ํตํด ์์ธ ์ข
๋ฅ๋ฅผ ๋ก๊ทธ๋ก ์ถ๋ ฅํ ์๋ ์๋ค.
์๋ธ๋ฆฟ ํํฐ์ ๊ฒฝ์ฐ ๋จ์ํ๊ฒ doFilter()
ํ๋๋ง ์ ๊ณต๋์ง๋ง, ์ธํฐ์
ํฐ๋ ์ปจํธ๋กค๋ฌ ํธ์ถ ์ , ํ, ์์ฒญ ์๋ฃ ์ดํ์ ๊ฐ์ด ๋จ๊ณ์ ์ผ๋ก ์ธ๋ถํ ๋์ด์์ ๋ฟ ์๋๋ผ ServletRequest, ServletResponse๋ง ์ ๊ณต๋๋ ์๋ธ๋ฆฟ ํํฐ์ ๋ฌ๋ฆฌ ์ธํฐ์
ํฐ๋ ์ด๋ค ์ปจํธ๋กค๋ฌ(ํธ๋ค๋ฌ)๊ฐ ํธ์ถ๋๋์ง์ ๋ํ ํธ์ถ ์ ๋ณด์ ModelAndView ์ ๋ณด๋ ๋ฐ์๋ณผ ์ ์์ด ๋์ฑ ์ ๊ตํ๊ณ ๋ค์ํ ๊ธฐ๋ฅ์ ์ง์ํ๋ค๋ ์ฅ์ ์ด ์๋ค.
์คํ๋ง ์ธํฐ์ ํฐ - ์ธ์ฆ ์ฒดํฌ
1. ์ธํฐ์ ํฐ ๊ฐ๋ฐ
์ธ์ฆ์ ์ปจํธ๋กค๋ฌ ํธ์ถ ์ ์๋ง ๊ฒ์ฆํ๋ฉด ๋๋ฏ๋ก, preHandle()
๋ง ๊ตฌํํ๋ฉด ๋๋ค.
@Slf4j
public class LoginCheckInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
String requestURI = request.getRequestURI();
log.info("์ธ์ฆ ์ฒดํฌ ์ธํฐ์
ํฐ ์คํ {}", request);
HttpSession session = request.getSession();
if (session == null || session.getAttribute(SessionConst.LOGIN_MEMBER) == null) {
log.info("๋ฏธ์ธ์ฆ ์ฌ์ฉ์ ์์ฒญ");
//๋ก๊ทธ์ธ์ผ๋ก ๋ฆฌ๋ค์ด๋ ํธ
response.sendRedirect("/login?redirectURL=" + requestURI);
return false;
}
return true;
}
}
2. ์ธํฐ์
ํฐ ๋ฑ๋ก - WebMvcConfigurer
์ด์ฉ
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new LogInterceptor()) //์ธํฐ์
ํฐ ๋ฑ๋ก
.order(1) //์์ ์ง์
.addPathPatterns("/**") //์ธํฐ์
ํฐ๋ฅผ ์ ์ฉํ URL ํจํด ์ง์
.excludePathPatterns("/css/**", "/*.ico", "/error"); //์ธํฐ์
ํฐ์์ ์ ์ธํ URL ํจํด
registry.addInterceptor(new LoginCheckInterceptor())
.order(2)
.addPathPatterns("/**")
.excludePathPatterns("/", "/members/add", "/login", "/logout", "/css/**", "/*.ico", "/error");
}
}
ArgumentResolver ํ์ฉ
์คํ๋ง MVC ๊ธฐ๋ณธ ๊ธฐ๋ฅ ์ค ์์ฒญ ๋งคํ ํธ๋ค๋ฌ ์ด๋ํฐ ๊ตฌ์กฐ์์ ArgumentResolver๋ฅผ ๋ค๋ฃจ์๋๋ฐ, ํด๋น ๊ธฐ๋ฅ์ ์ฌ์ฉํด์๋ ๋ก๊ทธ์ธ ํ์์ ํธ๋ฆฌํ๊ฒ ์ฐพ์ ์ ์๋ค.
1. ์ปจํธ๋กค๋ฌ
@GetMapping("/")
public String homeLoginArgumentResolver(@Login Member loginMember, Model model) {
//์ธ์
์ ํ์ ๋ฐ์ดํฐ๊ฐ ์์ผ๋ฉด ๋ก๊ทธ์ธ ์ ํ๋ฉด์ผ๋ก ์ด๋
if (loginMember == null) {
return "home";
}
//์ธ์
์ด ์ ์ง๋๋ฉด ๋ก๊ทธ์ธ ํ ํ๋ฉด์ผ๋ก ์ด๋
model.addAttribute("member", loginMember);
return "loginHome";
}
2. @Login ์ ๋ ธํ ์ด์ ์์ฑ
@Target(ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
public @interface Login {
}
3. LoginMemberArgumentResolver ์์ฑ
public class LoginMemberArgumentResolver implements HandlerMethodArgumentResolver {
@Override
public boolean supportsParameter(MethodParameter parameter) {
...
}
@Override
public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {
...
}
}
4. ArgumentResolver ๋ฑ๋ก - WebMvcConfigurer
์ด์ฉ
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Override
public void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers) {
resolvers.add(new LoginMemberArgumentResolver());
}
}
'Language & Framework > Spring' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[์คํ๋ง MVC] API ์์ธ ์ฒ๋ฆฌ (0) | 2023.03.04 |
---|---|
[์คํ๋ง MVC] ์์ธ ์ฒ๋ฆฌ์ ์ค๋ฅ ํ์ด์ง (0) | 2023.03.03 |
[์คํ๋ง MVC] ๋ก๊ทธ์ธ ์ฒ๋ฆฌ(1) - ์ฟ ํค, ์ธ์ (0) | 2023.03.02 |
[์คํ๋ง MVC] ๊ฒ์ฆ(2) - Bean Validation (0) | 2023.02.21 |
[์คํ๋ง MVC] ๊ฒ์ฆ(1) - Validation (0) | 2023.02.12 |