JSP : 내장 객체 / session
session : javax.servlet.http.HttpSession
HTTP 프로토콜은 클라이언트와 서버 간의 상태에 대한 보존 없이,
매번 새로운 연결을 하고 요청에 대한 응답을 서버가 전송하고 나면 모든 연결이 끊어진다.
연결이 끊어지면 클라이언트의 정보도 모두 사라진다.
→ 이런 정보를 보존하기 위해서 세션을 사용한다.
즉, 서버가 클라이언트의 정보를 갖고 있는 상태를 '세션'이라고 한다.
쿠키는 브라우저에 저장되지만 세션은 서버에 저장된다.
*클라이언트에 저장된 쿠키는 열어볼 수 있기 때문에 보안이 중요한 정보는 쿠키에 저장하지 않는다.
저장되는 내용은 프로그램 종료(로그아웃, 브라우저 종료 등)시까지 유지된다.
→ id, name, 장바구니 목록..등이 저장된다.
(ex) 장바구니는 임시로 저장하기 때문에(결제가 이뤄지기 전) 세션에 저장해두었다가,
결제가 완료된 것만 DB로 옮겨주는 방식으로 작동한다.
→ 세션은 서버에 저장되기 때문에 프로젝트의 모든 jsp에서 공유가 가능하다.
→ 세션은 HttpSession 로부터 파생된 내장 객체이다.
HttpSession session = request.getSession() 으로 생성되고 있음
request는 session생성, cookie 생성 등이 다 가능하다.
세션의 주요 기능
1) 저장
setAttribute(key, value) : key를 주고 value를 등록한다.
*value를 Object 단위로 저장한다.
2) 저장값 읽기
getAttribute(key) : key를 주고 value 를 얻을 수 있다.
getAttribute() == null → 로그인이 되지 않은 상태
*리턴형이 Object이기 때문에 형변환을 시켜 가져와야 한다.
3) 일부 삭제
removeAttribute(key) : 하나씩 삭제할 때
4) 전체 삭제
invalidate() : 로그아웃할 때 많이 사용함(세션에 있는 모든 내용을 지운다)
5) 기간 설정(언제까지 저장할 것인지)
기본으로 30분, 지정하지 않으면 자동 삭제된다.
setMaxInactiveInterval(time) 단위는 초!
세션을 이용해서 로그인 상태가 유지되는 홈페이지를 만들어 보자.
시간관계상 CSS는 BootStrap으로 처리한다.
우선 로그인/로그아웃 모듈을 만들어 준다.
이 jsp를 화면 분할한 main.jsp에 붙여서 포털 사이트같은 화면을 만들 것이다!
login.jsp
간단하게 아이디와 비밀번호를 입력할 input칸을 만들고,
<form>으로 감싸 <button>으로 로그인 처리를 담당할 longin_ok.jsp로 보내준다.
이 때, 경로를 ../member/login_ok.jsp 로 작성하는 이유는...
login.jsp가 결국 main에 포함되어 main.jsp로써 작동할 것이기 때문이다!
login.jsp라고만 적어 주면 main.jsp 의 입장에서는 위치를 알 수 없어진다.(아래 트리 참고)
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<%-- 한 줄 만들 때 class=row 함 --%>
<div class="row">
<form method=post action="../member/login_ok.jsp">
<table class="table">
<tr>
<th class="text-right" width=30%>ID </th>
<td width=70%>
<input type=text name=id size=15 class="input-sm" required>
<%-- input 사이즈 / sm md lg xs, required : 필수입력 --%>
</td>
</tr>
<tr>
<th class="text-right" width=30%>PW </th>
<td width=70%>
<input type=password name=pwd size=15 class="input-sm" required>
</td>
</tr>
<tr>
<td colspan="2" class="text-center">
<button class="btn btn-sm btn-danger">login</button>
</td>
</tr>
</table>
</form>
</div>
</body>
</html>
login_ok.jsp
로그인을 처리하면서, session에 id와 name이라는 key로 각각 저장해 준 후, main으로 다시 돌아간다.
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%
session.setAttribute("id","admin");
session.setAttribute("name","kim");
//main.jsp로 이동
response.sendRedirect("../main/main.jsp");
%>
logout.jsp
로그인 이후 화면을 logout.jsp에 구현한다. (로그아웃 버튼이 있기 때문에 이름이 logout)
session을 호출하여 name 을 불러와 화면에 보여 준다.
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<div class="row">
<form method=post action="../member/logout_ok.jsp">
<table class="table">
<tr>
<td width=70%>
<%=session.getAttribute("name") %>님
</td>
</tr>
<tr>
<td width=70%>
메일 : 2 쪽지 : 39
</td>
</tr>
<tr>
<button class="btn btn-sm btn-danger">logout</button>
</td>
</tr>
</table>
</form>
</div>
</body>
</html>
logout_ok.jsp
로그아웃을 처리하면서 session.invalidate()로 모든 세션을 제거한 후 다시 메인으로 이동한다.
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%
session.invalidate(); //다 해제
//main.jsp로 이동
response.sendRedirect("../main/main.jsp");
%>
main.jsp
메인에서는 로그인에서 등록한 세션을 불러와 id를 인식한다.
id가 비어 있으면(세션 없음) 미로그인 상태이므로 로그인 영역에 login.jsp를 불러와 보여 주고,
비어 있지 않으면 로그인 영역에 logout.jsp 를 불러와 보여 주도록 세팅한다.
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%
String id = (String)session.getAttribute("id");
String log_jsp="";
if(id==null){
log_jsp="../member/login.jsp";
}else{
log_jsp="../member/logout.jsp";
}
%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<%-- BootStrap CSS가져오기 --%>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/js/bootstrap.min.js"></script>
<style type="text/css">
.container{
margin-top: 20px;
width: 1200px;
}
.col-sm-3{
height: 800px;
}
.col-sm-9{
height: 800px;
}
</style>
</head>
<body>
<jsp:include page="header.jsp"></jsp:include>
<div class="container">
<div class="col-sm-3">
<jsp:include page="<%=log_jsp %>"></jsp:include>
</div>
<%-- col-sm-n에서 n들의 합이 12가 되면 된다. 12 이상을 벗어나면 아래로 내려 간다. --%>
<div class="col-sm-9">
</div>
</div>
</body>
</html>
*col-sm-n 클래스 속성
화면을 분할해 준다. col-sm-.. 클래스를 가진 요소들끼리의 n의 총합이 12가 되도록 한다.
비율은 알아서 조정되고, 합이 12가 넘는 경우 아래로 내려간다.
위의 코드를 실행하면 아래처럼 화면이 분할된다.
이제 기능을 좀 더 추가해서,
가입되어 데이터베이스에 등록된 유저만 로그인이 가능하도록 만들어 보자.
MemberDAO.java
데이터베이스에서 불러온 데이터와 입력된 값을 대조하여 로그인 가능여부를 체크하는 DAO를 구현한다.
로그인 경우의 수는 ID가 없는 경우, 비밀번호가 틀린 경우, 로그인 성공 으로 3가지이다.
따라서 로그인 가능여부를 판단하는 isLogin() 의 결과값으로 Boolean은 사용할 수 없고, String 을 반환하도록 한다.
*숫자로 넘겨도 되지만 숫자는 가독성때문에 대체로 상수화해서 넘긴다. (final int LOGIN =100 이런식)
package dao;
import java.util.*;
import java.sql.*;
import doodoo.conn.DBConnection;
public class MemberDAO {
private Connection conn;
private PreparedStatement ps;
private DBConnection dbconn = DBConnection.newInstance();
public String isLogin(String id, String pwd) {
String result = "";
try {
conn = dbconn.getConnection();
//우선 id 체크
String sql = "SELECT COUNT(*) FROM jspMember " +
"WHERE id=?";
ps = conn.prepareStatement(sql);
ps.setString(1, id);
ResultSet rs = ps.executeQuery();
rs.next();
int count = rs.getInt(1);
rs.close();
if (count == 0) {
//ID 없음
result = "NOID";
}
if (count != 0) {
//ID 있음 -> PW검색시작
sql = "SELECT pwd, name FROM jspMember " +
"WHERE id=?";
ps = conn.prepareStatement(sql);
ps.setString(1, id);
rs = ps.executeQuery();
rs.next();
String db_pwd = rs.getString(1);
String name = rs.getString(2);
rs.close();
if (db_pwd.equals(pwd)) {
result = name;
} else {
result = "NOPWD";
}
}
} catch (Exception ex) {
ex.printStackTrace();
System.out.println("Error! : isLogin()");
} finally {
dbconn.disConnection(ps);
}
return result;
}
}
login_ok.jsp
login.jsp에서 사용자가 request에 실어서 보내 준 데이터를 받아서,
데이터베이스에 연동하여 isLogin()과 요청 처리에 필요한 데이터를 읽는다!
이 때, 넘어오는 데이터들에 한글이 포함되어 있지 않기 때문에 setCharacterEncoding은 안해줘도 된다.
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8" import = "dao.*"%>
<jsp:useBean id="dao" class="dao.MemberDAO"/>
<%-- MemberDAO dao = new MemberDAO() 와 같다. --%>
<%
String id = request.getParameter("id");
String pwd = request.getParameter("pwd");
String result = dao.isLogin(id, pwd);
if(result.equals("NOID")){ //ID 없음
%>
<script>
alert("ID가 존재하지 않습니다!");
history.back();
</script>
<% }else if(result.equals("NOPWD")){ //비밀번호 틀림
%>
<script>
alert("비밀번호 다시 생각해 보세요~");
history.back();
</script>
<% }else{ //로그인 성공
session.setAttribute("id",id);
session.setAttribute("name",result);
//main.jsp로 이동
response.sendRedirect("../main/main.jsp");
}
%>
header.jsp
logout.jsp, logout_ok.jsp등은 동일하고, 헤더에 조금 변화를 줘 보자.
로그인한 사람의 id를 인식하여 관리자/일반회원/미로그인 각각 다른 헤더를 보이게 세팅한다. 그럼 끝.
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%
String id = (String)session.getAttribute("id");
%>
<%-- MENUBAR --%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<%-- 가져온 BootStrap:https://www.w3schools.com/bootstrap/bootstrap_navbar.asp --%>
<nav class="navbar navbar-inverse">
<div class="container-fluid">
<div class="navbar-header">
<a class="navbar-brand" href="#">JSPSite</a>
</div>
<ul class="nav navbar-nav">
<li class="active"><a href="../main/main.jsp">Home</a></li>
<li class="dropdown"><a class="dropdown-toggle" data-toggle="dropdown" href="#">회원
<span class="caret"></span></a>
<% if(id==null){//로그인 여부에 따라 다른 메뉴 출력%>
<ul class="dropdown-menu">
<li><a href="#">회원가입</a></li>
<li><a href="#">ID찾기</a></li>
<li><a href="#">PW찾기</a></li>
</ul>
<%}else{ %>
<ul class="dropdown-menu">
<li><a href="#">회원 수정</a></li>
<li><a href="#">회원 탈퇴</a></li>
</ul>
<%} %>
</li>
<li class="dropdown"><a class="dropdown-toggle" data-toggle="dropdown" href="#">맛집
<span class="caret"></span></a>
<ul class="dropdown-menu">
<li><a href="#">지역별 맛집 찾기</a></li>
<%if(id!=null){ %>
<li><a href="#">맛집 추천</a></li>
<li><a href="#">맛집 예약</a></li>
<%} %>
</ul>
</li>
<li class="dropdown"><a class="dropdown-toggle" data-toggle="dropdown" href="#">레시피
<span class="caret"></span></a>
<ul class="dropdown-menu">
<li><a href="#">레시피 목록</a></li>
<li><a href="#">쉐프</a></li>
<%if(id!=null){ %>
<li><a href="#">레시피 만들기</a></li>
<%} %>
</ul>
</li>
<li class="dropdown"><a class="dropdown-toggle" data-toggle="dropdown" href="#">서울 여행
<span class="caret"></span></a>
<ul class="dropdown-menu">
<li><a href="#">명소</a></li>
<li><a href="#">자연 & 관광</a></li>
<li><a href="#">쇼핑</a></li>
<li><a href="#">호텔</a></li>
<li><a href="#">게스트하우스</a></li>
</ul>
</li>
<li class="dropdown"><a class="dropdown-toggle" data-toggle="dropdown" href="#">커뮤니티
<span class="caret"></span></a>
<ul class="dropdown-menu">
<li><a href="#">공지사항</a></li>
<li><a href="#">묻고 답하기</a></li>
<%if(id!=null){ %>
<li><a href="#">자유 게시판</a></li>
<%} %>
</ul>
</li>
<%if(id!=null){ %>
<li><a href="#">맛집 빠른 예약</a></li>
<%} %>
<li><a href="#">레시피 쇼핑몰</a></li>
<%if(id!=null){
if(id.equals("admin")){%>
<li><a href="#">예약 현황</a></li>
<li><a href="#">구매 현황</a></li>
<%
}else{
%>
<li><a href="#">마이 페이지</a></li>
<% }
}
%>
</ul>
</div>
</nav>
</body>
</html>
추가로 위와 같이 로그인 영역 옆에 맛집 리스트들을 띄우는 것은.. 코드만 첨부한다.
main.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%
String id = (String)session.getAttribute("id");
String log_jsp="";
if(id==null){
log_jsp="../member/login.jsp";
}else{
log_jsp="../member/logout.jsp";
}
String[] jsp_list = {
"",//0번은 뺄것임~
"../food/category.jsp",
"../food/food_list.jsp",
"../food/food_detail.jsp"
};
// 사용자가 화면을 보여달라고 요청
String mode = request.getParameter("mode");
if(mode==null)
mode="1";
int index = Integer.parseInt(mode);
String jsp = jsp_list[index];
%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<%-- BootStrap CSS가져오기 --%>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/js/bootstrap.min.js"></script>
<style type="text/css">
.container{
margin-top: 20px;
width: 1200px;
}
.col-sm-3{
height: 800px;
}
.col-sm-9{
height: 800px;
}
</style>
</head>
<body>
<jsp:include page="header.jsp"></jsp:include>
<div class="container">
<div class="col-sm-3">
<jsp:include page="<%=log_jsp %>"></jsp:include>
</div>
<%-- col-sm-n에서 n들의 합이 12가 되면 된다. 12 이상을 벗어나면 아래로 내려 간다. --%>
<div class="col-sm-9">
<jsp:include page="<%=jsp %>"></jsp:include>
</div>
</div>
</body>
</html>
category.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8" import="java.util.*, dao.*, vo.*"%>
<jsp:useBean id="dao" class="dao.FoodDAO"/>
<%
List<CategoryBean> list = dao.CategoryListData();
%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<h3>믿고보는 맛집 리스트</h3>
<hr>
<div class="row">
<%
for(int i=0;i<12;i++){
CategoryBean cb = list.get(i);
%>
<div class="col-md-3">
<div class="thumbnail">
<a href="#">
<img src="<%=cb.getPoster() %>" alt="Lights" style="width:100%">
<div class="caption">
<p><%=cb.getTitle() %></p>
</div>
</a>
</div>
</div>
<%} %>
</div>
<h3>지역별 맛집 리스트</h3>
<div class="row">
<%
for(int i=12;i<18;i++){
CategoryBean cb = list.get(i);
%>
<div class="col-md-4">
<div class="thumbnail">
<a href="#">
<img src="<%=cb.getPoster() %>" alt="Lights" style="width:100%">
<div class="caption">
<p><%=cb.getTitle() %></p>
</div>
</a>
</div>
</div>
<%} %>
</div>
<h3>메뉴별 인기 맛집</h3>
<div class="row">
<%
for(int i=13;i<30;i++){
CategoryBean cb = list.get(i);
%>
<div class="col-md-3">
<div class="thumbnail">
<a href="#">
<img src="<%=cb.getPoster() %>" alt="Lights" style="width:100%">
<div class="caption">
<p><%=cb.getTitle() %></p>
</div>
</a>
</div>
</div>
<%} %>
</div>
</body>
</html>
FoodDAO.java
package dao;
import java.util.*;
import java.sql.*;
import vo.*;
import doodoo.conn.DBConnection;
public class FoodDAO {
private Connection conn;
private PreparedStatement ps;
private DBConnection dbconn = DBConnection.newInstance();
public List<CategoryBean> CategoryListData(){
List<CategoryBean> list = new ArrayList<CategoryBean>();
try {
conn = dbconn.getConnection();
String sql = "SELECT cno, title, poster "
+"FROM food_category "
+"ORDER BY cno ASC";
ps = conn.prepareStatement(sql);
ResultSet rs = ps.executeQuery();
while(rs.next()) {
CategoryBean cb = new CategoryBean();
cb.setCno(rs.getInt(1));
cb.setTitle(rs.getString(2));
cb.setPoster(rs.getString(3));
list.add(cb);
}
rs.close();
}catch(Exception ex) {
ex.printStackTrace();
}finally {
dbconn.disConnection(ps);
}
return list;
}
}
CategoryBean.java
package vo;
public class CategoryBean {
private int cno;
private String title, subject, poster;
public int getCno() {
return cno;
}
public void setCno(int cno) {
this.cno = cno;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getSubject() {
return subject;
}
public void setSubject(String subject) {
this.subject = subject;
}
public String getPoster() {
return poster;
}
public void setPoster(String poster) {
this.poster = poster;
}
}
'부트캠프(END) > Web' 카테고리의 다른 글
DBCP(DataBase Connection Pool) (0) | 2022.07.22 |
---|---|
jspBean (0) | 2022.07.21 |
JSP : 내장 객체 / application + cookie (0) | 2022.07.20 |