티스토리 뷰
Session Login/Logout -2
Session을 이용한 로그인 상태 유지 및 사용자 관리
1. session 내부 객체의 사용(HttpSession interface)
- javax.servlet.http.HttpSession Interface의 구현 객체, Server 제공자인 Apache Tomcat에서 기능을 구현한다.
- JSP에서의 세션은 HttpSession을 사용하며, JSP의 request, response와 마찬가리로 기본 내장 객체로 지정되어 있어 별도의 구현없이 사용이 가능
- 세션은 클라이언트의 브라우저 1개당 1개씩 생성되며, 동일 클라이언트라고 할지라고 브라우저 종류(Chrome, FF, IE)가 다르면 세션을 추가로 생성하는게 가능
- 둘 이상의 page request에서 사용자를 식별하거나, 웹 사이트를 방문하고 해당 사용자에 대한 정보를 저장하는 방법을 제공
- 서버의 메모리 상에 저장되는 정보이며 접속한 사용자 별로 세션 메모리가 할당된다. 모든 페이지에서 session 객체를 사용 할 수 있다. 사용자가 서버에 접속하면 session이 할당되고 브라우저를 닫거나 로그아웃을 하면 session 정보가 저장된 메모리가 자동으로 해제된다.
requset : 폼에서 보낸 데이터를 순간만 저장하는 메모리로 JSP 페이지 요청 마다 새로 생성되고 응답시 삭제
- 사용자가 로그인하면 웹사이트 전체에서 계속적으로 유지되는 ID와 패스워드 등은 session 변수로 저장하여 처리
- 서버의 메모리(RAM)를 사용함으로 비용이 많이 발생되어 필요한 곳에만 사용하는 것이 좋음
- 서버상에 있는 사용자와 관련된 모든 세션 변수의 값을 삭제하려면 session.invalidate()를 이용함
2. HashTable
- HashTable은 키와 값을 쌍으로 이루어진 구조를 띄고 있다.
- key 값은 기본적으로 중복이 불가능, 같은 키 값을 두번 입력하면 이전에 입력한 값이 할당됨
- HashTable 속성
- Hashtable<String, Integer> ht = new Hashtable<String, Integer>();
- ht.put("a", 1); // 키 : a, 값 : 1
- ht.get("a"); // a키에 해당하는 값 얻어오기
- Enumeration en = ht.keys(); // 해시 테이블에 있는 값 꺼내오기
3. Enumeration
- Enumeration 인터페이스는 객체들의 집합에서 각각의 객체들을 한 순간에 하나씩 처리 할 수 있는 메소드를 제공하는 컬렉션
- hasMoreElement() : vector로 부터 생성된 Enumeration의 요소가 있으면 true, 없으면 false 반환
4. 소스코드
- bit_login package들이 controller에 해당
- WebContent 폴더의 jsp 파일은 view에 해당
- Join.jsp
<%@ page language="java" contentType="text/html; charset=EUC-KR"
pageEncoding="EUC-KR"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="EUC-KR">
<title>BIT_LOGIN</title>
</head>
<body>
<center>
<form action="JoinProc.jsp" method="post">
<h1>회원가입</h1>
<p style="color: green">
아이디는 10자 이내로, 패스워드는 20자 이내로
</p>
ID <input type="text" name="id" size="30" placeholder="아이디" required="required" /> <br />
PW <input type="password" name="pw" size="30" placeholder="비밀번호" required="required" /> <br />
PW confirm <input type="password" name="pwcon" size="30" placeholder="비밀번호 확인" required="required" /> <br />
<input type="submit" value="회원가입" />
<input type="button" onclick="location.href='Login.jsp'" value="취소" />
</form>
<%
if (request.getParameter("error") != null) {
%>
<p style="color: red">
<%=request.getParameter("error")%>
</p>
<%
}
%>
</center>
</body>
</html>
- JoinProc.jsp
<%@page import="bit_login.MemberDAO"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%
request.setCharacterEncoding("euc-kr");
String id = request.getParameter("id");
String pw = request.getParameter("pw");
String pwcon = request.getParameter("pwcon");
String redirectUrl = "Join.jsp?error=The passwords are different.";
MemberDAO m = MemberDAO.getInstance();
if (m.checkPw(pw, pwcon)) {
if (m.checkLength(id, pw)) {
if (m.joinMember(id.toLowerCase(), pw)) {
redirectUrl = "Login.jsp?error=registration completed";
}
else {
redirectUrl = "Join.jsp?error=ID already registered.";
}
}
else {
redirectUrl = "Join.jsp?error=ID or PW length exceeded.";
}
}
response.sendRedirect(redirectUrl);
%>
- Login.jsp
<%@page import="bit_login.MemberSession"%>
<%@page import="bit_login.MemberDAO"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%
MemberDAO m = MemberDAO.getInstance();
MemberSession ms = MemberSession.getInstance();
%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>BIT_LOGIN</title>
</head>
<body>
<center>
현재 접속자수 :
<%=ms.getUserCount()%>
<!-- 해쉬테이블(세션)을 뒤져 세션이 있는지 확인 -->
<%
if (ms.isLogin(session.getId())) {
%>
<!-- 해쉬테이블에서 login이 되어 있으면 main 출력 -->
<h1>
<%=ms.getUserID(session.getId())%>님 반갑습니다.
</h1>
<a href="LogoutProc.jsp">로그아웃</a>
<!-- 해쉬테이블(세션)에 존재하지 않으면 else Login 출력 -->
<%
} else {
%>
<form action="LoginProc.jsp" method="post">
<h1>Login</h1>
<input type="text" name="id" size="30" placeholder="아이디" required="required" /> <br />
<input type="password" name="pw" size="30" placeholder="비밀번호" required="required" /> <br />
<input type="submit" value="로그인" />
<input type="button" onclick="location.href='Join.jsp'" value="회원가입" />
</form>
<%
}
%>
<%
if (request.getParameter("error") != null) {
%>
<p style="color: red">
<%=request.getParameter("error")%>
</p>
<%
}
%>
</center>
</body>
</html>
- LoginProc.jsp
<%@page import="bit_login.MemberSession"%>
<%@page import="bit_login.MemberDAO"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%
request.setCharacterEncoding("euc-kr");
String id = request.getParameter("id");
String pw = request.getParameter("pw");
String redirectUrl = "Login.jsp?error=ID or PW is different.";
MemberDAO m = MemberDAO.getInstance();
MemberSession ms = MemberSession.getInstance();
// 회원정보가 존재하는지 check
if(m.checkMember(id, pw)) {
// 이미 다른 곳에서 로그인 되어 있는지 check
if(!ms.isUsing(id)) {
/* 회원 정보가 존재하고 로그인이 되어 있지 않다면 session 등록 */
ms.setSession(session, id);
redirectUrl = "Login.jsp";
}
else {
/* 회원정보는 존재하지만 로그인이 이미 되어 있다면 */
redirectUrl = "Login.jsp?error=This ID is already logged in.";
}
}
response.sendRedirect(redirectUrl);
%>
- LogoutProc.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%
session.invalidate();
response.sendRedirect("Login.jsp");
%>
- MemberDAO.java
package bit_login;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.List;
import javax.servlet.http.HttpSession;
import javax.servlet.http.HttpSessionBindingEvent;
import javax.servlet.http.HttpSessionBindingListener;
public class MemberDAO{
private static MemberDAO instance = null;
// List로 회원 정보를 관리한다.
private static ArrayList<MemberDTO> memberList = new ArrayList<MemberDTO>();
private MemberDAO(){}
public static MemberDAO getInstance(){
if(instance == null) {
instance = new MemberDAO();
setup();
}
return instance;
}
public static void setup() {
memberList.add(new MemberDTO("min", "min123"));
memberList.add(new MemberDTO("hoon", "hoon123"));
memberList.add(new MemberDTO("hwan", "hwan123"));
memberList.add(new MemberDTO("hyun", "hyun123"));
}
// 로그인 버튼 클릭시 여기로
// 회원 정보 list에서 회원 정보가 있는지 check 한다.
public boolean checkMember(String id, String pw) {
for(MemberDTO data: memberList) {
if(data.getId().equals(id) && data.getPW().equals(pw)) {
return true;
}
}
return false;
}
// ID 중복 검사
public boolean checkId(String id) {
for(MemberDTO data: memberList) {
if(data.getId().equals(id)) {
return true;
}
}
return false;
}
public boolean checkLength(String id, String pw) {
if(id.length() > 10 || pw.length() > 20) {
return false;
}
return true;
}
// PW, PWCON 일치 검사
public boolean checkPw(String pw, String pwcon) {
if (pw.equals(pwcon)) {
return true;
}
return false;
}
// 이미 존재하는 id인지 확인
public boolean joinMember(String id, String pw) {
if(checkId(id)) {
return false;
}
// 이미 존재하지 않으면 add
memberList.add(new MemberDTO(id, pw));
return true;
}
}
- MemberDTO.java
package bit_login;
public class MemberDTO {
private String id;
private String pw;
public MemberDTO(String id, String pw) {
this.id = id;
this.pw = pw;
}
public String getId() {
return id;
}
public String getPW() {
return pw;
}
}
- MemberSession.java
package bit_login;
import java.util.Enumeration;
import java.util.Hashtable;
import javax.servlet.http.HttpSession;
import javax.servlet.http.HttpSessionBindingEvent;
import javax.servlet.http.HttpSessionBindingListener;
public class MemberSession implements HttpSessionBindingListener{
private static MemberSession instance = null;
private static Hashtable loginUsers = new Hashtable();
private MemberSession(){}
public static MemberSession getInstance(){
if(instance == null) {
instance = new MemberSession();
}
return instance;
}
// 이미 세션이 등록되어 있는지 확인
public boolean isLogin(String sessionID) {
boolean isLogin = false;
// 해시테이블 loginUsers에 있는 모든 값들을 가져온다.
Enumeration e = loginUsers.keys();
String key = "";
while(e.hasMoreElements()) {
key = (String)e.nextElement();
if(sessionID.equals(key)) {
isLogin = true;
}
}
return isLogin;
}
// 이미 로그인 되어 있는지 확인
public boolean isUsing(String id) {
boolean isUsing = false;
Enumeration e = loginUsers.keys();
String key = "";
while(e.hasMoreElements()) {
key = (String)e.nextElement();
if(id.equals(loginUsers.get(key))) {
isUsing = true;
}
}
return isUsing;
}
// 세션을 해쉬테이블에 등록
public void setSession(HttpSession session, String id) {
// 할당된 고유의 세션 값을 key로, id를 값으로 하여 해쉬테이블에 등록
loginUsers.put(session.getId(), id);
session.setAttribute("login", this.getInstance());
}
@Override
public void valueBound(HttpSessionBindingEvent event) {
}
// 해쉬테이블의 세션을 삭제
@Override
public void valueUnbound(HttpSessionBindingEvent event) {
loginUsers.remove(event.getSession().getId());
}
public String getUserID(String sessionID) {
return (String)loginUsers.get(sessionID);
}
// 해쉬테이블에 등록된 세션 즉, 접속자의 수를 구하기 위함.
public int getUserCount() {
return loginUsers.size();
}
}
5. 실행결과
2019.09.17(화)
Session Login/Logout -2
'JSP' 카테고리의 다른 글
[JSP] Session Login/Logout -1 (0) | 2019.09.16 |
---|
댓글