딸기말차
[Java web] 4. Session, JSP tag 본문

엔코아 플레이데이터(Encore Playdata) Backend 2기 백엔드 개발 부트캠프 (playdata.io)
백엔드 개발 부트캠프
백엔드 기초부터 배포까지! 매력있는 백엔드 개발자 포트폴리오를 완성하여 취업하세요.
playdata.io
1. 복습
1. Text 기반 문서 (HTML & CSS & XML)
해당 문서들은 text 기반이기 때문에 오타를 찾지 못한다. 때문에 없는 문법을 사용해도 실행은 되지만, 실행결과에 오류가 발생한다.
HTML과 CSS는 태그명, 속성명, 속성값이 고정되어있다. 즉, 문법화 되어있다. (W3C에서 제정)
반면 XML은 아예 문법화가 되어있지 않다. 오직 <? xml ?> 만 정해져있다.
2. Java web 데이터 전달 방식
기본적으로 전송되는 모든 데이터는 문자열의 형태를 띈다.
1) HTML <-> JSP & HTML <-> Servlet
- form tag
- event 발생 (onclick=location.href("url") & method 내에 document.location = "url")
2) JSP <-> JSP & JSP <-> Servlet & Servlet <-> Servlet
- request 객체에 parameter 값을 전달 (form & request.setParameter)
- request 객체에 attribute 값을 전달 (request.setAttribute & request.getAttribute)
- response.sendRedirect("url")
- forword & include (include는 dispatcher 객체를 jsp로 던지고 다시 반환된다.)
3. error page
<%@ page errorPage="error.jsp"%>
해당 태그 내에 errorPage 속성이 존재한다. errorPage=error.jsp 라고 설정하면, 에러가 나면 해당 에러페이지로 이동한다.
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" errorPage="error.jsp"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>오류 발생한 페이지</title>
</head>
<body>
<%= 5 / 0 %>
</body>
</html>
<%@ page isErrorPage = "true"%>
이동한 에러페이지에 해당 태그가 있어야 해당 에러페이지가 출력된다.
catch문의 exception 출력처럼 출력하기 위해선 <%=exception.toString()%> 으로 출력하면 된다.
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" isErrorPage="true"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>오류가 발생했을 때 이동한 페이지. 예외처리</title>
</head>
<body>
오류 발생 : <%= exception.toString() %>
</body>
</html>
4. include
다른 jsp에서 구현한 페이지를 가져와 삽입할 수 있다.
<%@ include file="파일명.jsp" %>
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>include test</title>
</head>
<body>
<!-- menu.jsp -->
<%@ include file="menu.jsp" %> <br/>
<!-- news.jsp -->
<%@ include file="news.jsp" %> <br/>
<!-- shopping.jsp -->
<%@ include file="shopping.jsp" %>
</body>
</html>
2. Session
session을 정리하기 전에 잠깐 cookie에 대해 정리하자면,
cookie는 웹 브라우저내에 존재하는 임시 저장소이다. 때문에 사용하기 위해선 객체를 만들어야한다. 하지만 cookie는 웹 브라우저 내에 데이터가 쌓이기 때문에 굉장히 위험한 기술이다. 이를 방지하기 위해 session 기술이 만들어졌다.
session은 웹 브라우저가 아니라 우리가 가동하는 application 내의 임시저장소이다. 즉, 서버 내에 데이터가 저장되기 때문에 cookie와 달리 눈으로 확인할 수 없고 직접 가져와봐야 알 수 있다.
session은 내장객체고 기본값이 true기 때문에 jsp파일 내에서 객체를 생성하지 않아도 session.메서드명 이런식으로 바로 접근이 가능하다. 또한, jsp 내에서 session을 사용하고 싶지 않은 경우 <%@ page session="false"%> 로 막을 수도 있다.
그리고 servlet 내에서 session을 사용하기 위해선, HttpSession session = request.getSession(); 이렇게 객체를 선언후 사용해야한다.
* session의 공통 메서드
세션에 데이터 저장 : session.setAttribute("이름", 데이터);
세션의 데이터 추출 : session.getAttribute("이름");
세션 초기화 : session.invalidate();
세션 내의 데이터 삭제 : session.removeAttribute("이름");
세션의 수명 지정 : session.setMaxInactiveInterval(초단위);
현재 세션의 수명 추출 : int time = session.getMaxInactiveInterval();
session의 실습을 위해 간단한 로그인페이지를 만들어 보았다.
우선, login.jsp에서 form 태그를 통해 logCheck servlet으로 데이터를 전송한다.
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>login</title>
</head>
<body>
<form action="logCheck" method="post">
<label>아이디 : </label><input type="text" name="ID" maxlength="10" required="required"> <br/>
<label>비밀번호 : </label><input type="password" name = "PW" maxlength="10" required="required"> <br/>
<input type="submit" value="로그인">
</form>
</body>
</html>
LogCheck Servlet의 구조는 다음과 같다.
1. 전달받은 ID, PW 값이 저장 된 데이터와 같다면 session 객체 내에 user를 저장 후 main.jsp로 redirect 한다.
2. 하지만 이 때 전달받은 값이 기존 데이터와 다르다면, login.jsp로 다시 돌아간다.
@WebServlet("/logCheck")
public class LogCheck extends HttpServlet {
private static final long serialVersionUID = 1L;
private final String id = "admin";
private final String pw = "1234";
private final String user = "관리자";
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setCharacterEncoding("UTF-8");
HttpSession session = request.getSession();
session.setMaxInactiveInterval(5);
if (id.equals(request.getParameter("ID")) && pw.equals(request.getParameter("PW"))) {
session.setAttribute("user", user);
response.sendRedirect("main.jsp");
}
else {
response.sendRedirect("login.jsp");
}
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}
main.jsp는 우선 session 내에 저장 된 user 데이터를 가져온다.
그리고 해당 데이터가 null이 아니면 로그인 완료와 로그아웃 버튼을 표시하고, null이면 다시 login.jsp로 돌아간다.
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>로그인 메인페이지</title>
</head>
<body>
<%if(session.getAttribute("user") == null) {
response.sendRedirect("login.jsp");
}
else {%>
<%=session.getAttribute("user")%> 님이 접속되었습니다.
<form action="logout.jsp" method="post">
<input type="submit" value="로그아웃">
</form>
<%}%>
</body>
</html>
main.jsp에서 로그아웃 버튼을 눌러 logout.jsp로 넘어왔다면, session.invalidate()를 실행해 session을 초기화 시켜 user 데이터를 삭제시킨다.
삭제가 되면, user 데이터가 null이 되기 때문에 main.jsp로 접근해도 login.jsp로 redirect 하게 된다.
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>logout</title>
</head>
<body>
<%session.invalidate(); // session 값을 없애는 메서드%>
<script type="text/javascript">
alert("로그아웃 되었습니다.")
document.location = "login.jsp";
</script>
</body>
</html>
3. JSP tag_1) include
JSP 내에는 편의를 위해 여러 내장 태그들이 존재한다. 해당 태그들은 <jsp:태그명> 이렇게 사용할 수 있다.
include 태그는 가져오는 페이지를 컴파일 하지 않고 가져오기 때문에 변화감지가 되지않고, 정적인 페이지를 가져올 때 주로 사용한다.
* 디렉티브(<%@ %>) include
가져오는 페이지를 컴파일 하고 가져오기 때문에 변화가 잦은 동적인 페이지를 가져올 때 주로 사용한다.
* include 태그의 flush 속성
컴파일 결과를 저장하는 영역. 저장한 결과를 어떻게 처리할 지 결정할 수 있다.
include 태그로 해당 페이지에가서 결과를 return 받으면, include를 실행한 곳으로 돌아오는게 아니라 페이지의 최상단으로 돌아온다. 때문에 flush를 통해 저장 후 사용해야 원하는 위치에서 해당 결과를 사용할 수 있게된다.
include 태그의 실습을 위해, 데이터를 입력받아 전달하는 form을 만들어보았다.
우선, include_action2.jsp에서 form 태그를 통해 데이터를 include_action.jsp로 전달하였다.
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>include action2.jsp : 입력화면</title>
</head>
<body>
<form action="include_action.jsp" method="post">
<input type="text" name="strID" />
<input type="password" name="strPW" />
<input type="submit" value="전송" />
</form>
</body>
</html>
include_action.jsp에선 전달받은 데이터를 include 태그 내부 param 태그의 value로 사용해, footer.jsp로 전달해 주었다.
참고로 param 태그는, URL?"데이터명"="값" 과같이 get 방식을 사용하는 것과 유사하다.
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>include action.jsp</title>
</head>
<body>
<hr>
<jsp:include page="footer.jsp">
<jsp:param value="<%=request.getParameter(\"strID\") %>" name="strID"/>
<jsp:param value="<%=request.getParameter(\"strPW\") %>" name="strPW"/>
</jsp:include>
<hr>
</body>
</html>
마지막으로 footer.jsp에선 전달받은 데이터를 출력해주었다.
여기서 중요한 점은, 우리는 footer.jsp로 데이터를 전달해주긴 했지만 URL이 footer.jsp로 이동한 것이 아니라는 점이다.
footer.jsp의 코드를 include_action.jsp 내로 include 해온 것이기 때문에, URL은 변동없이 그대로 include.jsp이다.
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>footer.jsp 전달 받은 값 출력</title>
</head>
<body>
아이디 : <%= request.getParameter("strID") %>
비밀번호 : <%= request.getParameter("strPW") %>
</body>
</html>
4. JSP tag_2) forward
forward 태그는 include 태그와 달리 해당 jsp 파일로 직접 가서 코드를 실행시킨다.
즉, include 태그는 해당 jsp 파일 내의 코드를 가져와 기존 jsp 파일에 추가하는 개념이지만, forward 태그는 기존 jsp 파일 내에서 forward 태그를 만나면 해당 jsp 파일의 코드로 넘어가 실행된다.
이 때 유의할 점은, 실제로 페이지가 넘어가는게 아니라 해당 jsp로 가서 코드만 실행시키는 것이기 때문에 URL은 바뀌지 않는다.
forward 태그의 실습을 위해, 데이터를 입력받아 전달하는 form을 만들어보았다.
우선, bloodtype.jsp에서 form 태그를 통해 데이터를 result.jsp로 전달하였다.
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>bloodtype.jsp</title>
</head>
<body>
<form action="result.jsp" method="post">
이름 : <input type="text" name="name" required="required"> <br>
혈액형 선택 : <br>
<input type="radio" name="bloodtype" value="a"> A형 <br>
<input type="radio" name="bloodtype" value="b"> B형 <br>
<input type="radio" name="bloodtype" value="ab"> AB형 <br>
<input type="radio" name="bloodtype" value="o"> O형 <br>
<input type="submit" value="전송">
</form>
</body>
</html>
result.jsp에선 전달받은 데이터에 ".jsp"를 더해, forward 태그 내부 param 태그의 value로 사용하여 해당 jsp로 값을 전달해 주었다.
forward 태그의 특징은 request 객체를 공유한다는 점이다. 때문에 forward 태그 내 param 태그에 굳이 value를 입력하지 않더라도, bloodtype.jsp에서 전달받은 request 객체를 그대로 a.jsp, b.jsp, ab.jsp, o.jsp로 전달해준다.
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>result.jsp : 선택한 혈액형 파일 forward</title>
</head>
<body>
<%request.setCharacterEncoding("UTF-8");%>
<jsp:forward page="<%=request.getParameter(\"bloodtype\") + \".jsp\"%>">
<jsp:param value="" name=""/>
</jsp:forward>
</body>
</html>
위에 서술한 forward의 특징 때문에, <jsp:param> 의 value에 아무런 값이 없어도 request.getAttribute로 값을 추출해 사용할 수 있다.
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>a</title>
</head>
<body>
<%=request.getParameter("name")%> 님의 혈액형은 <br/>
<%=request.getParameter("bloodtype")%> 이고, 성실, 신중, 완벽주의자
</body>
</html>
8. 16일차 후기
대부분의 웹 페이지에는 로그인 기능이 존재한다. 로그인 기능에 session은 빠질 수 없기 때문에, session의 사용법은 반드시 숙지하고 있어야 한다.
때문에 곧 시작할 두 번째 미니프로젝트에 로그인 기능을 구현해, session을 다루는 연습을하여 앞으로 모든 웹 페이지 개발 작업에서 능숙히 사용할 수 있으면 좋겠다는 생각을 했다.
'Bootcamp > Java web' 카테고리의 다른 글
| [Java web] 6. Mini Project_2 (0) | 2023.07.22 |
|---|---|
| [Java web] 5. EL, JSTL, Java Beans (1) | 2023.07.18 |
| [Java web] 3. Servlet 실습 (0) | 2023.07.14 |
| [Java web] 2. JSP 실습 (0) | 2023.07.13 |
| [Java web] 1. Servlet, JSP (0) | 2023.07.12 |