국비지원 JAVA 풀스택 과정/JAVA

[JAVA] 로그인 session 예제

ODaram 2022. 12. 8. 12:54

 

 

session 총 정리

1. 세션은 JSP에서 지원하는 내장객체이다.
 내장 객체는 (어떤것을 내장객체라고 하는지) 객체를 생성하는 코드가 필요없다, 
 객체 생성을 하지 않아도 된다.
 사용은 어떻게 ? session. ~ 으로 사용하면 된다.
 대표적인 내장 객체는 request. ~ 이다. (요청에 대한 내장객체)
 -  request.getParameter에서 서버에 요청된 것을 처리해준다.
 -  입력폼에 입력한 name의 값과 같아야 가져올 수 있다.
 -  가지고 온 후 인증 처리를 위해 각각 변수에 저장을 한다.
 -  저장한 변수를 memMgr.passCheck에 memberid 변수로 보낸다.
 -  memMgr 는 useBean 액션 태그로 지정해준다. ( <jsp:useBean id="memMgr" class="com.session.MemeberMgr" /> )
    끝태그 </jsp:useBean> 를 적어줘야 하나 매번 적기 힘들어 생략하고  마지막에 /를 넣어준다.
 -  useBean으로 지정하지 않으려면 MemberMgr memMgr = new MemberMgr(); 로 생성해준 뒤 
    임포트( <%@ page import = "com.session.MemberMgr"> ) 해준다. (=> 기본 문법이니 꼭 익혀두기)

 

src > main > java > exam-session > <sessionMemberLogin.jsp>

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Login</title>
<link rel="stylesheet" href="css/style.css">
</head>
<body>
	<h2>로그인</h2>
	<div class="container">
		<form action ="sessionMemberLoginOK.jsp" method ="post">
			<ul>
				<li><input type="text" name="memberid" placeholder="아이디 입력" autofocus required></li>
				<li><input type="password" name="memberpw" placeholder="비밀번호 입력" required></li>
				<li>
					<input type="submit" value="LOG IN"> 
						&nbsp;&nbsp; 
					<input type="reset" value="RESET">
				</li>
			</ul>
		</form>
	</div>
</body>
</html>
src > main > java > exam-session > <sessionMemberLoginOK.jsp>

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>

<!-- 두번째 방법 사용 -->
<jsp:useBean id="memMgr" class="com.session.MemberMgr" />

 <%
 	String memberid = null;
 	String memberpw = null;
 
 	if(request.getParameter("memberid") != null) memberid = request.getParameter("memberid");
 	if(request.getParameter("memberpw") != null) memberpw = request.getParameter("memberpw");
 	
 // 위에서 값을 받아왔기 때문에 체크를 해야한다.(검증메서드생성해서 확인해야함)
 // 즉, 인증처리를 하겠다.
 // 처음 화면에서 데이터를 보낼때 (action)에는 JAVA 파일을 지정할 수 없다. 고로 LoginOK.JSP 파일밖에 지정이 안됨
 // loginOK는 서블릿이라고한다. 여기에서 기능에 해당하는것을 작성할 수 있다.
 // 바로 입력하면 분산 프로그램에 위배됨, 모두 분산시키지 않으면 과부화 걸릴 확률이 높아져 미리 분산시키는 것이다. (mv모델과 mvc모델이 있는데 지금은 mv모델이다.)
 // mv모델 : 로직과 화면을 분리했다.

 // 인증을 여기서 하는데 MemberMgr의 기능을 가져와서 한다.
 // MemberMgr.java 를 참조하려면 MemberMgr 의 객체를 생성해야한다. 객체를 생성해서 주소값을 얻어야한다.
 
 // 두가지 방법이 있음
 // 1. new 연산자로 객체생성
 // 2. usebean action 태그로 생성
 
 // 지금은 두번재 방법 사용
 
 	// usebean 생성 후! 
 	if (memMgr.passCheck(memberid, memberpw)) {// passCheck 메서드를 아직 선언하지 않음
		//true 인 경우  (= 데이터베이스에 같은 값이 있다.) 		
		session.setAttribute("memID", memberid); // "" 값을 session에 저장한다.
		// session 객체에 'memID'라는 이름으로 사용자가 입력한 아이디 값을 설정한다. (=저장한다)
 %>
 		<script>
 			// 중간에 JAVAScript 는 코드 블럭 안에 들어갈 수 없다.
 			alert("로그인 되었습니다.");
 			location.href="sessionLoginConfirm.jsp"; 	// 로그인 되면 sessionLoginConfirm.jsp 로 이동해라
 		</script>
 <%
 	}else {

 %>
 		<script>
 			// 중간에 JAVAScript 는 코드 블럭 안에 들어갈 수 없다.
 			alert("로그인에 실패했습니다.");
 			location.href="sessionMemberLogin.jsp"; // 로그인 안되면 다시 로그인 페이지로 이동해라 
 		</script>
<%
	}
%>
src > main > java > exam-session > <sessionLoginConfirm.jsp>

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
    
 <%
 	String id = (String)session.getAttribute("memID");		// 패턴 프로그래밍 : 변수를 선언해서 담아라 , 자료형은 session 이고 캐스팅을 통해 String 자료형으로 변경해줘야함
 	// setAttribue 값 2개, getAttribute 값 2개
 	
 	if(id == null) { // session 값이 없으면 (= 로그인이 안됐으면)	// 이런 경우는 없을 테지만 혹시 모르는 상황에 대비해야한다. 
%>
	<script>
		alert("로그인에 실패했습니다.");
		location.href="sessionMemberLogin.jsp"; 	// location 은 자바스크립트의 내장 속성 / 지정한 페이지로 페이지를 전환한다.
	</script>
<% 		
 	}
 %>
    
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>로그인 성공</title>
</head>
<body>
	<p><strong><%=id %></strong>님이 로그인 했습니다.</p>
	<a href="sessionLogOut.jsp"><strong>LOGOUT</strong></a>
</body>
</html>
src > main > java > com > session >  <MemberMgr.java>


package com.session;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;

/*
  커넥션 풀(Connection Pull) : 데이터베이스 연결 객체를 생성하는 일은 많은 리소스를 소모시킨다.
   연결객체를 필요할 때 생성하는 것은	전체 시스템 속도를 저하의 원인이 된다. 
   따라서 커넥션 객체를 미리 생성(웹 서버가 시작할 때 생성)하고 필요할 때 얻어서 사용하고
   사용이 종료되면 반납하는 방식으로 변경한 것이 커넥션 풀이다.
 */
// DBConnectionMgr.java 에서 db 정보 넣은 뒤 이곳에서 연결해주면 된다.
public class MemberMgr {
	// 클래스 영역(코드블럭{})에 클래스형으로 변수를 선언 (=레퍼런스 변수 선언) 하면 반드시 값을 지정해야하는 의존성이 생긴다.
	// 이것을 '의존성 주입'이라고 표현한다.
	// 의존성 주입 : MemberMgr 클래스는 DBConnectionMgr에 의존적이다. (주입 = 값을 넣어주어야한다.)
	// 커넥션 pool 객체로부터 가져오지 못하면 아무것도 못하기 때문이다. (5행 참조!)
	private DBConnectionMgr pool;  // MemberMgr 은 DBConnectionMgr에 의존한다 (= 반드시 필요하다), pool : 레퍼런스 변수 선언
	// ※※※ 객체의 변수 (= 인스턴스 변수)에 값을 주입하는 방법은 2가지가 있다.(인스턴스 = 객체)
	// 1. setters Method 를 사용하는 방법 : 소프트웨어가 운영 중에 데이터를 주입한다.
	// 2. 생성자를 사용하는 방법 : 소프트웨어가 운영되기 전에 데이터를 주입한다.

	// DB커넥션은 소프트웨어가 운영되기 전에 주입해야한다. (톰캣이 실행되면 DBConnectionMgr가 바로 운영된다. )
	// 커넥션 풀 객체에서 커넥션 객체를 얻어야 하므로 미리 커넥션 풀 객체를 얻어와야 한다. (2번 사용!)
	
	// ※※※ 생성자 문법 
	public MemberMgr() { // 생성자로 커넥션 풀 인스턴스 변수를 초기화 한다. (= 처음 주입할 때를 초기화라고 한다.)
		//  DBConnectionMgr 는 톰캣이 실행되면 바로 운영되나 물리적으로 위치가 다르다.
		// 그렇기 때문에 예외처리를 해야한다. try {} catch(Exception e) {}
		try {
			// DBConnectionMgr 클래스의 static Method인 getInstance()를 호출해서 커넥션 풀 객체를 얻어 pool 인스턴스 변수를 초기화 한다. 
			//   = 커넥션 풀 객체를 얻는다.
			pool = DBConnectionMgr.getInstance();	// getInstance() :  객체를 얻는다. 
		}catch(Exception e) {System.out.println(e);}  // 커넥션 풀 객체를 못 얻어올 경우 오류 메시지를 Console 뷰에 출력한다. (왜 실패했는지 출력을 해준다.)
		

	}
	
	/* 
 	생성자를 통해 인스턴스 변수에 pool 객체를 얻어왔으니,
 	pool.getconnection 메서드를 호출하면 connection pool 로 부터 connection 객체를 얻어온다.
	Connection con = pool.getConnection();
 */
	//sessionMemberLoginOK 에서 31행 작성 후 
	public boolean passCheck(String memberid, String memberpw) { // sessionMemberLoginOK 에서 String 2개를 받아온다.
		// 사용자가 입력한 아이디와 비밀번호 값과 데이터베이스에 있는 아이디와 비밀번호 값을 비교한다.
		// 값을 비교해서 같은 값이 있으면 true를 반환하고 같은 값이 없으면 false를 반환한다.
		
		
		Connection con = null ;		// 클래스를 불러오는 import 작업을 해줘야한다. (최상단, java.sql 로 import 해야됨)
		PreparedStatement pstmt = null;
		ResultSet rs = null;
		// 결과값을 담는 변수 필요 
		boolean flag = false;
		
		// 물리적으로 분리 되어있을 때는 반드시 예외처리 해줘야함
		try {
			con=pool.getConnection();
			
			// 반복문을 사용해 비교를 하면 속도가 너무 느리다, 수만건의 데이터를 java로 가져오면 시간이 많이 걸린다. => DBMS에서 해결
			String sql = "select count(*) from tblMember where id = ? and pwd = ?"; // 프로그램 시 쿼리문 작성 할때 키워드는 대문자로 작성한다. / DBMS에서 처리하도록 해준다.
			// ? (위치홀더) 에 String memberid, String memberpw를 넣는다. 
			// 같은 값이 있으면 1(true)를 반환, 없으면 0(false)를 반환한다.
			
			// 쿼리 실행 객체 pstmt
			pstmt = con.prepareStatement(sql);
			pstmt.setString(1, memberid); // 첫번째 위치홀더에 위에서 매개변수로 받은 id 값 넣기
			pstmt.setString(2, memberpw);
			// 쿼리문 완성됨
			
			// 쿼리문 실행해야함
			rs = pstmt.executeQuery();	// 반환 값을 rs에 저장
			rs.next();	// sql 에 같은 값이 있다.
			
			if(rs.getInt(1) > 0 ) flag = true;	// rg.getInt(1)는 첫번째 컬럼의 값을 얻어온다.
		} catch(Exception e) {System.out.println(e);}
		
		finally { pool.freeConnection(con, pstmt, rs); }	// 자원을 반납한다.
		
		return flag; //인증처리 성공 시 true 값이 담김
		// LoginOK 로 반환한다.
	}
}

 

src > main > java > exam-session > <sessionLogOut.jsp>

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
    
<%
	// 세션을 강제로 객체를 없앤다. (정보의 유무와 상관없이 모두 없앤다.)
	session.invalidate();	// ※세션을 제거하는 메서드 이다.
%>

<script>
	alert("로그아웃 되었습니다.");
	location.href="sessionMemberLogin.jsp";
</script>