본문 바로가기
수업내용

20230531 수업내용2🫡🫡🫡

by titlejjk 2023. 5. 31.

이번 수업은 jsp는 마지막 수업으로 로그인/로그아웃/게시판 등등 기본적으로 다른 홈페이지에서 쓸수 있는 기능들을 구현해보는 수업이다.

여지껏 배운 것들을 모두 복습한다는 느낌으로..

데이터베이스 연동을 위한 준비를 먼저 해주고 이번 프로젝트에서 사용할 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>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha3/dist/css/bootstrap.min.css" />
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/js/bootstrap.bundle.min.js" integrity="sha384-kenU1KFdBIe4zVF0s0G1M5b4hcpxyD9F7jL+jjXkk+Q2h455rYXK/7HAuoJl+0I4" crossorigin="anonymous"></script>
</head>
<body>
	<div class="container">
		<h1>인덱스 페이지 입니다.</h1>
		<ul>
			<li><a href="${pageContext.request.contextPath}/users/signup_form.jsp">회원가입</a></li>
		</ul>
	</div>
</body>
</html>

style bootstrap css/js도 연결해주고

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>/users/signup_form.jsp</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha3/dist/css/bootstrap.min.css" />
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/js/bootstrap.bundle.min.js" integrity="sha384-kenU1KFdBIe4zVF0s0G1M5b4hcpxyD9F7jL+jjXkk+Q2h455rYXK/7HAuoJl+0I4" crossorigin="anonymous"></script>
</head>
<body>
	   <div class="container">
      <h3>회원 가입 폼 입니다.</h3>
      <form action="signup.jsp" method="post" id="signupForm">
         <div>
            <label class="control-label" for="id">아이디</label>
            <input class="form-control" type="text" name="id" id="id"/>
            <small class="form-text text-muted">영문자 소문자로 시작하고 5글자~10글자 이내로 입력하세요</small>
            <div class="valid-feedback">사용 가능한 아이디 입니다.</div>
            <div class="invalid-feedback">사용할 수 없는 아이디 입니다.</div>
         </div>
         
         <div>
            <label class="control-label" for="pwd">비밀번호</label>
            <input class="form-control" type="password" name="pwd" id="pwd"/>
            <small class="form-text text-muted">특수 문자를 하나 이상 조합하세요.</small>
            <div class="invalid-feedback">비밀 번호를 확인 하세요</div>
         </div>
         <div>
            <label class="control-label" for="pwd2">비밀번호 확인</label>
            <input class="form-control" type="password" name="pwd2" id="pwd2"/>
         </div>
         
         <div>
            <label class="control-label" for="email">이메일</label>
            <input class="form-control" type="text" name="email" id="email"/>
            <div class="invalid-feedback">이메일 형식에 맞게 입력하세요.</div>
         </div>
         <button class="btn btn-outline-primary" type="submit">가입</button>
      </form>
   </div>
</body>
</html>

기본적인 signup_form.jsp도 만들어 주었다.

위에 만들어진 폼의 양식대로 입력된 정보들을 데이터베이스에 저장할  signup.jsp도 만들어보겠다,

//요청 인코딩 설정
	request.setCharacterEncoding("utf-8");
	//1. 폼 전송되는 회원 가입정보를 읽어와서
	String id = request.getParameter("id");
	String pwd = request.getParameter("pwd");
	String email = request.getParameter("email");
	//2.Dto에 담아서
	
	//3.Dao를 이용해서 DB 에 저장하고
	
	//4.응답한다.

로 먼저 작성해준다.

그런다음 이클립스내에 WEB-INF에 table.sql 이라는 이름으로 SQL파일을 생성한 후에

와 같이 새로운 table을 만들어 주었다.

그 다음으로 test.users.dto/dao를 만들어 준다.

그 후 UserDto.java를 만들어 준후에 위에 테이블에 사용할 getter/setter와 생성자를 만들어준다.

package test.users.dto;

public class UsersDto {
	
	private String id;
	private String pwd;
	private String email;
	private String profile;
	private String regdate;
	
	public UsersDto(String id, String pwd, String email, String profile, String regdate) {
		super();
		this.id = id;
		this.pwd = pwd;
		this.email = email;
		this.profile = profile;
		this.regdate = regdate;
	}

	public String getId() {
		return id;
	}

	public void setId(String id) {
		this.id = id;
	}

	public String getPwd() {
		return pwd;
	}

	public void setPwd(String pwd) {
		this.pwd = pwd;
	}

	public String getEmail() {
		return email;
	}

	public void setEmail(String email) {
		this.email = email;
	}

	public String getProfile() {
		return profile;
	}

	public void setProfile(String profile) {
		this.profile = profile;
	}

	public String getRegdate() {
		return regdate;
	}

	public void setRegdate(String regdate) {
		this.regdate = regdate;
	}

	public UsersDto() {}
}

그 다음 dao를 만들어주는데 외부에서 객체 생성 불가하게 만들어주고 참조값을 리턴해주는 static메소드도 같이 만들어주는 코드를 작성했다.

package test.users.dao;

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

import test.users.dto.UsersDto;
import test.util.DbcpBean;

public class UsersDao {
	
	private static UsersDao dao;
	//외부에서 객체 생성할 수 없도록
	private UsersDao() {}
	//참조값을 리턴해주는 static 메소드
	public static UsersDao getInstance() {
		if(dao == null) {
			dao = new UsersDao();
		}
		return dao;
	}
	
	//회원 한명의 정보를 DB에 저장하고 성공여부를 리턴하는 메소드
	public boolean insert(UsersDto dto) {
		Connection conn = null;
		PreparedStatement pstmt = null;
		ResultSet rs = null;
		int rowCount = 0;
		try {
			//DbcpBean 객체를 이용해서 Connection 객체를 얻어온다(Connection Pool 에서 얻어오기)
			conn = new DbcpBean().getConn();
			//실행할 sql 문 
			String sql = "INSERT INTO users"
					+ " (id, pwd, email, regdate)"
					+ " VALUES(?, ?, ?, SYSDATE)";
			pstmt = conn.prepareStatement(sql);
			//sql 문이 미완성이라면 여기서 완성
			pstmt.setString(1, dto.getId());
			pstmt.setString(2, dto.getPwd());
			pstmt.setString(3, dto.getEmail());
			//select 문 수행하고 결과값 받아오기
			rowCount = pstmt.executeUpdate();
			//반복문 돌면서 ResultSet 에 담긴 내용 추출
		} catch (SQLException se) {
			se.printStackTrace();
		} finally {
			try {
				if (pstmt != null)
					pstmt.close();
				if (conn != null)
					conn.close();
			} catch (Exception e) {
			}
		}
		//만일 변화된 row 의 갯수가 0 보다 크면 작업 성공
		if(rowCount > 0) {
			return true;
		}else {
			return false;
		}

	}

}

이렇게 dao를 만든후 다시 signup.jsp로가서..

	//요청 인코딩 설정
	request.setCharacterEncoding("utf-8");
	//1. 폼 전송되는 회원 가입정보를 읽어와서
	String id = request.getParameter("id");
	String pwd = request.getParameter("pwd");
	String email = request.getParameter("email");
	//2.Dto에 담아서
	UsersDto dto = new UsersDto();
	dto.setId(id);
	dto.setPwd(pwd);
	dto.setEmail(email);
	//3.Dao를 이용해서 DB 에 저장하고
	boolean isSuccess = UsersDao.getInstance().insert(dto);
	//4.응답한다.

폼 전송되는 회원 가입정보를 읽어와서 dto에 담고 dao를 이용해 db에 저장하는 기본틀을 만들어준다.

이렇게 만들어진 웹에서 회원가입페이지에서 정보를 입력하면 아래와 같이 db에 저장이 된다.

다음은 login 폼을 만들러가보겠다.

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>/users/loginform.jsp</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha3/dist/css/bootstrap.min.css" />
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/js/bootstrap.bundle.min.js" integrity="sha384-kenU1KFdBIe4zVF0s0G1M5b4hcpxyD9F7jL+jjXkk+Q2h455rYXK/7HAuoJl+0I4" crossorigin="anonymous"></script>
</head>
<body>
	<div class = "container">
		<h1>로그인 폼</h1>
		<form action="login.jsp" method = "post"><!-- action은 login.jsp로 method는 post방식으로 -->
			<div>
				<label class = "form-label" for="id">아이디</label>
				<input class = "form-control" type="text" name = "id" id = "id"/>
			</div>
			<div>
				<label class = "form-label for="pwd">비밀번호</label>
				<input class = "form-control" type="password" name = "pwd" id = "pwd"/>
			</div>
			<button class = "btn btn-primary" type = "submit">로그인</button>
		</form>
	</div>
</body>
</html>

그 다음은 db에서 계정정보를 받아오는 코드를 login.jsp에 작성한다.

login.jsp를 작성할 때에는 다음을 조건으로 작성해볼 것이다.

  1. 폼으로부터 전송되는 id,pwd를 읽어와서
  2. UsersDto에 담고
  3. UsersDao에 전달해서 유요한 정보인지 확인해서
  4. 유효한 정보이면 로그인 처리를 하고 응답한다.
    유효한 정보가 아니면 아이디 혹은 비밀번호가 틀려요 라고 응답한다.

  5. 로그인처리
    session scope에 "id"라는 키값으로 로그인된 아이디를 저장하면된다.
    여기서 session scope란 HttpSession 객체의 setAttribute()메소드를 이용해서 값을 저장하는 영역을 말한다.

먼저 3번의 조회할 메소드를 UsersDao에 만들어준다

  //인자로 전달되는 dto 에 있는 아이디와, 비밀번호를 이용해서 해당 정보가 유효한 정보인지 여부를 리턴하는 메소드 
   public boolean isValid(UsersDto dto) {
      
      //아이디 비밀번호 유효성 여부를 담을 변수 만들고 초기값 false 부여하기
      boolean isValid=false;
      
      //필요한 객체를 담을 지역변수를 미리 만들어 둔다. 
      Connection conn = null;
      PreparedStatement pstmt = null;
      ResultSet rs = null;
      try {
         //Connection Pool 에서 Connection 객체를 하나 얻어온다.
         conn = new DbcpBean().getConn();
         //실행할 sql 문의 뼈대 구성하기
         String sql = "SELECT id"
               + " FROM users"
               + " WHERE id=? AND pwd=?";
         //sql 문의 ? 에 바인딩 할게 있으면 한다
         pstmt = conn.prepareStatement(sql);
         pstmt.setString(1, dto.getId());
         pstmt.setString(2, dto.getPwd());
         //SELECT 문을 수행하고 결과값을 받아온다.
         rs = pstmt.executeQuery();
         //SELECT 된 ROW 가 있는지 확인해 본다.
         if (rs.next()) {
            //SELECT 된 row 가 있다면 유효한 정보가 맞다.
            isValid=true;
         }
      } catch (Exception e) {
         e.printStackTrace();
      } finally {
         try {
            if (rs != null)
               rs.close();
            if (pstmt != null)
               pstmt.close();
            if (conn != null)
               conn.close(); //Connection Pool 에 Connection 반납하기
         } catch (Exception e) {
         }
      }
      return isValid;
   }

여기까지 정리하자면 login.jsp에는

//1. 폼전송되는 id, pwd를 읽어와서
	request.setCharacterEncoding("utf-8");
	String id = request.getParameter("id");
	String pwd = request.getParameter("pwd");
	//2. UserDto에 담아서
	UsersDto dto = new UsersDto();
	dto.setId(id);
	dto.setPwd(pwd);
	//3. UsersDao에 전달해서 유효한 정보인지 확인해서
	boolean isValid = UsersDao.getInstance().isValid(dto);

이렇게 완성되어있다.

이제 4번까지 작성을 다하고 body부분까지 작성을 하면

<%@page import="test.users.dao.UsersDao"%>
<%@page import="test.users.dto.UsersDto"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%
	//1. 폼전송되는 id, pwd를 읽어와서
	request.setCharacterEncoding("utf-8");
	String id = request.getParameter("id");
	String pwd = request.getParameter("pwd");
	//2. UserDto에 담아서
	UsersDto dto = new UsersDto();
	dto.setId(id);
	dto.setPwd(pwd);
	//3. UsersDao에 전달해서 유효한 정보인지 확인해서
	boolean isValid = UsersDao.getInstance().isValid(dto);
	/*
		4.유효한 정보이면 로그인 처리를 하고 응답한다.
		  유효한 정보가 아니면 아이디 혹은 비밀번호가 틀려요 라고 응답한다.
		  
		  [로그인 처리]
		   session scope에 "id"라는 키값으로 로그인된 아이디를 저장하면된다.
		   여기서 session scope란 HttpSession 객체의 setAttribute()메소드를 이용해서
		   값을 저장하는 영역을 말한다.
	*/
	if(isValid){
		//session scope에 id 라는 키값으로 로그인된 아이디 담기
		session.setAttribute("id", id);
	}
%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>/users/login.jsp</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha3/dist/css/bootstrap.min.css" />
</head>
<body>
	<div class = "container">
		<%if(isValid){%>
			<p class = "alert alert-success">
				<strong><%=dto.getId() %></strong>님 로그인되었습니다.
				<a href="${pageContext.request.contextPath}/index.jsp">확인</a>
			</p>
		<%}else{ %>
			<p class = "alert alert-danger">
			아이디 혹은 비밀번호가 틀려요
			<a href="${pageContext.request.contextPath}/users/loginform.jsp">다시시도</a>
			</p>
		<%} %>
	</div>
</body>
</html>

완성!

이렇게 로그인 화면을 완료하였다.

계정과 비밀번호를 다르게 입력해보았다.

이제 로그인 후에 index영역에서 로그인이 되어있는지 알수있는 상태를 만들어보겠다.

위에서 작성한 4번 주석에서 session scope에 "id"라는 키값으로 저장된 문자열을 저장해 두었는데 그걸 읽어오는 코드를 작성하고 로그인을 했다면 null이 아니고 안했다면 null이라는 조건으로 로그인이 되어있는 상태인지 만들어주도록 하였다.

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%
	//session scope 에 "id"라는 키값으로 저장된 문자열이 있는지 읽어와 본다.
	String id = (String)session.getAttribute("id");//login.jsp 에 만들어두었다.
	//로그인을 했다면 null이 아니고 안했다면 null이다.
%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>index.jsp</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha3/dist/css/bootstrap.min.css" />
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/js/bootstrap.bundle.min.js" integrity="sha384-kenU1KFdBIe4zVF0s0G1M5b4hcpxyD9F7jL+jjXkk+Q2h455rYXK/7HAuoJl+0I4" crossorigin="anonymous"></script>
</head>
<body>
	<div class="container">
		<%if(id != null){ %>
			<p>
				<strong><%=id %></strong> 님 어서오고!
				<a href="${pageContext.request.contextPath}/users/logout.jsp">로그아웃</a>
			</p>
		<%} %>
		<h1>인덱스 페이지 입니다.</h1>
		<ul>
			<li><a href = "${pageContext.request.contextPath}/users/signup_form.jsp">회원가입</a></li>
			<li><a href = "${pageContext.request.contextPath}/users/loginform.jsp">로그인</a></li>
		</ul>
	</div>
</body>
</html>

로그인중이라는 멘트!

나중에 session scope에 어떻게 여러명이 동시에 접속되면서 접속된 계정의 id를 가지고 있는지 설명해 주신다하셨다.

이제 로그아웃을 만들러 가야한다...

원리는 생각보다 간단하다.

위에 session scope에 저장되어있는 문자열을 삭제해 주면된다.

이 때 사용된 코드는

session.removeAttribute("id");

이다.

로그아웃!

위에 원리면 서버가준 무언가가 지워지는건데(기본30분정도 대기상태면 정보가 지워진다) 이 session scope에  지워버리는 개념으로 로그아웃이 되는 것 이다.

이렇게 계속 코딩을 만드는데 만들 때마다 인코딩을 설정해주는게 귀찮으니 filter를 만들어보겠다.

request.setCharacterEncoding("utf-8");//귀찮..
package test.filter;

import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter;

/*
 * 요청을 중간에 가로채서 encoding 설정을 해주는 Filter만들기
 */
@WebFilter("/*")// "/*"는 이 프로젝트에 오는 모든 요청에 대해 필터링을 하겠다는 의미
public class EndodingFilter implements Filter{

	@Override
	public void destroy() {
		
	}
	//필터가 동작할때 호출되는 메소드
	@Override
	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
			throws IOException, ServletException {
		//1.만일 인코딩 설정이 되지 않았다면
		if(request.getCharacterEncoding()==null) {
			//POST 방식 전송했을 때 한글 깨짐 방지
			request.setCharacterEncoding("utf-8");
		}
		//2.요청의 흐름 이어가기
		chain.doFilter(request, response);
	}

	@Override
	public void init(FilterConfig filterConfig) throws ServletException {
		
	}

}

 

'수업내용' 카테고리의 다른 글

20230607 수업내용🫡🫡🫡  (0) 2023.06.07
20230601 수업내용🫡🫡🫡  (0) 2023.06.01
20230531 수업내용🫡🫡🫡  (0) 2023.05.31
20230530 수업내용😢😢😢  (0) 2023.05.30
20230526 수업내용👉👉👉  (0) 2023.05.26

댓글