요청 서블릿 수행 전 작업을 필터를 사용해 처리 가능
서블릿과 독립적인 클래스로 존재
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() { }
}
객체들이 정해진 순서에 의해 연결되어 있는 것
컨테이너에 등록해야함
<filter>
<filter-name> 필터의 이름 </filter-name>
<fiter-class> 필터 클래스 이름 </filter-class>
<init-param>
<param-name> 초기화 파라미터 이름 </param-name>
<param-value> 초기화 파라미터 값 </param-value>
</init-param>
</filter>
필터가 어떤 서블릿에 적용되는 지 지정하는 것
<filter-mapping>
<filter-name> 필터의 이름 </filter-name>
<url-pattern> 매핑 이름 </url-pattern>
</filter-mapping>
필터의 실행 순서는 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);
}
}
web.xml 문서 사용하지 않고 필터 등록, 매핑
필터 객체가 자동으로 생성되어 컨테이너에 등록됨.
애너테이션 사용 시 필터 매핑은 필터 클래스 내에서 이뤄지므로 필터의 이름이 반드시 필요하지 않음. -> 필터 이름 생략 가능
@WebFilter(filterName="필터 이름" 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")
@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);
}
}
@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);
}
}
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] -- 응답 필터 부분");
}
}
<!-- 리스너 객체는 웹서버 중지시 소멸 -->
<listener>
<listener-class> 클래스 이름 </listener-class>
</listener>
@Weblistener
public class Test implements HttpSessionListener { }
<구현>
ServletContext 객체의 초기화, 소멸에 관련된 리스너
객체의 속성에 관련되는 리스너
/* 어노테이션 사용으로 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 객체의 초기화와 소멸 관련된 리스너
객체 속성에 관련된 리스너
세션의 초기화와 소멸에 관련된 리스너
구현한 객체가 세션 객체에 바인딩 되거나 언바인딩될 때 처리할 수 있도록 하는 리스너
로그인 폼 && 접속자 수 나타내기 예시
<%@ 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");
}
}