30일차(2)/jsp(10) : Session Scope
<index.jsp>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>/index.jsp</title>
</head>
<body>
<div class="container">
<h1>인덱스 페이지입니다.</h1>
<ul>
<li><a href="${pageContext.request.contextPath }/fortune">오늘의 운세</a></li>
<li><a href="${pageContext.request.contextPath }/member">회원 한명의 정보 보기</a></li>
<li><a href="${pageContext.request.contextPath }/friend/list">친구 목록 보기</a></li>
<li><a href="test/play.jsp">놀러가기</a></li>
</ul>
</div>
<form action="${pageContext.request.contextPath }/test/save.jsp" method="post">
<input type="text" name="nick" placeholder="닉네임 입력..." />
<button type="submit">닉네임 기억시키기</button>
</form>
<br />
<form action="${pageContext.request.contextPath }/test/save" method="post">
<input type="text" name="nick" placeholder="닉네임 입력..." />
<button type="submit">닉네임 기억시키기</button>
</form>
</body>
</html>
- 새 form, button 을 추가한다.
- post방식으로 전송하고, "nick"이라는 파라미터명으로 전송되는 닉네임을 읽어낼 것이다.
<save.jsp> session scope 추가
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%
//폼 전송되는 닉네임을 읽어와서
request.setCharacterEncoding("utf-8");
String nick=request.getParameter("nick");
//Session scope에 "nick"이라는 키값으로 저장하기
session.setAttribute("nick", nick);
%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>/test/save.jsp</title>
</head>
<body>
<p> <strong><%=nick %></strong>이라는 닉네임을 기억하겠습니다.</p>
<p> 30분 동안 아무런 요청을 하지 않거나 웹브라우저를 닫으면 자동 삭제 됩니다.</p>
<a href="../index.jsp">인덱스로 이동하기</a>
</body>
</html>
- request 영역만 있는게아니라 session scope 라는 영역도 있다.
- <% %>영역에서 기본변수 중 session 변수 찾기
- 같은 .setAttribute 메소드를 사용한다.
request.에 점을 찍으면 request scope에 저장하고,
session. 에 점을 찍으면 session scope에 저장하는 것
- session에 담으면 응답이 끝나도 사라지지 않는다. 페이지를 이동해도 살아있다!
- 인덱스에 /test/play.jsp로 이동하는 링크 추가
<play.jsp> 생성
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>/test/play.jsp</title>
</head>
<body>
<%
/*
HttpSession 객체에 "nick" 이라는 키값으로 저장된 값이 있는지 읽어와 본다. 없으면 null이 리턴된다.
(session scope에 "nick"이라는 키값으로 저장된 문자열이 있는지 읽어와 본다.)
*/
String nick=(String)session.getAttribute("nick");
//60초 동안 다시 요청을 해오지 않으면 자동으로 삭제되도록 설정
//session.setMaxInactiveInterval(60);
//session scope에 저장된 모든 값 삭제하기
session.invalidate();
%>
<h3>노는 페이지입니다.</h3>
<%if(nick==null) {%>
<p>session 영역(scope)에 "nick"이라는 키값으로 저장된 값이 없습니다.</p>
<%}else{ %>
<p>
<strong><%=nick %></strong> 님 놀러 오셨네요? 신나게 놀다 가세요!
<a href="logout.jsp">세션에 저장된 nick 삭제(로그아웃)</a>
</p>
<%} %>
</body>
</html>
- getAttribute로 저장해놓은 값 가져오기.
- request와 사용법은 똑같다. 그 데이터가 얼마나 오래 유지되는지가 다를 뿐이다.
- 폼에 값을 입력해 저장한 후 놀러가기를 누르면 닉네임이 저장된 것을 볼 수 있다.
- 응답할때 한번 사용하고 잊어버리는 것은 request scope에 (일회성 데이터),
페이지를 이동해도 게속 유지하는 것은 session scope에 저장한다!
- session에 로그인했는지에 대한 정보, 어떤 아이디로 로그인했는지 등등을 담아두면 좋다.
(만약 로그인 정보를 request영역에 담아두면 페이지를 이동할 때마다 로그인을 해야한다...)
- 그러면 언제까지 기억하는가? 30분 동안 아무런 요청을 하지않거나, 웹브라우저를 닫으면 사라진다.
- 세션 유지시간을 임의로 줄일 수도 있고, 강제로 세션영역에 있는 것을 지울수도 있다.
/test/ <logout.jsp> 만들기
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>/test/logout.jsp</title>
</head>
<body>
<%
//세션 영역에 "nick"이라는 키값으로 저장된 값 삭제하기
session.removeAttribute("nick");
%>
<p>로그아웃 되었습니다.</p>
<a href="${pageContext.request.contextPath }/">인덱스로 가기</a>
</body>
</html>
.setMaxInactiveInterval(); : 세션의 유효시간 지정! 들어가는 int값은 초 단위로 입력한다.
- removeAtrribute : 세션 값 삭제하기
- 로그아웃하기 를 클릭하면 이 페이지가 생성되고,
- 저장했던 이름 '바나나'가 삭제되어 있다.
.setMaxInactiveInterval(60);
- 이 페이지에서 다른 동작 없이 60초간 가만히 있으면 삭제된다.
.invalidate : 세션 초기화 기능.
- 만약 여러개의 닉네임을 저장할 수 있다면,
그 여러개의 닉네임을 하나하나 지정하지 않고 한번에 삭제할 수 있다.
- 서버는 불특정다수의 수많은 닉네임을 어떻게 다 따로따로 기억하고 있을까?
→ 브라우저로 구분된다. 어떤 웹브라우저가 어떤 닉네임을 저장했는지 기억하고 있는 것.
- 크롬/edge 로 각각 열어보면, 같은 경로의 페이지임에도 크롬에서 저장한 내용은 다른 브라우저에서는 나오지 않는다.
- session 으로 로그인, 로그아웃 기능 구현할 예정!
- 같은 작업 servlet으로 해보기
- 프로젝트에서 우클릭-Java EE Tools-Generate Deplyment~ 에서 web.xml 을 생성한다.
<web.xml> 수정한 파일
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" version="4.0">
<display-name>Step03_Scope</display-name>
<!-- /Step03_Scope/ 경로(최상위) 요청을 했을 때 응답할 페이지 목록 -->
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
<!-- 서블릿이 어디 있는지 알리면서 이름 부여하기(서블릿 정의) -->
<servlet>
<servlet-name>saveServlet</servlet-name>
<servlet-class>test.servlet.SaveServlet</servlet-class>
</servlet>
<!-- 어떤 이름의 서블릿이 어떤 패턴의 요청을 처리할지 지정하기(서블릿 맵핑) -->
<servlet-mapping>
<servlet-name>saveServlet</servlet-name>
<url-pattern>/test/save</url-pattern>
</servlet-mapping>
</web-app>
- index.jsp 이외에는 삭제한다.
- 저 부분은 최상위 경로까지만 입력해도 index.jsp가 나오도록 하는 기능이다.
- servers 폴더에 전체용 web.xml도 있다. 프로젝트별로 override하여 설정하는 것.
- xml을 로딩해서 앱의 동작에 반영. 시작될때 실행된다.
- 이미 양식, 형식은 정해져 있다. 새로 무언가를 작성하기 쉽지 않다.
- ctrl+space 해서 servlet을 선택해 준다.
(안에 덜 작성하면 오류로 인지되어 밑줄 발생함)
- Apache Tomcat Server에 'saveServlet'이라는 서블릿의 이름과 위치를 알리는 역할!
- 어떤 요청을 처리할지 지정하는 것. 이것을 servlet을 매핑한다고 한다.
- 어떤 요청이 들어왔을 때 이 서블릿을 작동하게 할것인지 설명해주는 것!
<SaveServlet> 생성
package test.servlet;
import java.io.IOException;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
/*
* @WebServlet("/test/save") 어노테이션 설정 대신에
* /WEB-INF/web.xml 문서에 아래의 설정으로 대체할 수 있다.
*
* <servlet>
<servlet-name>saveServlet</servlet-name>
<servlet-class>test.servlet.SaveServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>saveServlet</servlet-name>
<url-pattern>/test/save</url-pattern>
</servlet-mapping>
*/
public class SaveServlet extends HttpServlet{
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//폼 전송되는 닉네임을 읽어와서
req.setCharacterEncoding("utf-8");
String nick=req.getParameter("nick");
//session scope에 "nick"이라는 키값으로 저장하기
HttpSession session=req.getSession(); //HttpServletRequest객체의 메소드를 활용해서 HttpSession얻어내기
session.setAttribute("nick", nick);
session.setMaxInactiveInterval(60);
//응답을 위임하기
RequestDispatcher rd=req.getRequestDispatcher("/WEB-INF/views/test/save.jsp");
rd.forward(req, resp);
}
}
- 여기서는 세션이라는 지역변수가 없기 때문에 사용할 수 없다.
- .getsession 메소드를 사용해서 Session에 들어있는 값을 읽어온다.
HttpSession session=req.getSession();
- HttpServletRequest 객체의 메소드를 활용해서 HttpSession 얻어내기
- jsp가 아닌 servlet으로 작성하려면 좀 번거롭다 ㅎㅎ
/WEB-INF/views/test/ <save.jsp>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>/WEB-INF/views/test/save.jsp</title>
</head>
<body>
<%
String nick=(String)session.getAttribute("nick");
%>
<p><strong><%=nick %></strong>이라는 닉네임을 기억하겠습니다.</p>
<p> 30분 동안 아무런 요청을 하지 않거나 웹브라우저를 닫으면 자동 삭제 됩니다.</p>
<a href="../index.jsp">인덱스로 이동하기</a>
</body>
</html>
- 현재 주소창에 찍히는 위치는 test/save이다.
그렇기 때문에 ../ 를 입력하면 /Step03_Scope/ 로 경로가 지정된다.
- 실제 test 폴더에서 index.jsp 페이지는 .../ 으로 3칸 상위폴더로 올라가야 한다.
- 하지만 ../ 로만 입력해도 index.jsp 로 이동한다.
→ forward 된 경로와 무관하게, 현재 주소창에서 보여주는 경로에 위치해 있다고 보아야 한다.
- forward된 jsp페이지는 주소창과는 완전히 다른 위치에 있다!
'국비교육(22-23)' 카테고리의 다른 글
31일차(1)/jsp(11) : 회원가입, 로그인 기능 구현하기 (0) | 2022.11.21 |
---|---|
[참고] Eclipse에 Quantum DB 설치 (0) | 2022.11.21 |
30일차(1)/jsp(9) : Request Scope (0) | 2022.11.18 |
29일차(2)/CSS(6) : bootstrap CSS 적용하기 (0) | 2022.11.17 |
29일차(1)/jsp(8) : DBCP활용 예제 (todo 테이블) (0) | 2022.11.17 |