서블릿 9장

Recursion_Error·2023년 6월 1일
0

필터 Filter

요청 서블릿 수행 전 작업을 필터를 사용해 처리 가능

서블릿과 독립적인 클래스로 존재

public class MyFilter implements Filter {
	public void init(FilterConfig config) throws ServletException {	}
	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
				//요청 필터
            	chain.doFilter(request, response);
            	//응답 필터 }
	public void destroy() {	}

}
  • init() 메서드
    필터 객체가 생성될 때 단 한번 호출. 초기화하는 목적으로 사용
  • destroy() 메서드
    필터 객체가 소멸할 때 단 한번 수행.
  • doFilter() 메서드
    요청 필드와 응답 필터 중 하나만 구현하는 경우 doFilter()메서드는 생략할 수 없음.

필터 체이닝 Filter Chaining

객체들이 정해진 순서에 의해 연결되어 있는 것

필터 등록

 컨테이너에 등록해야함

필터 등록 - web.xml

<filter>
	<filter-name> 필터의 이름 </filter-name>
    <fiter-class> 필터 클래스 이름 </filter-class>
    <init-param>
    	<param-name> 초기화 파라미터 이름 </param-name>
        <param-value> 초기화 파라미터 값 </param-value>
    </init-param>
</filter>
  • filter-name : 필터 이름 지정.
    필터들은 유일한 값을 가져야 함 (생략 x)
  • filter-class : 패키지를 포함하는 필터 클래스 이름 (생략 x)
  • init-param : 초기화 파라미터 지정 (생략 0)
  • param-name : init-param 지정 시 생략 x
  • param-value : init-param 지정 시 생략 x
filter mapping
필터가 어떤 서블릿에 적용되는 지 지정하는 것
<filter-mapping>
	<filter-name> 필터의 이름 </filter-name>
    <url-pattern> 매핑 이름 </url-pattern>
</filter-mapping>
  • filter-name : 매핑하고자 하는 필터의 이름 지정
    fliter의 filter-name와 같은 값 지정
  • url-pattern : 패턴을 사용해 매핑하고자 하는 서블릿 지정
    패턴에 만족하는 모든 서블릿에 필터가 적용됨.

필터의 실행 순서는 filter-mapping 태그의 순서로 결정됨.
따라서, 순서 변경시 태그 순서를 변경해야함.


/*
*	class name: EncodeFilter
*/

public class EncodeFilter implements Filter {
	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
    	request.setCharacterEncoding("UTF-8");
        chain.doFilter(request, response);
    }
}
<!-- 
	class name: Encoding
	모든 서블릿에 적용될 수 있도록 한다.
-->

<filter>
	<filter-name> Encoding </filter-name>
    <filter-class> Chapter09.EncdingFilter </filter-class>
</filter>

<filter-mapping>
	<filter-name> Encoding </filter-name>
    <url-pattern> /* </url-pattern>
</filter-mapping>

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
	<meta charset="UTF-8">  
</head>
<body>
  <form name="inputForm" method="post" action="InputProc">
    이름: <input type=text name="name" size=20><br>
    부서: <input type=text name="depart" size=20><br>
    <input type="submit" value="이름">
  </form>
  </body>
</html>

@WebServlet("/InputProc")
public class InputProc extends HttpServlet {
	private static final long serialVersionUID = 1L;
    
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    
    	//request.setCharacterEncoding("UTF-8");
        //위 코드를 필터로 보내버림. 
    
    	response.setContentType("text/html;charset=utf-8");
        PrintWriter out = response.getWriter();
        
        String name = request.getParameter("name");
        String depart = request.getParameter("depart");
        
        out.println("이름: " + name + "<br>");
        out.println("부서: " + depart);
    }
}    
초기화 파라미터를 이용한 필터링
필터 클래스의 소스 코드를 수정하지 않고 필터의 내용을 변경할 수 있음

초기화 파라미터 추출은 init()메서드의 인자로 지정한 FilterConfig 객체 사용 -> getInitParameter() 메서드 제공


<filter>
  	<filter-name> Encoding </filter-name>
  
  <!-- 추가 부분 -->
  <!-- 초기화 파라미터 값으로 UTF-8 지정 -->
  		<init-param>
         	<param-name> Encode </param-name>
          	<param-value> UTF-8 </param-value>
        </init-param>
  
  	</filter-class> Chapter09.EncodingFilter </filter-class>
</filter>

<filter-mapping>
  	<filter-name> Encoding </filter-name>
  	<url-pattern> /* </url-pattern>
</filter-mapping>

/*
*	class name: EncodeFilter
*/

public class EncodeFilter implements Filter {

	/* 
    * 추가 부분
    * UTF-8 대신 Encode 지정
    */
	String charEnc;
    public void init(FilterConfig config) {
    	charEnc = config.getInitPrameter("Encode");
    }
	
	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
    	request.setCharacterEncoding("charEnc);
        chain.doFilter(request, response);
    }
}

필터 등록 - @WebFilter 애너테이션

web.xml 문서 사용하지 않고 필터 등록, 매핑

필터 객체가 자동으로 생성되어 컨테이너에 등록됨.
애너테이션 사용 시 필터 매핑은 필터 클래스 내에서 이뤄지므로 필터의 이름이 반드시 필요하지 않음. -> 필터 이름 생략 가능

@WebFilter(filterName="필터 이름" urlPatterns={"URL 패턴"})
  • filter-Name : 필터 클래스의 필터 이름
  • urlPatterns : 필터와 매핑이 이뤄지는 대상
URL 패턴을 직접 지정하는 방법
@WebFilter("/URL 패턴")

@WebFilter("/first")
@WebFilter(value="/first")
@WebFilter(urlPatterns="/first")

/* 하나 이상의 필터를 지정할 때 */
/* value 혹은 urlPatterns 속성 사용 */
@WebFilter(value={"/first", "/second"})
@WebFilter(urlPatterns={"/first", "/second"})
와일드 카드를 지정하는 방법
@WebFilter("/와일드카드 문자")

/* 모든 서블릿에 사용 */
@WebFilter("/*")
/* 모든 jsp 문서에 사용 */
/* jsp 확장자를 지정할 경우 '/'는 사용하지 않음 */
@WebFilter("*.jsp")
Servlet 이름을 지정하는 방법
@WebFilter(servletName="서블릿이름")
/* EncodeFilter2 필터는 모든 서블릿에 적용 */

@WebFilter("/*")
public class EncodeFilter2 implements Filter {
	
    public void doFilter (ServletRequest request, ServletResponse respones, FilterChain chain) throws IOException, ServletException {
    	request.setCharacterEncoding("utf-8");
        chain.doFilter(request, response);
    }
}
initParams 속성으로 @WebInitParam 애너테이션을 지정해 초기화 파라미터 생성
@WebFilter (
	urlpatterns = {"/URL 패턴"},
    initParams = @WebInitParam (name = "파라미터", value = "값")
/* EncodeFilter2 초기화 파라미터로 수정*/

@WebFilter(
	/* 모든 서블릿 적용 */
	urlPatterns="/*",
    
    /* 초기화 파라미터 Encode 지정 */
	initParams = @WebInitParam(name="Encode", value="UTF-8")
)

public class EncodeFilter2 implements Filter {
	
    String charEnc;
    
    public void init(FilterConfig config) {
    	charEnc = config.getInitPrameter("Encode");
    }
    
    public void doFilter (ServletRequest request, ServletResponse respones, FilterChain chain) throws IOException, ServletException {
    	request.setCharacterEncoding("charEnc);
        chain.doFilter(request, response);
    }
}

@WebFilter에서의 필터 실행 순서 지정

web.xml == <filter-mapping> 사용
@WebFilter == filterName 사용
@WebFilter(filterName = "filter1")
public void AnnoFilter1 implements Filter {
	
    public void doFilter (ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
    	System.out.println("[AnnoFilter1] -- 요청 필터 부분");
        chain.doFilter(request, response);
        System.out.println("[AnnoFilter1] -- 응답 필터 부분");
    }
}

리스너


리스너 객체 등록 방법 - web.xml

  • listener 태그 이용
<!-- 리스너 객체는 웹서버 중지시 소멸 -->
<listener>
  <listener-class> 클래스 이름 </listener-class>
</listener>

리스너 객체 등록 방법 - @WebListener

@Weblistener
public class Test implements HttpSessionListener { }

<구현>

ServletContext 객체

ServletContext 객체 리스너

ServletContext 객체의 초기화, 소멸에 관련된 리스너

ServletContextAttributeListener 객체 리스너

객체의 속성에 관련되는 리스너

/* 어노테이션 사용으로 web.xml 문서에 등록할 필요 없음. */
@WebListener
public class TestServletContextListener implements ServletContextListener {
	
    public TestServletContextListener() {
    	System.out.println("TestServletContext 서블릿 생성됨.");
    }
    
    public void contextDestroyed(ServletContextEvent sce) {
    	System.out.println("TestServletContext 서블릿 종료됨.");
    }
    
    public void contextInitialized(ServletContextEvent sce) {
    	System.out.println("TestServletContext 서블릿 초기화됨.");
    }
}

HttpServletRequest 객체 리스너

ServletRequestListener 리스너

HttpServletRequest 객체의 초기화와 소멸 관련된 리스너

ServletRequestAttributeListener 리스너

 객체 속성에 관련된 리스너

HttpSession 객체 리스너

HttpSessionListener 리스너

세션의 초기화와 소멸에 관련된 리스너

HttpSessionAttributeListener 리스너

HttpSessionBindingListener 리스너

구현한 객체가 세션 객체에 바인딩 되거나 언바인딩될 때 처리할 수 있도록 하는 리스너

로그인 폼 && 접속자 수 나타내기 예시

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
</head>
<body>
	<form name = "myform" method="post" action="Login">
		아이디 <input type="text" name="userId" size=20><br>
		패스워드 <input type="password" name="userPw" size=20><br>
		
		<input type="submit" value = "로그인"> 
	</form>
</body>
</html>

//세션에 바인딩/언바인딩 사용 -> BindingListener
@WebListener
public class TestSessionListener implements HttpSessionBindingListener{

	private String userId;
	private String userPw;
	static int persons = 0;
	
	/* 클래스는 반드시 기본 생성자로 선언한다. */
	public TestSessionListener() {}
	
	public TestSessionListener(String userId, String userPw) {
		this.userId = userId;
		this.userPw = userPw;
	}
	
	/* getter 메서드 : 멤버변수의 값을 추출하기 위해 */
	public String getUserId() {
		return userId;
	}
	
	public String getUserPw() {
		return userPw;
	}
	
    /* 성공시 */
	public void valueBound(HttpSessionBindingEvent event) {
		++persons;
	}
	
    /* 실패시 */
	public void valueUnbound(HttpSessionBindingEvent evnet) {
		persons--;
	}
}
@WebServlet("/Login")
public class LoginProc extends HttpServlet {
	private static final long serialVersionUID = 1L;

	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		doPost(request, response);
	}

	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		request.setCharacterEncoding("utf-8");
		
		response.setContentType("text/html;charset=utf-8");
		PrintWriter out = response.getWriter();
		
        /* 데베에서 추출한 id, pw */
		String realId = "Jo";
		String realPw = "Jopass";
		
        /* 사용자가 입력한 id, pw */
		String userId = request.getParameter("userId");
		String userPw = request.getParameter("userPw");
		
		if(userId.equals(realId) && userPw.equals(realPw)) {
        
        	/* 세션 생성 (사용자의 상태 유지를 위함) */
			HttpSession session = request.getSession();
			
            /* TestSessionListener에 HttpSessionBindingListener 구현함 */
            /* 세션 속성으로 바인딩 */
			TestSessionListener login = new TestSessionListener(userId, userPw);
			session.setAttribute("login", login);
			
			out.println("<script type='text/javascript'>");
			out.println("setInterval('history.go(0)', 5000)");
			
			out.println("</script>");
			
			out.println(login.getUserId() + "님. 로그인되었습니다.<br>");
			out.println("접속자 수: "+ TestSessionListener.persons +"<br>");
			out.println("<a href='logout'>로그아웃</a>");
			
		} else {
			response.sendRedirect("LoginForm.jsp");
		}
	}
}
@WebServlet("/Logout")
public class LogoutProc extends HttpServlet {
	private static final long serialVersionUID = 1L;

	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    	/* 위의 session을 불러옴 */
		HttpSession session = request.getSession();
        
        /* 세션 종료 */
        /* 종료로 인해 valueUnbound 호출 */
		session.invalidate();
		response.sendRedirect("LoginForm.jsp");
	}
}
profile
무한으로 돌리는 . . .

0개의 댓글