프로그래밍/JSP

알기 쉬운 JSP 필터 순서 설정하는 방법에 대해 알아보자

byungmin 2020. 7. 29. 11:24

필터 체인(Filter Chain)

웹어플리케이션에는 여러개의 필터를 지정할 수 있는데, 이 때 필터가 순서대로 넘어오지않고 아무렇게나 넘어오게 되면 오류가 발생할 수 있다. 그래서 순서를 가지고 여러개의 필터가 사슬처럼 묶여있는 것을 필터 체인이라고 한다.

 

1. 필터를 여러개 등록하는 방법

web.xml에 <filter>태그를 통해 필터를 등록해준다.

<filter>
     <filter-name>LoginFilter</filter-name>
     <filter-class>test.filter.LoginFilter</filter-class>
</filter>

<filter>
     <filter-name>AdminFilter</filter-name>
     <filter-class>test.filter.AdminFilter</filter-class>
</filter>

 

2. 필터 순서를 지정해주는 방법

필터가 여러개 있다면 순서대로 필터가 넘어올 수 있도록 해야 한다.

이 때 <filter-mapping> 태그를 통해서 순서를 지정해 줄 수 있다.

<filer-mapping>
    <filter-name>LoginFilter</filter-name>
    <url-pattern>/user/*</url-pattern>
</filer-mapping>
 
 
<filer-mapping>
    <filter-name>AdminFilter</filter-name>
    <url-pattern>/admin/*</url-pattern>
</filer-mapping>
 

 

3. @WebFilter 어노테이션을 통해 순서를 지정해주는 방법

Users[Admin] 페이지에 접근하려고 한다.

Users페이지에 접근하기 위해 필터를 두 개 생성하려고 한다.

1. user필터를 통해 로그인 되어있는지 확인하고 

2. admin필터를 통해 관리자로 로그인 되어있는지 확인하려고 한다.

 

하지만 순서대로 필터가 실행되지 않고 2번부터 실행된다면 로그인이 되어있지 않은 상태에서 admin에 접근하려하기 때문에 user필터에서 실행되는 메소드를 실행할 수 없게 된다. 

 

1) User 필터를 먼저 생성해준다.

/**
 * /user/* 로 시작하는 요청이 올 경우 로그인체크 필터가 해당 요청을 필터링한다. 
 */
@WebFilter(urlPatterns = {"/user/*", "/admin/*"})
public class LoginCheckFilter implements Filter {

	public void destroy() {
	}
	
	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
		System.out.println("LoginCheckFilter...");
		// 세션에 저장되어 있는 loginUser를 꺼낸다.
		// 만약 저장되어 있는 loginUser가 없다면 "로그인 해야 이용할 수 있어요"를 보여주고
		HttpServletRequest req = (HttpServletRequest)request;
		HttpSession session = req.getSession();
		UserVO loginUser = (UserVO)session.getAttribute("loginUser");
		
		if(loginUser == null) {
			String msg = "로그인 해야 이용할 수 있어요.";
			String loc = req.getContextPath()+"/signin.do"; // 절대 경로로 써줘야 한다.
			String viewpage = CommonUtil.addMsgLoc(req, msg, loc);
			
			// this.setredirect 없으니까 disp 객체 생성해서 forword로 보내준다.
			RequestDispatcher disp
			= req.getRequestDispatcher(viewpage);
			disp.forward(req, response);
			
			return;
		}
		// 그렇지 않으면 다음 필터로 넘긴다.
		
		chain.doFilter(request, response);
	}

	/**
	 * @see Filter#init(FilterConfig)
	 */
	public void init(FilterConfig fConfig) throws ServletException {
		// TODO Auto-generated method stub
	}

}

 

2) admin 필터를 먼저 생성해주고 User필터 클래스를 상속받는다.

3) 로그인을 체크하는 로직에 super.doFilter 메소드를 사용하여 User필터로 넘어가도록 해준다.

/**
 * 관리자 여부를 체크하는 필터
 */
@WebFilter("/admin/*")
public class AdminCheckFilter extends LoginCheckFilter {


	public void destroy() {
		// TODO Auto-generated method stub
	}

	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
		System.out.println("AdminCheckFilter...");
		
		HttpServletRequest req = (HttpServletRequest)request;
		HttpSession ses = req.getSession();
		
		UserVO loginUser = (UserVO)ses.getAttribute("loginUser");
		
		RequestDispatcher disp = null;
		
		if(loginUser == null) {
			
			super.doFilter(request, response, chain);
			
			return;
			
		} else {
			
			if(loginUser.getUserid().equals("admin")) {
				
			} else {
				System.out.println("cc");
				String msg = "관리자만 이용할 수 있어요.";
				String loc = req.getContextPath()+"/index.do"; // 절대 경로로 써줘야 한다.
				String viewpage = CommonUtil.addMsgLoc(req, msg, loc);
				
				// this.setredirect 없으니까 disp 객체 생성해서 forword로 보내준다.
				
				disp = req.getRequestDispatcher(viewpage);
				disp.forward(req, response);
				
				return;
			}

		}
		
				
		
		chain.doFilter(request, response);
	}

	public void init(FilterConfig fConfig) throws ServletException {
		// TODO Auto-generated method stub
	}

}