저번 글 : https://ticssfm.tistory.com/177?category=1007516
저번 글에 이어서 이번에는 MVC 패턴을 이용하여 간단하게 로그인, 로그아웃하는 법을 포스팅 하겠다.
일단 User 정보가 들어갈 DB는 mysql을 사용하였다. DB 먼저 생성해주자
create schema study;
use study;
create table `user`(
`id` varchar(50) primary key,
`pwd` varchar(50) not null
);
desc user; -- user table 정보 확인
insert into user(id, pwd) values ("gd", "gd");
select * from user; -- user table data 확인
이렇게 study DB에 user 테이블을 만들고 간단하게 id, pwd만 넣을 수 있게 만들었다.
그럼 이제 dynamic web 프로젝트를 생성해서 만들어보자! 참고로 톰캣은 9.0버전 사용했다.
MVC 패턴을 이용한 로그인, 로그아웃 구현
0. DBUtil 클래스 생성
package com.study.sample.util;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
public class DBUtil {
private DBUtil() {
try {
Class.forName("com.mysql.cj.jdbc.Driver"); // mysql 드라이버 로드
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
// 싱글톤
private static DBUtil instance = new DBUtil();
public static DBUtil getInstance() {
return instance;
}
public Connection getConnection() throws SQLException {
String url = "jdbc:mysql://127.0.0.1:3306/study?serverTimezone=UTC&useUniCode=yes&characterEncoding=UTF-8";
String user = "ID"; // DB id
String pwd = "PWD"; // DB pwd
return DriverManager.getConnection(url, user, pwd); // load된 드라이버로 Connection 활성화
}
public void close(AutoCloseable... closeables) {
for (AutoCloseable c : closeables) {
if (c != null) {
try {
c.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
}
DB 연동을 위해 DBUtil이라는 클래스를 싱글톤으로 생성해주었다.
JDBC 인터페이스를 이용해 mysql과 연동해주었다.
1. DTO
package com.study.sample.dto;
public class User {
String id, pwd;
public User() {
super();
// TODO Auto-generated constructor stub
}
public User(String id, String pwd) {
super();
this.id = id;
this.pwd = pwd;
}
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;
}
@Override
public String toString() {
return "User [id=" + id + ", pwd=" + pwd + "]";
}
}
DTO는 Data Transfer Object의 약자로, 데이터 전송을 위해 생성되는 객체이다.
table에 있는 id, pwd 값을 사용하기 위한 객체를 생성해주었다.
2. DAO
package com.study.sample.dao;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import com.study.sample.dto.User;
import com.study.sample.util.DBUtil;
public class UserDao {
// 싱글톤
private UserDao () {}
private static UserDao instance = new UserDao();
public static UserDao getInstance() {
return instance;
}
DBUtil dbUtil = DBUtil.getInstance();
// 로그인
public User login(String id, String pwd) throws SQLException {
String sql = "select id, pwd from user where id=? and pwd=?";
Connection conn = null;
PreparedStatement pstmt = null;
ResultSet rs = null;
try {
conn = dbUtil.getConnection(); // DB 연결
pstmt = conn.prepareStatement(sql); // sql 실행
pstmt.setString(1, id);
pstmt.setString(2, pwd);
rs = pstmt.executeQuery(); // sql문을 executeQuery() 메소드를 사용해 테이블로 받아온다.
if(rs.next()) { // 만약 rs 테이블이 존재한다면 user에 넣어서 리턴한다.
User user = new User();
user.setId(rs.getString(1));
user.setPwd(rs.getString(2));
return user;
}
return null;
} finally {
dbUtil.close(pstmt, conn);
}
}
}
다음은 Dao 부분이다.
DAO는 Data Access Object의 약자로, 실제 DB에 접근하는 객체이다.
이 부분이 MVC에서 Model 부분이다.
그리고 Model은 컨트롤러에서 바로 넘어오지 않고 Service를 거쳐서 온다.
서비스에서 여러가지 처리도 가능
참고로 login 리턴 타입을 User로 해주었는데 int나 boolean 등으로 해도 된다.
3. Service
package com.study.sample.service;
import java.sql.SQLException;
import com.study.sample.dao.UserDao;
import com.study.sample.dto.User;
public class UserService {
// 싱글톤
private UserService () {}
private static UserService instance = new UserService();
public static UserService getInstance() {
return instance;
}
UserDao userDao = UserDao.getInstance();
// 로그인
public User login(String id, String pwd) throws SQLException {
return userDao.login(id, pwd);
}
}
다음은 Service 클래스이다.
컨트롤러에서 바로 DAO에 접근하지 않고 Service를 거쳐서 들어온다.
4. Controller
package com.study.sample.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;
import javax.servlet.http.HttpSession;
import com.mysql.cj.Session;
import com.study.sample.dto.User;
import com.study.sample.service.UserService;
@WebServlet("/user")
public class UserController extends HttpServlet {
private static final long serialVersionUID = 1L;
UserService userService = UserService.getInstance();
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String action = request.getParameter("action");
try {
switch (action) {
case "login":
login(request, response);
break;
case "logout":
logout(request, response);
break;
default:
break;
}
} catch (Exception e) {
response.sendRedirect(request.getContextPath() + "/error/error.jsp");
e.printStackTrace();
}
}
private void logout(HttpServletRequest request, HttpServletResponse response) {
HttpSession session = request.getSession();
session.removeAttribute("id");
}
private void login(HttpServletRequest request, HttpServletResponse response) throws IOException {
String id = request.getParameter("id");
String pwd = request.getParameter("pwd");
try {
User user = userService.login(id, pwd); // service -> DAO에서 보낸 User 받아오기
HttpSession session = request.getSession();
session.setAttribute("id", id); // 세션에 id 저장
request.setAttribute("info", user); // loginSuccess.jsp로 가면서 user를 info라는 이름으로 보냄
request.getRequestDispatcher("/loginSuccess.jsp").forward(request, response);
} catch (Exception e) {
response.sendRedirect(request.getContextPath() + "/error/error.jsp");
e.printStackTrace();
}
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}
드디어 view에서 바로 넘어오는 controller이다.
로그아웃은 DB를 거칠 필요가 없으므로 컨트롤러에서 처리해주었다.
로그인 시 sessoin에 id값을 저장하고 로그아웃 클릭 시 session에 있는 id 데이터를 삭제한다.
view인 jsp에서 action=login을 호출하면 controller에 있는 login() 메소드를 호출하는 방식으로 구현하였다.
5. view
login.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<c:set var="root" value="${pageContext.request.contextPath}" />
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<form action="${root}/user">
<input type="hidden" name="action" value="login">
<div class="form-group">
<label for="productCode">id</label>
<input type="text" class="form-control" id="id" name="id" placeholder="ID 입력">
</div>
<div class="form-group">
<label for="model">password</label>
<input type="text" class="form-control" id="pwd" name="pwd" placeholder="PWD 입력">
</div>
<button type="submit" class="btn btn-primary" id="login">로그인</button>
<a class="btn btn-secondary" href="${root}/product?action=list" >취소</a>
</form>
</body>
login에 필요한 id 와 pwd를 입력받는 input을 만들고 로그인버튼 클릭 시 GET방식으로 넘겨주었다.
loginSuccess.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<c:set var="root" value="${pageContext.request.contextPath}" />
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<h1>로그인</h1>
<c:choose>
<c:when test="${info.id ne null}">
<h1>성공!</h1>
${info.id} <br>
${info.pwd}
</c:when>
<c:otherwise>
<h1>실패</h1>
</c:otherwise>
</c:choose>
</body>
</html>
로그인이 되었는지 확인하기 위해 간단하게 el태그를 사용해 controller에서 넘겨준 id값이 null이 아니라면
성공! 과 아이디, 비밀번호를 출력하는 화면이다.
- 결과 화면
'컴퓨터 > WEB' 카테고리의 다른 글
[Spring] DI(Dependency Injection)와 IoC(Inversion of Control)란? (0) | 2022.10.23 |
---|---|
[Spring] 웹서버(Web Server)와 서블릿 컨테이너(Servlet Container) 의 역할과 처리 순서 (0) | 2022.10.23 |
[Spring] Servlet, JSP 그리고 MVC 패턴 (0) | 2022.09.18 |
[Django] 장고 User 모델 OneToOneField로 확장해서 사용하기 + 토큰으로 로그인하기 (0) | 2022.05.14 |
[Web] 로그인 메커니즘, 그리고 세션과 쿠키 (0) | 2022.05.10 |