JSP 게시판 만들기 2 - 회원DB구현 및 로그인 구현

2021. 1. 28. 00:08Web/JSP

WebContent 폴더 내에 index.html파일을 생성해 준다. index Page 라는 것은 어떤 웹사이트던지 홈페이지에 처음 접속 했을때 실행되는 홈페이지 라고 할 수 있다.

예를 들어 네이버에도 이렇게 적용해서 들어가도 접속이 된다.

이제 index.jsp를 작성 해 보자 가자;

 

처음 html파일 생성 시에 EUC-KR로 설정이 되어있는데 charset을 UTF-8로 바꿔주자(contentType, pageEncoding)

UTF-8은 최근에 가장 많이 사용되는 국제적인 인코딩 언어이다.

 

(index.jsp)

 

<!-- 기본적인 웹사이트 틀을 잡아주는 부분 charset="언어" -->
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<link rel="stylesheet" href="css/custom.css">
<title>JSP 게시판 웹 사이트</title>
</head>
<body>
	<!-- 1.body tag 내에 script tag 생성 -->
	<script>
			//웹페이지에 접속 시에 강제로 로그인 화면으로 이동 시켜주는 소스 작성
			location.href = 'login.jsp';
	</script>
</body>
</html>

우선 웹페이지가 시작되면 로그인 페이지로 이동할 수 있는 기능을 만들어서 그러고 실행하면~?

현재는 프로젝트를 마친후라서 login.jsp가 정상적으로 실행시 작동을 한다. 처음 작성 한다면 404 - Not Found error가 뜰 것이다. 페이지가 작성이 되지않았기 때문이다.

 

이제 login.jsp를 생성해보자.

실제로 현업에서는 홈페이지를 제작할때 디자인을 먼저 하고, 기능을 맞춰넣는 경우가 많다. 우선 로그인 페이지의 디자인을 먼저 할껀데 이 때 디자인을 더욱 빠르게 하기위해서 디자인 프레임워크bootstrap을 설치해 보자.

여기가 bootstrap 홈페이지 download누르고 드가면

이걸 받으면 되는데 !? 받아보면 영상에서는 css, fonts, js 세가지 파일이 존재하는데 최신버전엔 fonts 파일이 없다. 이유를 보자 하니 부트스트랩이 3버전에서 4버전업 할때 fonts 파일을 삭제했다 더라~

 

 

근데 강의 제작한게 2017년이라 그동안 bootstrap이 버전업을 많이해서 많은게 바뀌어서 완벽히 일치하지않는다. 최신 버전의 부트스트랩은 나중에 document 번역해서 보면서 익히고,

일단은 동빈이형 블로그에 가서 일치하는 bootstrap 버전을 다운로드 한다. bootstrap-3.3.7 버전을 찾아온다. 

사용하기로 한 JSP 폴더에 압축을 풀고 bootstrap-3.3.7 -> dist -> 폴더 세개를 복사해서 

이렇게 WebContent 안에 붙여넣기 하자.

이제 홈페이지 로그인 화면을 그려주는 login.jsp를 작성해 보자~

 

(login.jsp)

<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<!--기본적으로 부트스트랩은 컴퓨터 or 핸드폰 어떤device로 접속하더라도 해상도에 맞게 알아서 설정되는 탬플릿이다. 따라서 간단하게 반응형 웹에 사용되는 메타 태그를 작성해준다.-->
<meta name="viewport" content="width=device-width" , inital-scale="1">
<!--link 태그를 이용해서, stylesheet를 참조선언 해주고, 링크로 css폴더안에 있는 bootstrap.css를 사용해 준다고 명시해준다. jSP내의 디자인 담당-->
<link rel="stylesheet" href="css/bootstrap.css">
<link rel="stylesheet" href="css/custom.css">
<title>JSP 게시판 웹 사이트</title>
</head>
<body>
	<!-- 네비게이션 구현 네비게이션이라는 것은 하나의 웹사이트의 전반적인 구성을 보여주는 역할 -->
	<nav class="navbar navbar-default">
		<!-- header부분을 먼저 구현해 주는데 홈페이지의 로고같은것을 담는 영역이라고 할 수 있다. -->
		<div class="navbar-header">
			<!-- <1>웹사이트 외형 상의 제일 좌측 버튼을 생성해준다. data-target= 타겟명을 지정해주고-->
			<button type="button" class="navbar-toggle collapsed"
				data-toggle="collapse" data-target="#bs-example-navbar-collapse-1"
				aria-exmaple="false">
		<!-- 이건 모바일 화면으로 볼때, 요약된 메뉴 목록에 줄을 그려주는부분 그림에서 설명 *1* 별건없고 단지 꾸며주는 용도-->
				<span class="icon-bar"></span>
				<span class="icon-bar"></span>
				<span class="icon-bar"></span>
			</button>
			<!-- 여긴 웹페이지의 로고 글자를 지정해준다. 클릭 시 main.jsp로 이동하게 해주는게 국룰 -->
			<a class="navbar-brand" href="main.jsp">JSP 게시판 웹 사이트</a>
		</div>
		<!-- 여기서 <1>에만든 버튼 내부의 데이터 타겟과 div id가 일치해야한다. -->
		<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
			<!-- div 내부에 ul은 하나의 어떠한 리스트를 보여줄때 사용 -->
			<ul class="nav navbar-nav">
				<!-- 리스트 내부에 li로 원소를 구현 메인으로 이동하게만들고-->
				<li><a href="main.jsp">메인</a></li>
				<!-- 게시판으로 이동하게 만든다. -->
				<li><a href="bbs.jsp">게시판</a></li>
			</ul>
			<!-- 리스트 하나 더 생성 웹페이지 화면에서 우측 부분-->
			<ul class="nav navbar-nav navbar-right">
				<!-- 원소를 하나 구현해 준다. 네비게이션 우측 슬라이드메뉴 구현  -->
				<li class="dropdown">
					<!-- 안에 a태그를 하나 삽입한다. href="#"은 링크없음을 표시한다. -->
					<a href="#" class="dropdown-toggle"
						data-toggle="dropdown" role="button" aria-haspopup="true"
						aria-expanded="false">접속하기
						<!-- 이건 하나의 아이콘 같은것 a태그 내부 삽입-->
						<span class="caret"></span></a>
					<!--접속하기 아래에 드랍다운메뉴 생성  -->
					<ul class="dropdown-menu">
						<!-- li class="active" 현재 선택된 홈페이지를 표시해 주게만든다. -->
						<li class="active"><a href="login.jsp">로그인</a></li>
						<!-- active는 한 개만 선언 -->
						<li><a href="join.jsp">회원가입</a></li>
					</ul>
				</li>
			</ul>	
		</div>
		<!-- 네비게이션 바 구성 끝 -->
	</nav>
	
	<!--<2> 여기서 부터 로그인 양식 <div>컨테이너 하나의 컨테이너처럼 감싸주는 역할 -->
	<div class="container"> 
		<!-- 이건 왜 넣어주는걸까 -->
		<div class="col-lg-4"></div>
		<!-- 로그인 폼 작성 -->
		<div class="col-lg-4">
			<div class="jumbotron" style="padding-top: 20px;">
				<!-- 양식 삽입 post는 회원가입이나 로그인같이 어떠한 정보값을 숨기면서 보내는 메소드/ 로그인 Action페이지로 정보를보내겠다-->
				<form method="post" action="loginAction.jsp">
					<!-- 로그인 페이지 내부의 문장 가운데 정렬로 삽입 -->
					<h3 style="text-align: center;">로그인 화면</h3>
					<!-- 아이디 입력 공간 구현 -->
					<div class="form-group">
						<!-- name="userID"쪽은 나중에 서버프로그램을 작성할때 사용하기때문에 대소문자구별 -->
						<input type="text" class="form-control" placeholder="아이디" name="userID" maxlength="20">
					</div>
					<!-- 패스워드 입력 공간 구현 -->
					<div class="form-group">
						<input type="password" class="form-control" placeholder="비밀번호" name="userPassword" maxlength="20">
					</div>
					<!-- 로그인 버튼 구현 -->
					<input type="submit" class="btn btn-primary form-control" value="로그인">
				</form>	
			</div>	
		</div>
		<!-- 왜 넣어줄까 2 -->
		<div class="col-lg-4"></div>
	</div>
	<!--이 파일의 애니메이션을 담당할 자바스크립트 참조선언 jquery를 특정 홈페이지에서 호출 -->
	<script src="https://code.jquery.com/jquery-3.1.1.min.js"></script>
	<!--js폴더 안에있는 bootstrap.js를 사용선언  -->
	<script src="js/bootstrap.js"></script>
</body>
</html>

①.코드 내부 주석 *1*에 대한부분

bootstrap을 사용함으로서 해상도가 줄어들거나 할때 웹페이지가 유동적으로 바뀌는 모습을 볼 수 있다. 

이제 로그인 화면을 만들었으니... 기능적인 부분을 만들어보자 가자;

로그인 기능을 만들기 전 우선 해야할것은 로그인에 들어오는 정보를 담아주는 데이터베이스를 다운로드 하자, 강의에선 mysql을 사용했다. 그리고 파일 설치 후 로컬에 install할때는 모두 default값으로 앵간해선 next눌러서 설치를 진행 하면 된다. 그리고 강의에 사용된 version은 5.7.18인데 난 최신버전으로 8.0.22를 받았는데 벌써 또 1버전이 업되었네;; 이런 미띤.. 홈페이지 구조도 자주바뀌고.. 일하지마 Oracle!!

 

뭐 설치할때 별로 그렇게 중요한건 없지만, 이부분의 rootPW 설정은 꼭 기억해야한다. 나머진 next 

설치 완료되면 시작화면창에 mysql 커맨드가 뜬다 실행시켜서 프로젝트 데이터베이스와 그 안에 유저 정보를 받을 테이블을 생성하자.

처음 키면 설치때 정해준 root Password를 입력하고 Project에 사용될 DATABASE를 생성한다.

그 후 생성한 DATABASE에 USE 디비명; 으로 디비 내부에 접속해서 그림과 같이 회원 가입 시 받을 데이터를 넣고 테이블 생성한다. *PRIMARY KEY로 userID를 감싸준 이유는 ID중복을 막기 위해서 이다.

잘 생성이 되었는지 확인해보자 . show tables; (bbs디비 안에 있는 테이블 2개를 볼 수 있다.)

그리고 테이블 안 구조를 확인해보자 desc user; 생성 시 넣은 속성으로 잘 구축이 되어있는걸 알 수 있다.

이제 테이블 내부에 회원을 등록하는

INSERT INTO USER VALUES('gildong', '123456', '남자', 'gindong@naver.com); 쿼리로 테이블에 데이터를 삽입 한다.  실수로 성별앞에 이름을 빼먹었다. 참고*

길동이가 잘드가있는걸 확인 할 수 있다. 그러면 이제 만들어진 회원 데이터를 jsp 서버에서 담고 처리하는 것을 해 보자.

 

우선 Project Explorer에 java Resources/src/user 패키지를 생성 해 준다.  그리고 user 패키지 내부에 User 클래스를 생성 해 준다.

 

(User.java)

package user;
//Database에서 회원 정보들을 자바안에 담아주는 클래스 
public class User {
	//db table에 입력된 이름, 속성값이 일치 되는 변수를 생성해 준다.
	private String userID;
	private String userPassword;
	private String userName;
	private String userGender;
	private String userEmail;
	
	public String getUserID() {
		return userID;
	}

	public void setUserID(String userID) {
		this.userID = userID;
	}

	public String getUserPassword() {
		return userPassword;
	}

	public void setUserPassword(String userPassword) {
		this.userPassword = userPassword;
	}

	public String getUserName() {
		return userName;
	}

	public void setUserName(String userName) {
		this.userName = userName;
	}

	public String getUserGender() {
		return userGender;
	}

	public void setUserGender(String userGender) {
		this.userGender = userGender;
	}

	public String getUserEmail() {
		return userEmail;
	}

	public void setUserEmail(String userEmail) {
		this.userEmail = userEmail;
	}

}

위에 테이블에 넣은 값과 동일한 이름으로 변수를 선언 해준다. 그 후 위에 사진처럼 Source 에 Generate Getter and Setter 를 누르면 저 화면이 뜨는데, 다 체크 후 Generate를 해주면 밑에 함수들이 쭈루룩생긴다. (하도많이써서 생활화 되어서 굳이 안쓰려했는데, 처음 시작하는 임의의 누군가가 볼지도 모르니까)

 

이런식으로 하나의 데이터를 관리하고 처리할 수 있는 기법을 jsp에서 구현하는 것을 Java Beans 라고 한다.

이제 로그인 기능에 필요한 준비물은 다 끝났다. 기능 구현 가자; 

JSP에서 회원 디비에 접근 할 수 있도록 DAO(Database Access Object)라는 것을 만들어 줄 것이다.

 

 

(UserDAO.java)

package user;

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

public class UserDAO {
	//Database 접근 객체로 사용할 conn을 선언해주고,
	private Connection conn;
	// 정보를 담을 수 있는 객체 선언
	private PreparedStatement pstmt;
	private ResultSet rs;

	//UserDAO를 생성자로 만들어 주고, 자동적으로 데이터베이스 연결이 이뤄지게 해주는 코드를 짠다.
	public UserDAO() {
		//예외 처리를 하기 위해서 try&catch 문을 쓴다.
		try {
			//dbURL안에 localhost라는 것은 본인 컴퓨터에 접속을 의미하고 3306포트에 연결된 BBSdb에 접속할 수 있게 해준다.
			//강의랑 디비 버전을 다르게해서 뒤에 뭘더붙임 ㅇㅇ;
			String dbURL =  "jdbc:mysql://localhost:3306/BBS?serverTimezone=UTC";
			//db에 접속하는 ID를 담는 부분
			String dbID = "root";
			//db에 접속하는 PW를 담는 부분
			String dbPassword = "root";
			//mysql에 접속할 수 있는 driver를 찾을수 있게 해주는 코드 driver라는건 mysql에 접속할 수 있도록 매개체 역할을 해주는 라이브러리이다.
			//강의버전보다 한참 높은 버전의 디비를 써서 드라이버 주소가 좀다름
			Class.forName("com.mysql.cj.jdbc.Driver");
			//getConnection함수 내부에 dbURL에 root root 로 접속할 수 있게 해주는 데이터를 넣어 접속이 완료되면 conn객체안에 접속된 정보가 담기게 된다.
			conn = DriverManager.getConnection(dbURL, dbID, dbPassword);
		
		} catch (Exception e) {
			//오류의 내용을 내부 콘솔에 띄우기 위한 함수이다.
			e.printStackTrace();
		}
	}

	//위에꺼는 실제로 mysql에 접속을 하게 해주는 부분이고, 이제 실제로 로그인을 시도하는 하나의 함수 구현 userID,userPassword를 입력 받아서 실행한다.
	public int login(String userID, String userPassword) {
		//이제 입력받은 userID 와 PW가 일치하는지 확인을 하기위해서 db내에서 userID 값에 대한 PW를 조회하는 쿼리를 넣어준다. *1.해킹방지를 위해 중간에 ?를 넣어놓고
		String SQL = "SELECT userPassword FROM USER WHERE userID = ?";
		//try,catch문으로 예외처리를 해주고
		try {
			//pstmt에 어떠한 정해진 sql문장을 데이터베이스에 삽입하는 형식으로 인스턴스를 가져온다.
			pstmt = conn.prepareStatement(SQL); 
			//*2.쿼리 중 userID = ? 에 해당하는 부분에 입력받은 userID를 넣어주는 것이다. 그니까 바로 쿼리문으로 드가면 해킹틈 생기니까 setString으로 한번 거치고간다. 2말2야
			pstmt.setString(1, userID);
			//이렇게 db에 넣을 쿼리문 셋팅이 끝났다. 실행한 결과를 rs에다가 담아준다.
			rs = pstmt.executeQuery();
			//이제 결과의 존재 여부에 따른 행동을 실행시켜주는 부분을 만들어 보자, 아이디가 존재할때
			if (rs.next()) {
				//만약 rs에 들어있는 값과 db내부의 userPW가 일치하면 login성공
				if (rs.getString(1).equals(userPassword))
					//login 성공
					return 1;
			 else 
				 //아니면 비밀번호 미 일치 실행한다. 
				return 0;
			}
			// 아이디가 없을때
			return -1;
		//그 외의 예상 불가 예외는 catch로 잡아준다.
		} catch (Exception e) {
			//해당 예외 출력
			e.printStackTrace();
		}
		// 데이터베이스 오류를 의미
		return -2;
	//로그인 시도 함수 작성 끝 loginAction Page 가자;
	}
	
	
	//회원가입 정보를 넣는곳
	public int join(User user) {
		String SQL = "INSERT INTO USER VALUES (?, ?, ?, ?, ?)";
		try {
			pstmt = conn.prepareStatement(SQL);
			pstmt.setString(1, user.getUserID());
			pstmt.setString(2, user.getUserPassword());
			pstmt.setString(3, user.getUserName());
			pstmt.setString(4, user.getUserGender());
			pstmt.setString(5, user.getUserEmail());
			return pstmt.executeUpdate();
		}catch(Exception e) {
			e.printStackTrace();
		}
		return -1; //데이터베이스 오류
	}
}

이제 실제로 로그인 시도를 해주는 함수를 구현했다. 이 함수를 실제로 사용해서 사용자에게 결과를 알려주는 JSP를 만들어 주자. 가자;

 

 

(loginAction.jsp)

<%@page import="user.User"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!-- 앞서 만들었던 User.DAO의 객체를 사용하기위해 선언 -->
<%@ page import="user.UserDAO" %>
<!-- 자바스크립트 문장을 작성 하기위해 사용하는 내부라이브러리? -->
<%@ page import="java.io.PrintWriter" %>
<!-- 건너오는 모든 데이터를 UTF-8로 받기위해 가져오는것 -->
<% request.setCharacterEncoding("UTF-8"); %>
<!-- 한명의 회원 정보를 담는 전에만든 javaBeans를 사용한다는 것, scope로 현재 페이지에서만 사용을 선언-->
<jsp:useBean id="user" class="user.User" scope="page" /> 
<!-- 로그인 페이지에서 넘겨준 user정보를 받아서 한명의 사용자에 데이터에 값을 넣어주는 것 -->
<jsp:setProperty name = "user" property = "userID" />
<!-- 이렇게 하면 loginAction.jsp 안에 넘어온 데이터들이 그대로 담기게 된것이다! -->
<jsp:setProperty name = "user" property = "userPassword" />
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>JSP Web Site</title>
</head>
<body>
	<%
		String userID = null;
		if(session.getAttribute("userID") != null){
			userID = (String) session.getAttribute("userID");
		}
		if (userID != null){
			PrintWriter script = response.getWriter();
			script.println("<script>");
			script.println("alert('이미 로그인이 되어있습니다.')");
			script.println("location.href = 'main.jsp'");
			script.println("</script>");
		}
				
		//이제 넘어온 userID와 PW를 꺼내서 사용해보자. UserDAO인스턴스 생성
		UserDAO userDAO = new UserDAO();
		//UserDAO 에서 만들었던 public int login(userID,userPW)를 넣어주는 것을 변수 result에 담는다.
		int result = userDAO.login(user.getUserID(), user.getUserPassword());
		//login함수에서 return값이 1이라면
		if (result == 1){
			session.setAttribute("userID", user.getUserID());
			//하나의 스크립트 문장을 넣어줄 수있도록 한다.
			PrintWriter script = response.getWriter();
			//println으로 접근해서 스크립트 문장을 유동적으로 실행 할 수 있게한다.
			script.println("<script>");
			//메인 페이지로 넘겨주는 선언을 해주고,
			script.println("location.href = 'main.jsp'");
			//스크립트 태그를 닫아준다.
			script.println("</script>");
		}
		//비밀번호가 틀릴때
		else if(result == 0){
			PrintWriter script = response.getWriter();
			script.println("<script>");
			//웹페이지에 팝업을 띄워준다.
			script.println("alert('비밀번호가 틀립니다.');");
			//이 전 페이지로 사용자를 다시 돌려보내는 함수이다.
			script.println("history.back()");
			script.println("</script>");
		}
		//아이디가 없을때
		else if(result == -1){
			PrintWriter script = response.getWriter();
			script.println("<script>");
			script.println("alert('존재하지 않는 아이디입니다.');");
			script.println("history.back()");
			script.println("</script>");
		}
		//db연결 ㅈ같이 됬을때
		else if(result == -2){
			PrintWriter script = response.getWriter();
			script.println("<script>");
			script.println("alert('데이터베이스 오류가 발생했습니다.');");
			script.println("history.back()");
			script.println("</script>");
		}
		%>
</body>
</html>

이제 로그인함수를 사용해서 사용자에게 보여주는 Action페이지 제작이 끝났는데, 이제 제대로 되는지 테스트를 해보자...  그러기 위해서는 마지막으로 mysql에 접속하기 위한 Driver를 프로젝트에 추가 해 줘야한다. 설치 가자;

 

mysql 공식페이지로 가서 mysql download Connector/j를 찾아서 설치 해 준다. C드라이브에 프로젝트 중인 폴더안에 압축을 풀어준다.

압축 푼 폴더 내부로 드가서 jar파일 복사 후 이클립스 Project Explorer 에 WEB-INFOMATION안에 lib에 붙여넣기 ㄱㄱ

그 후

 

이렇게 하면 jdbc Driver 설정은 끝~ 이제 한번 실행시켜서 해봐라~ db만들때 넣었던 아이디와 비밀번호를 치고 로그인을 누르면

화면은 안뜰껀데 위에 URL이 main.jsp로 넘어갔으면 성공한거다.