HTTP 요청 -> WAS -> 필터 -> 서블릿 -> 컨트롤러
HTTP 요청 -> WAS -> 필터1 -> -> 필터2 -> 필터3 -> 서블릿 -> 컨트롤러
Filter -> javax.servlet implements하기
LogFilter.java
public class LogFilter implements Filter{ @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { // ServletRequest -> HttpServletRequest 로 명시적 형변환 해주기 HttpServletRequest httpServletRequest = (HttpServletRequest)request; String requestURI = httpServletRequest.getRequestURI(); System.out.println("requestURI : " + requestURI); chain.doFilter(request, response); //다음 서블릿 요청으로 넘김 System.out.println("responseURI : " + requestURI); } }
public class LoginCheckFilter implements Filter{ //로그인이 필요하지 않은 페이지 url 요청들 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; System.out.println("인증 체크 필터 시작"); // whitelist에 있는 uri는 검증을 하지 않기때문에, // isLoginCheckPath 메서드에서 매칭되지 않는 경우만 가져온다. // 인증체크 로직 시작 if(isLoginCheckPath(requestURI)) { System.out.println("인증 체크 로직 실행 : " + requestURI); HttpSession session = httpRequest.getSession(false); if(session == null || session.getAttribute(SessionConst.LOGIN_MEMBER) == null) { // 로그인 되지 않음 System.out.println("미 인증 사용자 요청"); // 로그인으로 redirect // 사용자가 원래 가려고 했던 URI를 파라미터 값으로 기억했다가 로그인 후, //이 페이지로 이동 httpResponse.sendRedirect("/login?redirectURL=" + requestURI); // 미인증 사용자는 다음으로 진행하지 않고 끝낸다. return; } } // 로그인이 되어있다면 다음 단계로 넘어간다. chain.doFilter(request, response); } /* * 화이트 리스트의 경우 인증 체크 x * simpleMatch : 파라미터 문자열이 특정 패턴에 매칭되는지를 검사함. */ private boolean isLoginCheckPath(String requestURI) { return !PatternMatchUtils.simpleMatch(whitelist, requestURI); // 매칭이 되지 않을 때 검증을 해야하기 때문에 부정해준다. }
사용자가 원래 요청했던 URI를 파라미터로 저장했다가, 로그인 후 페이지 이동
컨트롤러 수정하기 -> LoginController.java
@PostMapping("/login") // 세션에 담아주기 public String loginv3(@ModelAttribute LoginForm form, Model model, RedirectAttributes redirectAttributes , HttpServletRequest request, @RequestParam(defaultValue = "/")String redirectURL ) { // 넘어온 파라미터 값이 없으면 "/" 여기로 이동하겠다. Member loginMember = loginService.login(form.getLoginId(), form.getPassword()); System.out.println(loginMember); if( loginMember == null) { // 로그인실패 model.addAttribute("msg", "로그인실패"); return "login/loginForm"; } // 로그인 성공 HttpSession session = request.getSession(); //세션에 로그인 회원정보 보관 session.setAttribute(SessionConst.LOGIN_MEMBER, loginMember); redirectAttributes.addFlashAttribute("msg","로그인 성공"); return "redirect:" + redirectURL; }
-> @Controller, @Service, @Repository는 스프링 컨테이너에 빈으로 등록되면서, 파일 안에 있는 메서드들도 알아서 등록이 되었지만, @Component 어노테이션을 사용하여 컨테이너에 등록한다면, 각각의 메서드들도 @Bean 이라는 어노테이션으로 등록을 해줘야 하는데, 스프링 부트에서 제공하는 @PostConstruct 어노테이션은 메서드까지 Bean으로 등록되는 로직까지 포함되어 있다.
@Component public class WebConfig implements WebMvcConfigurer{ @Bean public FilterRegistrationBean<Filter> logFilter() { FilterRegistrationBean<Filter> filterRegistrationBean = new FilterRegistrationBean<Filter>(); filterRegistrationBean.setFilter(new LogFilter()); // LogFilter등록 filterRegistrationBean.setOrder(1); // 먼저 적용할 필터 순서 filterRegistrationBean.addUrlPatterns("/*"); //모든 url 다 적용 -> 모든 요청에 다 필터 적용 return filterRegistrationBean; } }
@Bean public FilterRegistrationBean<Filter> loginCheckFilter() { FilterRegistrationBean<Filter> filterRegistrationBean = new FilterRegistrationBean<Filter>(); filterRegistrationBean.setFilter(new LoginCheckFilter()); // LoginCheckFilter등록 filterRegistrationBean.setOrder(2); // 먼저 등록할 필터 순서 filterRegistrationBean.addUrlPatterns("/*"); //모든 url 다 적용 -> 모든 요청에 다 필터 적용 return filterRegistrationBean; }