서블릿 속성
세가지 서블릿 API 클래스에 저장되는 객체
setAttribute(String name, Object value): 속성 바인딩하기
getAttribute(String name): 속성 가져오기
removeAttribute(String name): 속성 제거하기
서블릿 스코프
서블릿 API에 바인딩된 속성에 대한 접근 범위
pro10/src/sec01/ex01/SetAttribute.java
package sec01.ex01;
...
@WebServlet("/set")
public class SetAttribute extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/html;charset=utf-8");
PrintWriter out = response.getWriter();
String ctxMesg = "context에 바인딩됩니다.";
String sesMesg = "session에 바인딩됩니다.";
String reqMesg = "request에 바인딩됩니다.";
ServletContext ctx = getServletContext();
HttpSession session = request.getSession();
/* 바인딩 */
ctx.setAttribute("context", ctxMesg);
session.setAttribute("session", sesMesg);
request.setAttribute("request", reqMesg);
out.print("바인딩을 수행합니다.");
}
}
pro10/src/sec01/ex01/GetAttribute.java
package sec01.ex01;
...
@WebServlet("/get")
public class GetAttribute extends HttpServlet{
public void doGet(HttpServletRequest request , HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/html;charset=utf-8");
PrintWriter out = response.getWriter();
ServletContext ctx = getServletContext();
HttpSession sess = request.getSession();
/* 바인딩 값 가져오기 */
String ctxMesg = (String)ctx.getAttribute("context");
String sesMesg = (String)sess.getAttribute("session"); //브라우저마다 다른 세션
String reqMesg = (String)request.getAttribute("request"); //바인딩 요청 '/set'과 다른 새로운 요청
out.print("context값 : " + ctxMesg + "<br>");
out.print("session값 : " + sesMesg + "<br>"); //다른 브라우저로 요청 시 null
out.print("request값 : " + reqMesg + "<br>"); //null
}
}
pro10/src/sec02/ex01/TestServlet1.java
전부 (디렉터리 이름 + 매핑 이름) 일치
선택(요청)한 서블릿 실행
package sec02.ex01;
...
@WebServlet("/first/test")
public class TestServlet1 extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setCharacterEncoding("utf-8");
response.setContentType("text/html;charset=utf-8");
PrintWriter out = response.getWriter();
String context = request.getContextPath();
String url = request.getRequestURL().toString();
String mapping = request.getServletPath();
String uri = request.getRequestURI();
out.println("<html>");
out.println("<head>");
out.println("<title>Test Servlet1</title>");
out.println("</head>");
out.println("<body bgcolor='green'>");
out.println("<b>TestServlet1</b><br>");
out.println("<b>컨텍스트 이름 : "+ context + "</b><br>");
out.println("<b>전체 경로 : "+ url +"<b><br>");
out.println("<b>매핑 이름 : "+mapping+"<b><br>");
out.println("<b>URI : " + uri + "<b>");
out.println("</body>");
out.println("</html>");
out.close();
}
}
pro10/src/sec02/ex01/TestServlet2.java
디렉터리 이름 일치
해당 디렉터리 서블릿 실행
package sec02.ex01;
...
@WebServlet("/first/*")
public class TestServlet2 extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response) throws SevletException, IOException {
request.setCharacterEncoding("utf-8");
response.setContentType("text/html;charset=utf-8");
PrintWriter out = response.getWriter();
String context = request.getContextPath();
String url = request.getRequestURL().toString();
String mapping = request.getServletPath();
String uri = request.getRequestURI();
out.println("<html>");
out.println("<head>");
out.println("<title>Test Servlet2</title>");
out.println("</head>");
out.println("<body bgcolor='yellow'>");
out.println("<b>TestServlet2</b><br>");
out.println("<b>컨텍스트 이름 : "+ context + "</b><br>");
out.println("<b>전체 경로 : "+ url +"<b><br>");
out.println("<b>매핑 이름 : "+mapping+"<b><br>");
out.println("<b>URI : " + uri + "<b>");
out.println("</body>");
out.println("</html>");
out.close();
}
}
pro10/src/sec02/ex01/TestServlet3.java
확장자 일치
확장자명에 맞는 서블릿 실행
package sec02.ex01;
...
@WebServlet("*.do") /* 모든 요청: @WebServlet("/*") */
public class TestServlet2 extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response) throws SevletException, IOException {
request.setCharacterEncoding("utf-8");
response.setContentType("text/html;charset=utf-8");
PrintWriter out = response.getWriter();
String context = request.getContextPath();
String url = request.getRequestURL().toString();
String mapping = request.getServletPath();
String uri = request.getRequestURI();
out.println("<html>");
out.println("<head>");
out.println("<title>Test Servlet2</title>");
out.println("</head>");
out.println("<body bgcolor='red'>");
out.println("<b>TestServlet3</b><br>");
out.println("<b>컨텍스트 이름 : "+ context + "</b><br>");
out.println("<b>전체 경로 : "+ url +"<b><br>");
out.println("<b>매핑 이름 : "+mapping+"<b><br>");
out.println("<b>URI : " + uri + "<b>");
out.println("</body>");
out.println("</html>");
out.close();
}
}
브라우저에서 서블릿으로 요청/응답할 때 미리 관련된 작업을 처리하는 기능
필터 사용 시 모든 요청이 필터를 거침
서블릿에서 요청/응답 필터 기능은 동일한 필터가 수행함
각 서블릿에서 반복적으로 처리해야하는 작업에 사용
ex) 한글 인코딩
요청 필터
사용자 인증 및 권한 검사
요청 시 요청 관련 로그 작업
인코딩
응답 필터
응답 결과에 대한 암호화
서비스 시간 측정
javax.servlet.Filter
컨테이너에서 호출하여 작업 수행
javax.servlet.FilterConfig
javax.servlet.FilterChain
필터를 각 요청에 맞게 적용하기 위해 필터 매핑 필요
Filter 인터페이스 구현 필수
필터 매핑 방법:
pro10/WebContent/login.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>로그인창</title>
</head>
<body>
<form name="frmLogin" method="post" action="login" encType="utf-8">
이름 :<input type="text" name="user_name"><br>
비밀번호:<input type="password" name="user_pw"><br>
<input type="submit" value="로그인">
<input type="reset" value="다시입력">
</form>
</body>
</html>
prro10/src /sec03/ex01/LoginTest.java
package sec03.ex01;
...
@WebServlet("/login")
public class LoginTest extends HttpServlet {
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 user_name = request.getParameter("user_name");
String user_pw = request.getParameter("user_pw");
out.println("<html><body>");
out.println("이름는 " + user_name +"<br>");
out.println("비밀번호는 "+user_pw +"<br>");
out.println("</body></html>");
}
}
필터 생성
1. 패키지 -> Filter 메뉴
2. class name: 필터명(EncoderFilter) 입력
3. Filter mappings: 입력한 필터명 선택
4. Pattern: /*
pro10/src/sec03/ex01/EncoderFilter.java
package sec03.ex01;
...
@WebFilter("/*") //필터 애너테이션
public class EncoderFilter implements Filter {
ServletContext context;
public void init(FilterConfig fConfig) throws ServletException {
System.out.println("utf-8 인코딩............");
context = fConfig.getServletContext();
}
// 실제 필터 기능 구현 메소드
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)throws ServletException, IOException {
System.out.println("doFilter 호출");
request.setCharacterEncoding( "utf-8" ); //인코딩
String context= ((HttpServletRequest)request).getContextPath();
String pathinfo = ((HttpServletRequest)request).getRequestURI();
String realPath = request.getRealPath( pathinfo);
String mesg = " Context 정보:" + context
+ "\n URI 정보 : " + pathinfo
+ "\n 물리적 경로: " + realPath;
System.out.println(mesg);
chain.doFilter( request, response ); //다음 필터로 전달
}
public void destroy() {
System.out.println("destroy 호출");
}
}
pro10/src/sec03/ex01/EncoderFilter.java
package sec03.ex01;
...
@WebFilter("/*") //필터 애너테이션
public class EncoderFilter implements Filter {
ServletContext context;
public void init(FilterConfig fConfig) throws ServletException {
System.out.println("utf-8 인코딩............");
context = fConfig.getServletContext();
}
// 실제 필터 기능 구현 메소드
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)throws ServletException, IOException {
System.out.println("doFilter 호출");
request.setCharacterEncoding( "utf-8" ); //인코딩
tring path = ((HttpServletRequest)request).getContextPath();
String pathinfo = ((HttpServletRequest)request).getRequestURI();
String realPath = request.getRealPath( pathinfo);
String mesg = " Context 정보:" + context
+ "\n URI 정보 : " + pathinfo
+ "\n 물리적 경로: " + realPath;
System.out.println(mesg);
long begin = System.currentTimeMillis(); //요청 필터 - 요청 처리 전 시각
chain.doFilter( request, response ); //다음 필터로 전달 (응답)
long end = System.currentTimeMillis(); //응답 필터 - 요청 처리 후 시각
System.out.println("작업 시간:"+(end-begin)+"ms");
}
public void destroy() {
System.out.println("destroy 호출");
}
}
서블릿 리스너
서블릿에서 발생하는 이벤트에 대해 적절한 처리 수행
사용 시 애너테이션을 이용해 리스너 등록 필요 - HttpSessionBindingListener 제외
Context 객체 속성 이벤트 처리
클라이언트의 요청 이벤트 처리
요청 객체 속성 이벤트 처리
세션 속성 이벤트 처리
컨텍스트 객체 이벤트 처리
세션 활성화/비활성화 이벤트 처리
세션에 바인딩/언바인딩된 객체를 알려주는 이벤트 처리
리스너 등록 불필요
pro10/WebContent/login2.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>로그인창</title>
</head>
<body>
<form name="frmLogin" method="post" action="login" encType="utf-8">
아이디 :<input type="text" name="user_id"><br>
비밀번호:<input type="password" name="user_pw"><br>
<input type="submit" value="로그인">
<input type="reset" value="다시 입력">
</form>
</body>
</html>
pro10/src/sec04/ex01/LoginTest.java
package sec04.ex02;
...
@WebServlet("/login")
public class LoginTest extends HttpServlet {
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();
HttpSession session = request.getSession();
String user_id = request.getParameter("user_id");
String user_pw = request.getParameter("user_pw");
/* 이벤트 핸들러 생성 및 세션에 저장 */
LoginImpl loginUser = new LoginImpl(user_id, user_pw);
if(session.isNew()) { session.setAttribute("loginUser", loginUser); }
out.println("<head>");
out.println("<script type='text/javascript'>");
out.println("setTimeout('history.go(0);', 5000)"); //현재 접속자 수 5초마다 재요청
out.println("</script>");
out.println("</head>");
out.println("<html><body>");
out.println("아이디는 " + loginUser.user_id +"<br>");
out.println("총 접속자수는"+LoginImpl.total_user +"<br>");
out.println("</body></html>");
}
}
pro10/src/sec04/ex01/LoginImpl.java
HttpSessionBindingListener 이벤트 리스너 구현
package sec04.ex01;
import javax.servlet.http.HttpSessionBindingEvent;
import javax.servlet.http.HttpSessionBindingListener;
public class LoginImpl implements HttpSessionBindingListener {
String user_id;
String user_pw;
static int total_user = 0; //접속자수
public LoginImpl() { }
public LoginImpl(String user_id, String user_pw) {
this.user_id = user_id;
this.user_pw = user_pw;
}
@Override
// 세션 바인딩(저장) 시 접속자수 증가
public void valueBound(HttpSessionBindingEvent arg0) {
System.out.println("사용자 접속");
++total_user;
}
@Override
// 세션 소멸 시 접속자수 감소
public void valueUnbound(HttpSessionBindingEvent arg0) {
System.out.println("사용자 접속 해제");
total_user--;
}
}
세션 객체 이벤트 처리
pro10/src/sec04/ex02/LoginTest.java
package sec04.ex02;
...
@WebServlet("/login")
public class LoginTest extends HttpServlet {
ServletContext context = null;
List user_list = new ArrayList(); //접속자 아이디 리스트
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setCharacterEncoding( "utf-8" );
response.setContentType("text/html;charset=utf-8");
context=getServletContext();
PrintWriter out = response.getWriter();
HttpSession session=request.getSession();
String user_id = request.getParameter("user_id");
String user_pw = request.getParameter("user_pw");
/* 이벤트 핸들러 생성 & ServletContext 객체에 바인딩 */
LoginImpl loginUser = new LoginImpl(user_id, user_pw);
if(session.isNew()) { // 최초 로그인 시
session.setAttribute("loginUser", loginUser);
user_list.add(user_id); // 접속자 아이디를 리스트에 저장
context.setAttribute("user_list",user_list); // context 객체 속성으로 저장
}
out.println("<html><body>");
out.println("아이디는 " + loginUser.user_id +"<br>");
out.println("총 접속자 수는" + LoginImpl.total_user +"<br><br>"); //세션 바인딩 이벤트 처리
out.println("접속 아이디:<br>");
List list = (ArrayList) context.getAttribute("user_list");
for(int i = 0; i < list.size(); i++) {
out.println(list.get(i)+"<br>"); //접속자 아이디 출력
}
out.println("<a href='logout?user_id="+user_id+"'>로그아웃 </a>"); //서블릿 로그아웃 처리
out.println("</body></html>");
}
}
pro10/src/sec04/ex02/LogoutTest.java
package sec04.ex02;
...
@WebServlet("/logout")
public class LogoutTest extends HttpServlet {
ServletContext context;
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doHandle(request,response);
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doHandle(request,response);
}
private void doHandle(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setCharacterEncoding( "utf-8" );
response.setContentType("text/html;charset=utf-8");
context=getServletContext();
PrintWriter out = response.getWriter();
HttpSession session = request.getSession();
String user_id = request.getParameter("user_id"); //로그아웃 할 아이디
session.invalidate();
/* 접속자 리스트에서 제거 */
List user_list = (ArrayList) context.getAttribute("user_list");
user_list.remove(user_id);
context.removeAttribute("user_list");
context.setAttribute("user_list", user_list);
out.println("<br>로그아웃했습니다.");
}
}
pro10/src/sec04/ex02/LoginImpl.java
package sec04.ex02;
import javax.servlet.annotation.WebListener;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;
@WebListener //이벤트 핸들러 등록 필수
public class LoginImpl implements HttpSessionListener {
String user_id;
String user_pw;
static int total_user=0;
public LoginImpl() { }
public LoginImpl(String user_id, String user_pw) {
this.user_id = user_id;
this.user_pw = user_pw;
}
@Override
//세션 생성 처리
public void sessionCreated(HttpSessionEvent arg0) {
System.out.println("세션 생성");
++total_user; //접속자 수 증가
}
@Override
//세션 소멸 처리
public void sessionDestroyed(HttpSessionEvent arg0) {
System.out.println("세션 소멸");
--total_user; //접속
}
}
*자바 웹을 다루는 기술