MVC 패턴을 적용한 이번 예의 구조를 살펴보자
폴더의 수가 많고 매우 복잡해 보이지만
파일 하나하나가 잘 분류되어 어떤 기능을 하는지 예상이 된다.
WEB-INF / lib / ojdbc6.jar 파일은 예5 게시글과 같이 끌어오면 된다.
이번 예는 DB를 조회, 입력하여 로그인, 회원가입, 로그아웃을 만들어보자.
새로 나오는 개념은 Session이라는 개념으로 로그인을 성공 했을 경우 로그인의 정보들(계정정보 등)을
담아두어 여러 페이지에서 사용 할 수 있는 방이라고 생각하면 된다.
예를 들어서 네이버에 로그인을 하고 아무 활동도 안하고 시간이 지나면 "세션이 만료되었습니다." 하고 자동 로그아웃 된다.
세션은 로그인 시점부터 관련 정보를 Session을 통해서 담고 있다가
설정해둔 일정 시간이 지나면 파기하게끔 설정해둔 것이다.
파기가 되면 로그아웃 처리가 되는것이다.
그리고 이번에는 java를 공부할 때 다루었던 Properties 파일을 이용해서
반복적으로 사용할 키워드들을 Key, Value 형태로 다룬다.
예에서는 서버의 jdbc.oracle~~~이나 oracle:jdbc:thin과 같이 쓰기 귀찮은 구문을 미리 입력해둔다.
예를 확인해보자.
먼저 로그인폼
index.jsp, loginForm.jsp
------------------------------------------------------------------------------------------------------------------------------------
index.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<h1 align="center">MVC model2 방식을 이용한 회원 로그인</h1>
<h3 align="center"><a href="views/member/loginForm.jsp">회원 서비스 테스트</a></h3>
</body>
</html>
loginForm.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<style type="text/css">
input[type='submit'] {
height:55px;
}
</style>
</head>
<body>
<div align="center">
<h2>로그인 테스트</h2>
<form action="<%=request.getContextPath() %>/login" method="post">
<table>
<tr>
<td><label>아이디</label></td>
<td><input type="text" name="userId"></td>
<td rowspan="2"><input type="submit" value="로그인"></td>
</tr>
<tr>
<td><label>비밀번호</label></td>
<td><input type="password" name="password"></td>
</tr>
<tr>
<td colspan="3"><input type="button" onclick="location.href='newAccount.jsp'" value="회원가입"></td>
</tr>
</table>
</form>
</div>
</body>
</html>
------------------------------------------------------------------------------------------------------------------------------------
로그인 기능구현 MemberService.java는 멤버 추가도 포함되어 있다.
LoginServlet.java, MemberService.java, MemberDao.java
------------------------------------------------------------------------------------------------------------------------------------
LoginServlet.java
package com.kh.w6.member.controller;
import java.io.IOException;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import com.kh.w6.member.model.service.MemberService;
import com.kh.w6.member.model.vo.Member;
@WebServlet("/login")
public class LoginServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
// 로그인처리를 위한 상수 선언
public static int LOGIN_OK = 1;
public static int WRONG_PASSWORD = 0;
public static int ID_NOT_EXIST = -1;
public LoginServlet() {
super();
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 1. 전송값에 한글이 있는 경우
request.setCharacterEncoding("UTF-8");
// 2. 전송값 꺼내서 변수에 기록하기
String userId = request.getParameter("userId");
String password = request.getParameter("password");
System.out.println("ID : " + userId);
System.out.println("Pwd : " + password);
//3. 비지니스 로직을 처리할 서비스 클래스의 메소드로 전달값 넘김
Member requestMember = new Member();
requestMember.setUserId(userId);
requestMember.setPassword(password);
Member loginUser = new MemberService().loginCheck(requestMember);
//4. 받은 결과에 따라서 성공/실패 페이지 내보내기
String view = "";
if(loginUser.getStatus() == LOGIN_OK) {
view = "views/main/main.jsp";
HttpSession session = request.getSession();
session.setAttribute("loginUser", loginUser);
}else {
String msg;
if(loginUser.getStatus() == WRONG_PASSWORD) {
msg = "패스워드를 잘못 입력하셨습니다.";
}else {
msg = "존재하지 않는 아이디입니다.";
}
request.setAttribute("msg", msg);
view = "views/common/errorPage.jsp";
}
RequestDispatcher reqDispatcher = request.getRequestDispatcher(view);
reqDispatcher.forward(request, response);
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}
MemberService.java
package com.kh.w6.member.model.service;
import java.sql.Connection;
import java.sql.SQLException;
import static com.kh.w6.common.JDBCTemplate.*;
import com.kh.w6.member.controller.LoginServlet;
import com.kh.w6.member.model.dao.MemberDao;
import com.kh.w6.member.model.vo.Member;
public class MemberService {
//로그인 처리용 메소드
public Member loginCheck(Member requestMember) {
Connection con = getConnection();
MemberDao mDao = new MemberDao();
int result = mDao.checkStatus(con, requestMember);
Member loginUser = new Member();
if(result == LoginServlet.LOGIN_OK) { // 로그인 성공
loginUser = mDao.selectOne(con, requestMember);
loginUser.setStatus(LoginServlet.LOGIN_OK);
}else {
if (result == LoginServlet.WRONG_PASSWORD) { // 비밀번호 틀림
loginUser.setStatus(LoginServlet.WRONG_PASSWORD);
}else { // 아이디 틀림
loginUser.setStatus(LoginServlet.ID_NOT_EXIST);
}
}
return loginUser;
}
// 회원 추가용 메소드
public int addMember(Member newMember) {
Connection con = getConnection();
MemberDao mDao = new MemberDao();
int result = mDao.updateMember(con, newMember);
try {
if(result > 0){
con.commit();
}else{
con.rollback();
}
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return result;
}
}
MemberDao.java
package com.kh.w6.member.model.dao;
import java.io.FileReader;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Properties;
import com.kh.w6.member.controller.LoginServlet;
import com.kh.w6.member.model.vo.Member;
import static com.kh.w6.common.JDBCTemplate.*;
public class MemberDao {
private Properties prop = new Properties();
public MemberDao() {
String fileName = MemberDao.class.getResource("/sql/member/member-query.properties").getPath();
try {
prop.load(new FileReader(fileName));
} catch (Exception e) {
e.printStackTrace();
}
}
// 로그인 상태 조회용 메소드
public int checkStatus(Connection con, Member requestMember) {
PreparedStatement pstmt = null;
int result = LoginServlet.ID_NOT_EXIST; // 실패했을 때를 위한 초기화
ResultSet rset = null;
String query = prop.getProperty("checkStatus");
try {
pstmt = con.prepareStatement(query);
pstmt.setString(1, requestMember.getUserId());
rset = pstmt.executeQuery();
String userId = "";
String password = "";
if (rset.next()) {
userId = rset.getString("USER_ID");
password = rset.getString("PASSWORD");
}
if (requestMember.getUserId().equals(userId) && requestMember.getPassword().equals(password)) {
result = LoginServlet.LOGIN_OK;
}else if (requestMember.getUserId().getClass().equals(userId) && !requestMember.getPassword().equals(password)) {
result = LoginServlet.WRONG_PASSWORD;
}else {
result = LoginServlet.ID_NOT_EXIST;
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
close(rset);
close(pstmt);
}
return result;
}
// 로그인 정보 조회용 메소드
public Member selectOne(Connection con, Member requestMember) {
Member loginUser = null;
PreparedStatement pstmt = null;
ResultSet rset = null;
String query = prop.getProperty("selectOne");
try {
pstmt = con.prepareStatement(query);
pstmt.setString(1, requestMember.getUserId());
pstmt.setString(2, requestMember.getPassword());
rset = pstmt.executeQuery();
if (rset.next()) {
loginUser = new Member();
loginUser.setUserId(rset.getString("USER_ID"));
loginUser.setPassword(rset.getString("PASSWORD"));
loginUser.setUserName(rset.getString("USER_NAME"));
loginUser.setGender(rset.getString("GENDER"));
loginUser.setAge(rset.getInt("AGE"));
loginUser.setEmail(rset.getString("EMAIL"));
loginUser.setPhone(rset.getString("PHONE"));
loginUser.setAddress(rset.getString("ADDRESS"));
loginUser.setHobby(rset.getString("HOBBY"));
loginUser.setEnrollDate(rset.getDate("ENROLL_DATE"));
}
} catch (SQLException e) {
e.printStackTrace();
}finally {
close(rset);
close(pstmt);
}
return loginUser;
}
public int updateMember(Connection con, Member newMember) {
PreparedStatement pstmt = null;
int result = 0;
String query = prop.getProperty("updateOne");
try {
pstmt = con.prepareStatement(query);
pstmt.setString(1, newMember.getUserId());
pstmt.setString(2, newMember.getPassword());
pstmt.setString(3, newMember.getUserName());
pstmt.setString(4, newMember.getGender());
pstmt.setInt(5, newMember.getAge());
pstmt.setString(6, newMember.getEmail());
pstmt.setString(7, newMember.getPhone());
pstmt.setString(8, newMember.getAddress());
pstmt.setString(9, newMember.getHobby());
result = pstmt.executeUpdate();
} catch (SQLException e) {
e.printStackTrace();
}finally {
close(pstmt);
}
return result;
}
}
------------------------------------------------------------------------------------------------------------------------------------
driver.properties, member-query.properties
------------------------------------------------------------------------------------------------------------------------------------
driver.properties
driver=oracle.jdbc.driver.OracleDriver
url=jdbc:oracle:thin:@localhost:1521:xe
user=jsp
password=jsp
member-query.properties
checkStatus=SELECT * FROM member WHERE user_id = ?
selectOne=SELECT * FROM member WHERE user_id = ? AND password = ?
updateOne=INSERT INTO MEMBER VALUES(?,?,?,?,?,?,?,?,?,SYSDATE)
------------------------------------------------------------------------------------------------------------------------------------
멤버의 정보가 담길 객체
Member.java
------------------------------------------------------------------------------------------------------------------------------------
package com.kh.w6.member.model.vo;
import java.sql.Date;
public class Member implements java.io.Serializable{
private String userId;
private String password;
private String userName;
private String gender;
private int age;
private String email;
private String phone;
private String address;
private String hobby;
private Date enrollDate;
private int status = 99; // 1또는 0으로 로그인 성공 실패를 가리기 때문에 쓰레기값을 넣어놓는다.
public Member() {}
public Member(String userId, String password, String userName, String gender, int age, String email, String phone,
String address, String hobby, Date enrollDate, int status) {
super();
this.userId = userId;
this.password = password;
this.userName = userName;
this.gender = gender;
this.age = age;
this.email = email;
this.phone = phone;
this.address = address;
this.hobby = hobby;
this.enrollDate = enrollDate;
this.status = status;
}
public Member(String userId, String password, String userName, String gender, int age, String email, String phone,
String address, String hobby) {
super();
this.userId = userId;
this.password = password;
this.userName = userName;
this.gender = gender;
this.age = age;
this.email = email;
this.phone = phone;
this.address = address;
this.hobby = hobby;
}
@Override
public String toString() {
// TODO Auto-generated method stub
return super.toString();
}
public String getUserId() {
return userId;
}
public void setUserId(String userId) {
this.userId = userId;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getHobby() {
return hobby;
}
public void setHobby(String hobby) {
this.hobby = hobby;
}
public Date getEnrollDate() {
return enrollDate;
}
public void setEnrollDate(Date enrollDate) {
this.enrollDate = enrollDate;
}
public int getStatus() {
return status;
}
public void setStatus(int status) {
this.status = status;
}
}
------------------------------------------------------------------------------------------------------------------------------------
로그아웃, 회원가입
LogoutServlet.java, newAccount.java
------------------------------------------------------------------------------------------------------------------------------------
LogoutServlet.java
package com.kh.w6.member.controller;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* Servlet implementation class LogoutServlet
*/
@WebServlet("/logout")
public class LogoutServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
/**
* @see HttpServlet#HttpServlet()
*/
public LogoutServlet() {
super();
// TODO Auto-generated constructor stub
}
/**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.getSession().invalidate();
response.sendRedirect("views/member/loginForm.jsp");
}
/**
* @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
doGet(request, response);
}
}
newAccount.java
package com.kh.w6.member.controller;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.kh.w6.member.model.service.MemberService;
import com.kh.w6.member.model.vo.Member;
@WebServlet("/newaccount")
public class newAccount extends HttpServlet {
private static final long serialVersionUID = 1L;
public newAccount() {
super();
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setCharacterEncoding("UTF-8");
String userId = request.getParameter("userId");
String password = request.getParameter("password");
String userName = request.getParameter("userName");
int age = Integer.parseInt(request.getParameter("age"));
String gender = request.getParameter("gender");
String email = request.getParameter("email");
String phone = request.getParameter("phone");
String address = request.getParameter("address");
String[] hobbies = request.getParameterValues("hobby");
String hobby = String.join(",", hobbies);
System.out.println("입력한 정보----------\r\n"
+ userId + "\r\n"
+ password + "\r\n"
+ userName + "\r\n"
+ age + "\r\n"
+ gender + "\r\n"
+ email + "\r\n"
+ phone + "\r\n"
+ address + "\r\n"
+ hobby);
Member newMember = new Member(userId, password, userName, gender, age, email, phone, address, hobby);
System.out.println(newMember.toString());
int result = new MemberService().addMember(newMember);
response.setContentType("text/html; charset=UTF-8");
PrintWriter out = response.getWriter();
if(result > 0){
out.println("<script>alert('성공적으로 회원 가입 되었습니다.');</script>");
out.println("<script>location.href='views/member/loginForm.jsp';</script>");
out.close();
}else{
out.println("<script>alert('회원 가입에 실패했습니다.');</script>");
out.println("<script>history.back();</script>");
out.close();
}
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}
------------------------------------------------------------------------------------------------------------------------------------
JDBCTemplate.java
------------------------------------------------------------------------------------------------------------------------------------
JDBCTemplate.java
package com.kh.w6.common;
import java.io.FileReader;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;
public class JDBCTemplate {
public static Connection getConnection() {
Connection conn = null;
Properties prop = new Properties();
String fileName = JDBCTemplate.class.getResource("/sql/driver.properties").getPath();
System.out.println(fileName);
try {
prop.load(new FileReader(fileName));
String driver = prop.getProperty("driver");
String url = prop.getProperty("url");
String user = prop.getProperty("user");
String password = prop.getProperty("password");
// 아래 클래스 구문은 신버전에서는 자동으로 추가되어서 생략해도 되지만
// 구버전 호환을 위해 명시해두자.
Class.forName(driver);
conn = DriverManager.getConnection(url, user, password);
conn.setAutoCommit(false);
System.out.println(conn);
} catch (Exception e) {
e.printStackTrace();
}
// prop 파일을 수정할 때 classes 폴더 아래의 파일을 수정하면 서버 껏따 킬때 재생성 되기 때문에 사라진다.
// 그리고 바로바로 수정사항이 적용이 안될 때도 있는데 메뉴바 상단의 Project - clean을 실행하면 강제 재컴파일 시켜준다.
return conn;
}
public static void close(Connection con) {
try {
if(con != null && !con.isClosed()) {
con.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
public static void close(Statement stmt) {
try {
if(stmt != null && !stmt.isClosed()) {
stmt.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
public static void close(ResultSet rset) {
try {
if(rset != null && !rset.isClosed()) {
rset.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
public static void commit(Connection con) {
try {
if(con != null && !con.isClosed()) {
con.commit();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
public static void rollback(Connection con) {
try {
if(con != null && !con.isClosed()) {
con.rollback();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
------------------------------------------------------------------------------------------------------------------------------------
이 외의 폼들은 다음과 같다.
main.jsp, newAccount.jsp, errorPage.jsp
------------------------------------------------------------------------------------------------------------------------------------
main.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8" import="com.kh.w6.member.model.vo.Member"%>
<% Member loginUser = (Member)session.getAttribute("loginUser"); %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<style>
#userInfo {
float:right;
}
</style>
</head>
<body>
<h1 align="center">Welcome to MVC 랜드</h1>
<div id="userInfo">
<label><%= loginUser.getUserName() %>님 환영합니다.</label><br>
<button id="changeInfo">정보수정</button>
<button id="logout">로그아웃</button>
</div>
<script type="text/javascript">
$(function name() {
$("#logout").click(function() {
location.href="<%=request.getContextPath()%>/logout";
});
});
</script>
</body>
</html>
newAccount.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<form action="<%=request.getContextPath() %>/newaccount" method="post">
<input type="text" placeholder="아이디" name="userId" id="userId">
<br>
<input type="password" placeholder="패스워드" name="password" id="password">
<br>
<input type="text" placeholder="이름" name="userName" id="userName">
<br>
<input type="text" placeholder="나이" name="age" id="age">
<br>
<input type="email" placeholder="이메일" name="email" id="email">
<br>
<input type="tel" placeholder="휴대폰" name="phone" id="phone">
<br>
<input type="text" placeholder="주소" name="address" id="address">
<br>
<label>성별 : </label>
<input type="radio" name="gender" id="male" value="M">
<label for="male">남</label>
<input type="radio" name="gender" id="female" value="F">
<label for="female">여</label>
<br>
<label>취미 : </label>
<input type="checkbox" name="hobby" id="hobby0" value="운동">
<label for="hobby0">운동</label>
<input type="checkbox" name="hobby" id="hobby1" value="등산">
<label for="hobby1">등산</label>
<input type="checkbox" name="hobby" id="hobby2" value="독서">
<label for="hobby2">독서</label>
<input type="checkbox" name="hobby" id="hobby3" value="게임">
<label for="hobby3">게임</label>
<input type="checkbox" name="hobby" id="hobby4" value="여행">
<label for="hobby4">여행</label>
<br><br>
<input type="submit" value="가입">
<input type="reset" value="취소">
</form>
</body>
</html>
errorPage.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<% String msg = (String)request.getAttribute("msg"); %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<h1><%= msg %></h1>
</body>
</html>
------------------------------------------------------------------------------------------------------------------------------------
MemberException.java 파일은 따로 내용을 수정 안하였으니 만들 내용이 없다.
'JDBC, Servlet, JSP, Ajax, Json, Gson > 02.Servlet, JSP 사용법' 카테고리의 다른 글
[Servlet, JSP]02-14. JSP에서 Wrapper 구조를 통해 비밀번호 암호화(SHA-512 알고리즘 적용), Filter 클래스 사용 (0) | 2018.12.13 |
---|---|
[Servlet, JSP]02-13 Servlet, JSP 예 7 MVC2, Session 사용 (0) | 2018.12.10 |
[Servlet, JSP]02-11. MVC 패턴 1, 2 (0) | 2018.12.10 |
[Servlet, JSP]02-10. Servlet, JSP 예 5 (0) | 2018.12.10 |
[Servlet, JSP]02-09. Servlet, JSP 예 4 (임의 에러페이지, 날짜 함수, jsp include, 연산처리 방법) (0) | 2018.12.07 |