폴더 구조
src
├─ main
│ └─ java
│ ├─ common
│ │ └─ DbConnection.java
│ ├─ controller
│ │ └─ UserController.java
│ ├─ model
│ │ ├─ dao
│ │ │ └─ UserDao.java
│ │ └─ User.java
│ └─ service
│ └─ UserService.java
│
└─ web
└─ view
└─ user
├─ login.jsp
└─ signup.jsp
MVC 패턴
- Controller = UserController.java
- View = signup.jsp, login.jsp
- Model = User.java 아니면 UserDto, UserVo, UserDomain
Layered 패턴
회원가입 기능일 때,
UserController.java -> UserService.java -> UserDao.java
코드
login.jsp
form에서 input 태그에 입력한 값을 action의 주소로 http post 방식으로 넘겨준다.
name에 있는 키와 입력한 값으로 파라미터 전달된다.
( /user/login?email=test@test.com&password=qwer1234 )
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>로그인</title>
</head>
<body>
<form action="/user/login" method="post">
<p>이메일 : <input type="text" name="email"></p>
<p>비밀번호 : <input type="password" name="password"></p>
<button>로그인하기</button>
</form>
</body>
</html>
signup.jsp
login과 마찬가지로 input 태그에 입력한 값을 action의 주소로 http post 방식으로 넘겨준다.
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>회원가입</title>
</head>
<body>
<form action="/user/signup" method="post">
<p>이메일 : <input type="text" name="email"></p>
<p>비밀번호 : <input type="password" name="password"></p>
<p>이름 : <input type="text" name="name"></p>
<button>가입하기</button>
</form>
</body>
</html>
UserController.java
사용자가 보낸 요청을 받아 처리한다. (http get, post)
사용자가 접속한 주소를 확인하고, 주소에 맞게 처리해준다. (/login, /signup)
사용자가 입력한 파라미터를 Service 클래스에 넘긴다.
package controller;
import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.*;
import model.User;
import service.UserService;
import java.io.IOException;
@WebServlet("/user/*")
public class UserController extends HttpServlet {
private UserService userService;
public UserController() {
userService = new UserService();
}
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String action = req.getPathInfo();
if ("/login".equals(action)) {
req.getRequestDispatcher("/view/user/login.jsp").forward(req, resp);
} else if ("/signup".equals(action)) {
req.getRequestDispatcher("/view/user/signup.jsp").forward(req, resp);
}
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String action = req.getPathInfo();
if ("/signup".equals(action)) {
User user = new User(
req.getParameter("email"),
req.getParameter("password"),
req.getParameter("name")
);
userService.signup(user);
resp.sendRedirect("/user/login");
} else if ("/login".equals(action)) {
User user = new User(
req.getParameter("email"),
req.getParameter("password")
);
boolean result = userService.login(user);
if(result) {
resp.sendRedirect("/");
return;
}
resp.sendRedirect("/user/login");
}
}
}
UserService.java
UserController에서 받아온 파라미터로 비즈니스 로직(암호화 등)을 수행한 다음 UserDao에 데이터를 전달한다.
package service;
import common.DbConnection;
import model.User;
import model.dao.UserDao;
public class UserService {
private UserDao userDao;
public UserService() {
userDao = new UserDao(DbConnection.getConnection());
}
public void signup(User user) {
String originPassword = user.getPassword();
user.setPassword("암호화됨" + originPassword);
this.userDao.insertUser(user);
}
public boolean login(User user) {
String originPassword = user.getPassword();
user.setPassword("암호화됨" + originPassword);
boolean result = this.userDao.selectUser(user);
if(result) {
return true;
}
return false;
}
}
UserDao.java
DB와 연결하여 데이터의 CRUD 작업을 처리한다.
package model.dao;
import model.User;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
public class UserDao {
private Connection conn;
public UserDao(Connection conn) {
this.conn = conn;
}
public void insertUser(User user) {
String sql = "INSERT INTO user (email, password, name) " +
"VALUE ('" + user.getEmail() + "','" + user.getPassword() + "','" + user.getName() + "')";
try {
conn.createStatement().executeUpdate(sql);
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
public boolean selectUser(User user) {
String sql = "SELECT * FROM user WHERE email = '" + user.getEmail()
+ "' AND password = '" + user.getPassword() + "'";
try {
ResultSet rs = conn.createStatement().executeQuery(sql);
if(rs.next()) {
return true;
}
return false;
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
}
User.java
사용자 객체
사용자의 데이터를 정의한다.
package model;
public class User {
private String email;
private String password;
private String name;
public User(String email, String password) {
this.email = email;
this.password = password;
}
public User(String email, String password, String name) {
this.email = email;
this.password = password;
this.name = name;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
전체 동작 과정 (회원가입 기능)
1. 클라이언트가 서버에 /user/signup 이라는 주소로 접속 (HTTP GET)
http://localhost:8080/user/signup
2. UserController.java에 doGet 메소드가 실행
@WebServlet("/user/*")
public class UserController extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//..
}
}
3. String action = req.getPathInfo(); -> 이 코드로 사용자가 접속한 주소를 확인 ("/signup" 이라는 문자열이 action 변수에 저장)
String action = req.getPathInfo();
4. action 이라는 변수에 저장된 값이 "/signup"과 일치하면 /view/user/signup.jsp 파일을 클라이언트에게 전달
else if ("/signup".equals(action)) {
req.getRequestDispatcher("/view/user/signup.jsp").forward(req, resp);
}
5. 웹 브라우저에서 form 태그를 이용해서 input 태그에 입력한 값을 action의 주소로 HTTP POST 방식으로 전달
<form action="/user/signup" method="post">
<p>이메일 : <input type="text" name="email"></p>
<p>비밀번호 : <input type="password" name="password"></p>
<p>이름 : <input type="text" name="name"></p>
<button>가입하기</button>
</form>
6. UserController.java에 doPost 메소드가 실행
@WebServlet("/user/*")
public class UserController extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//..
}
}
7. String action = req.getPathInfo(); -> 이 코드로 사용자가 접속한 주소를 확인
("/signup" 이라는 문자열이 action 변수에 저장)
String action = req.getPathInfo();
8. action 이라는 변수에 저장된 값이 "/signup"과 일치하면 User라는 모델 클래스의 객체를 생성
=> Model에 데이터를 담기 위해서
9. UserController가 하위 계층인 UserService의 메소드를 실행, 실행하면서 모델을 전달
if ("/signup".equals(action)) {
// 8. 모델 생성
User user = new User(
req.getParameter("email"),
req.getParameter("password"),
req.getParameter("name")
);
// 9. 모델 전달
userService.signup(user);
}
10. UserService가 모델을 받아서 비즈니스 로직을 처리하고 UserDao의 insertUser 메소드를 실행, 실행하면서 모델을 전달
-> 비즈니스 로직 = 서비스 코드에서 부가적인 기능 구현 (회원가입 - 비밀번호 암호화)
public void signup(User user) {
String originPassword = user.getPassword();
user.setPassword("암호화됨" + originPassword);
this.userDao.insertUser(user);
}
11. UserDao가 모델을 받아서 정해진 SQL을 실행
public boolean selectUser(User user) {
String sql = "SELECT * FROM user WHERE email = '" + user.getEmail()
+ "' AND password = '" + user.getPassword() + "'";
try {
ResultSet rs = conn.createStatement().executeQuery(sql);
if(rs.next()) {
return true;
}
return false;
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
에러 시나리오
클라이언트의 요청이 서버로 제대로 전달이 안 된다
-> UserController.java, User.java
클라이언트의 요청이 DB에 제대로 저장되지 않는다.
-> UserDao.java
DB에 저장되기는 하는데 패스워드가 암호화되지 않는다.
-> UserService.java
예를 들어 test라는 기능 추가하고 싶을 때
-> TestController.java, TestService.java, TestDao.java, Test.java 만들면 됨
DB 연동 후 테스트
테이블 생성
CREATE TABLE user (
idx INT PRIMARY KEY AUTO_INCREMENT,
email VARCHAR(50) NOT NULL UNIQUE,
password VARCHAR(200),
name VARCHAR(10) NOT NULL
);
회원가입 기능
가입하기를 누르면 DB에 잘 들어와진다.
로그인 기능
'BE > Java' 카테고리의 다른 글
[Java] DTO 설계 시 고려사항 (0) | 2025.01.10 |
---|---|
[Java] multipart/form-data란? / form 태그로 서버에 파일 전달하기 (0) | 2025.01.09 |
[Java] SQL Injection, PreparedStatement (2) | 2025.01.09 |
[Java] IntelliJ + MariaDB 연동, SQL 실행 (0) | 2025.01.08 |
[Java] IntelliJ + Tomcat 연동, Servlet 설정 (파라미터) (0) | 2025.01.08 |