

1. 세션 실습 (1)

위 그림과 같이 프로그램을 짜 볼 것이다.
boardList.jsp
<java />
<%@ page language="java" contentType="text/html; charset=UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>fastcampus</title>
<link rel="stylesheet" href="<c:url value='/css/menu.css'/>">
</head>
<body>
<div id="menu">
<ul>
<li id="logo">fastcampus</li>
<li><a href="<c:url value='/'/>">Home</a></li>
<li><a href="<c:url value='/board/list'/>">Board</a></li>
<li><a href="<c:url value='/login/login'/>">login</a></li>
<li><a href="<c:url value='/register/add'/>">Sign in</a></li>
<li><a href=""><i class="fas fa-search small"></i></a></li>
</ul>
</div><div style="text-align:center">
<h1>This is BOARD</h1>
<h1>This is BOARD</h1>
<h1>This is BOARD</h1>
<h1>This is BOARD</h1>
<h1>This is BOARD</h1>
</div>
</body>
</html>
BoardControllaer.java
<java />
package com.fastcampus.ch2;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
@RequestMapping("/board")
public class BoardController {
@GetMapping("/list")
public String list(HttpServletRequest request) {
if(!loginCheck(request)) { //loginCheck가 true가 아니라면
return "redirect:/login/login"; //login을 안했으면 login 화면으로 이동
}
return "boardList"; //login을 했으면 게시판 화면으로 이동
}
private boolean loginCheck(HttpServletRequest request) {
//1.세션을 얻어서
HttpSession session = request.getSession();
//2.세션에 id가 있는지 확인
// if(session.getAttribute("id")!=null)
// return true;
// else
// return false;
return session.getAttribute("id")!=null; //null이 아니면 true, null이면 false
}
}
로그인을 안하면 로그인 화면으로,
로그인을 하면 게시판 화면으로 갈 수 있도록 로직을 짰다.
LoginController.java
<java />
package com.fastcampus.ch2;
import java.net.URLEncoder;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
@RequestMapping("/login")
public class LoginController {
@GetMapping("/login")
public String loginForm() {
return "loginForm";
}
@PostMapping("/login")
public String login(String id,String pwd,boolean rememberId,
HttpServletRequest request,
HttpServletResponse response) throws Exception {
//1. 아이디와 패스워드 확인
//2-1. 일치하지 않으면 loginForm으로 이동
if (!loginCheck(id,pwd)) {
String msg=URLEncoder.encode("id 또는 pwd가 일치하지 않습니다.","utf-8");
return "redirect:/login/login?msg="+msg;
}
//2-2. 아이디와 패스워드가 일치하면,
//세션 객체를 얻어오기
HttpSession session = request.getSession();
// 세션 객체에 id를 저장
session.setAttribute("id", id);
if(rememberId) {
//쿠키를 생성
// 1. 쿠키를 생성
Cookie cookie =new Cookie("id",id);
// 2. 응답에 저장
response.addCookie(cookie);
}else {
//쿠키를 삭제
Cookie cookie =new Cookie("id",id);
cookie.setMaxAge(0);
response.addCookie(cookie);
}
// 3. 홈으로 이동
return "redirect:/";
}
private boolean loginCheck(String id, String pwd) {
return "asdf".equals(id) && "1234".equals(pwd);
}
}
세션 객체를 얻어오고 세션 객체에 id를 저장하는 로직을 추가했다.
이제 로그인을 하면, 홈 화면은 물론 게시판 화면으로 들어갈 수 있다.
로그아웃 기능 추가
<java />
@GetMapping("/logout")
public String logout(HttpSession session) {
//1.세션을 종료
session.invalidate();
//2.홈으로 이동
return "redirect:/";
}
index.jsp 수정
login하면 메뉴판의 login이 logout으로 바뀌어야 하니까,
바뀌어야하는 부분을 변수로 바꾼다.
<java />
<div id="menu">
<ul>
<li id="logo">fastcampus</li>
<li><a href="<c:url value='/'/>">Home</a></li>
<li><a href="<c:url value='/board/list'/>">Board</a></li>
<li><a href="<c:url value='/login/login'/>">login</a></li>
<li><a href="<c:url value='/register/add'/>">Sign in</a></li>
<li><a href=""><i class="fas fa-search small"></i></a></li>
</ul>
</div>
<java />
<div id="menu">
<ul>
<li id="logo">fastcampus</li>
<li><a href="<c:url value='/'/>">Home</a></li>
<li><a href="<c:url value='/board/list'/>">Board</a></li>
<li><a href="<c:url value='${loginOutLink}'/>">${loginOut}</a></li>
<li><a href="<c:url value='/register/add'/>">Sign in</a></li>
<li><a href=""><i class="fas fa-search small"></i></a></li>
</ul>
</div>
전체 코드
<java />
<%@ page language="java" contentType="text/html; charset=UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<c:set var="LoginOutLink" value="${sessionScope.id=null ? '/login/login' : 'login/logout'}"/>
<c:set var="LoginOut" value="${sessionScope.id=null ? 'Login' : 'Logout'}"/>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>fastcampus</title>
<link rel="stylesheet" href="<c:url value='/css/menu.css'/>">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.8.2/css/all.min.css"/>
</head>
<body>
<div id="menu">
<ul>
<li id="logo">fastcampus</li>
<li><a href="<c:url value='/'/>">Home</a></li>
<li><a href="<c:url value='/board/list'/>">Board</a></li>
<li><a href="<c:url value='${LoginOutLink}'/>">${LoginOut}</a></li>
<li><a href="<c:url value='/register/add'/>">Sign in</a></li>
<li><a href=""><i class="fas fa-search small"></i></a></li>
</ul>
</div>
<div style="text-align:center">
<h1>This is HOME</h1>
<h1>This is HOME</h1>
<h1>This is HOME</h1>
</div>
맨 위 세 번째 줄부터,
삼항 연산자로 로직을 추가해주었다.
게시판에서, 로그인을 클릭하고 로그인을 하면 홈 화면으로 움직인다.
로그인을 하면 원래 있던 곳(게시판)에 있는 것이 편하니
로직을 바꿔준다.

PerformanceFilter.java를 고친다.
형변환 작업을 하고,
어디서, 어떤 메소드로 요청했는 지 알 수 있다.
<java />
// 필터를 적용할 요청의 패턴 지정 - 모든 요청에 필터를 적용.
@WebFilter(urlPatterns="/*")
public class PerformanceFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
// 초기화 작업
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
// 1. 전처리 작업
long startTime = System.currentTimeMillis();
// 2. 서블릿 또는 다음 필터를 호출
chain.doFilter(request, response);
// 3. 후처리 작업
//형변환 작업
HttpServletRequest req = (HttpServletRequest)request;
String referer = req.getHeader("referer"); //어디서 요청했는지 알수있음
String method=req.getMethod(); //어떤 메소드로 요청했는지 알 수 있음
System.out.print("["+referer+"]->"+method+"["+req.getRequestURI()+"]"); //어디서 어디로 요청을 보내는 지 알 수 있음
System.out.println(" 소요시간="+(System.currentTimeMillis()-startTime)+"ms");
}
@Override
public void destroy() {
// 정리 작업
}
}


"board/list"라는 정보를 로그인 화면까지는 GET으로 보내고,
로그인 화면에 hidden form을 만들어서 "board/list"라는 정보가
LoginController에 같이 닿을 수 있도록 한번 만들어보겠습니다
<java />
@Controller
@RequestMapping("/board")
public class BoardController {
@GetMapping("/list")
public String list(HttpServletRequest request) {
if(!loginCheck(request)) { //loginCheck가 true가 아니라면
return "redirect:/login/login?toURL="+request.getRequestURL(); //login화면에 GET방식으로 데이터를 주는 것
}
return "boardList"; //login을 했으면 게시판 화면으로 이동
}
private boolean loginCheck(HttpServletRequest request) {
//1.세션을 얻어서
HttpSession session = request.getSession();
//2.세션에 id가 있는지 확인
// if(session.getAttribute("id")!=null)
// return true;
// else
// return false;
return session.getAttribute("id")!=null; //null이 아니면 true, null이면 false
}
}
login 화면에 GET방식으로 데이터를 주었으니
loginForm.jsp로 이동한다.
아이디와 비밀번호 아래에
한 칸을 더 만들어주고,
어디로 이동할 지에 대한 데이터를 넣어준다.
<java />
<input type="text" name="id" value="${cookie.id.value}" placeholder="이메일 입력" autofocus>
<input type="password" name="pwd" placeholder="비밀번호">
<input type="text" name="toURL" value="${param.toURL}">
<button>로그인</button>
다시 로그아웃 한 상태로
게시판에 이동하려고 하니 아래와 같이 뜬다.


<java />
<input type="text" name="id" value="${cookie.id.value}" placeholder="이메일 입력" autofocus>
<input type="password" name="pwd" placeholder="비밀번호">
<input type="hidden" name="toURL" value="${param.toURL}">
<button>로그인</button>
text에서 hidden으로 바꿔준다.
이제 값을 받는 쪽이 LoginController이다.
<java />
@PostMapping("/login")
public String login(String id,String pwd,boolean rememberId,
HttpServletRequest request, String toURL,
HttpServletResponse response) throws Exception {
//1. 아이디와 패스워드 확인
//2-1. 일치하지 않으면 loginForm으로 이동
if (!loginCheck(id,pwd)) {
String msg=URLEncoder.encode("id 또는 pwd가 일치하지 않습니다.","utf-8");
return "redirect:/login/login?msg="+msg;
}
//2-2. 아이디와 패스워드가 일치하면,
//세션 객체를 얻어오기
HttpSession session = request.getSession();
// 세션 객체에 id를 저장
session.setAttribute("id", id);
if(rememberId) {
//쿠키를 생성
// 1. 쿠키를 생성
Cookie cookie =new Cookie("id",id);
// 2. 응답에 저장
response.addCookie(cookie);
}else {
//쿠키를 삭제
Cookie cookie =new Cookie("id",id);
cookie.setMaxAge(0);
response.addCookie(cookie);
}
// 3. 홈으로 이동
toURL = toURL==null || toURL.equals("") ? "/" : toURL;
//toURL의 값이 제대로 넘어오지 않는다면 (null이거나, 빈 문자열이면) 홈으로 가게 하고 그렇지 않으면 toURL로
return "redirect:"+toURL;
}
맨 아래의 코드 수정 : 매번 홈으로 이동하게 했지만, 이번에는 toURL로 넘어온 데이터로 redirect 하게 한다.
세션 유지기간이 짧아야하므로,
홈, 로그인화면에서는 세션을 시작할 필요가 없으므로
id와 pwd를 판단하는 화면에서부터 세션을 시작하게 한다.

true일 때는 세션 있을 때, (세션 없을 때 세션을 생성함)
false일 때는 세션 없을 때 (세션 없을 때 세션을 새로 생성하지 않음)
라는 뜻이다.
1. 세션이 필요없는 JSP 화면에는 session=false
2. session=false가 기존 세션에 영향을 끼치지 않는다.
session=true일 때 session=false를 만나면 세션을 새로 생성하지 않을 뿐이다.
true와 false는 세션을 시작할지, 말지에 대한 답일 뿐이다.
index.jsp로 이동

index.jsp와 loginForm.jsp 위에
<java />
<%@ page session="false" %>
을 추가한다.
결과 :
홈 화면에서 아무리 새로고침을 눌러도 JSESSONID가 생기지 않는다.
<java />
@PostMapping("/login")
public String login(@CookieValue("id") String cookieId,
String id,String pwd,boolean rememberId,
HttpServletRequest request, String toURL,
HttpServletResponse response) throws Exception {
CookieValue라는 어노테이션은
Cookie중에 id라는 cookie값을 읽어 cookieId에 넣어준다는 뜻이다.
쿠키 값을 읽어오는데 어노테이션을 사용할 수도 있다!
본 포스팅은 패스트캠퍼스 환급 챌린지 참여를 위해 작성되었습니다.
패스트캠퍼스 [직장인 실무교육]
프로그래밍, 영상편집, UX/UI, 마케팅, 데이터 분석, 엑셀강의, The RED, 국비지원, 기업교육, 서비스 제공.
fastcampus.co.kr
'패캠 챌린지' 카테고리의 다른 글
패스트캠퍼스 챌린지 - 22일차 [스프링의 정석:남궁성과 끝까지 간다] (1) | 2023.03.13 |
---|---|
패스트캠퍼스 챌린지 - 21일차 [스프링의 정석:남궁성과 끝까지 간다] (0) | 2023.03.12 |
패스트캠퍼스 챌린지 - 19일차 [스프링의 정석:남궁성과 끝까지 간다] (0) | 2023.03.10 |
패스트캠퍼스 챌린지 - 18일차 [스프링의 정석:남궁성과 끝까지 간다] (2) | 2023.03.09 |
패스트캠퍼스 챌린지 - 17일차 [스프링의 정석:남궁성과 끝까지 간다] (0) | 2023.03.08 |