1. 클라이언트에서 서버에 Request(요청)
2. 요청 Filter를 지나 Dispatcher Servlet에 도착
3. Dispatcher Servlet에서 핸들러(컨트롤러) 매핑 뒤 반환
4. Dispatcher Servlet에서 매핑하여 반환한 컨트롤러로 인터셉터를 거쳐 요청 전달, 컨트롤러에서 의존성 주입을 위한 xxService 접근
5. DB 접근을 위해 xxDao(Repository)로 접근
6. JDBC 또는 MyBatis를 이용해 DB 접근
7. 값을 가지고 다시 쭉쭉 뒤로 돌아오다가 Controller에서 ModelAndView 혹은 String(viewName)으로 반환
8. Dispatcher Servlet으로 반환 도중 또 한번 인터셉터를 거친다.
9. viewResolver로 요청 후 Dispatcher Servlet으로 응답 반환
10. Model을 가지고 view로 이동, 가져올 view를 찾아 Dispatcher Servlet으로 반환
11. 마지막으로 서버에서 필터를 거쳐 클라이언트로 Response(응답)
👍 ViewResolver와 View를 거치는 대신 REST API를 뽑아내는 과정을 조만간 할 것이다.
👍 기존의 Board에 User와 관련된 기능들을 덧붙였다. 예를 들어 Login이나 유저를 확인하는 관리자 페이지 등이 있다.
👍 기존의 user 테이블에 curriculum 테이블을 추가하며 데이터베이스를 수정하였다.
CREATE TABLE board (
id INT AUTO_INCREMENT,
writer VARCHAR(20) NOT NULL,
title VARCHAR(50) NOT NULL,
content TEXT,
view_cnt INT DEFAULT 0,
reg_date TIMESTAMP DEFAULT now(),
PRIMARY KEY(id)
);
INSERT INTO board(title, writer, content)
VALUES ("BackEnd easy해","박씨","너도 할 수 있어"),
("누르지마시오", "따봉맨", "아무내용없음"),
("나는 원딜장인", "bzeromo", "근데 탑을 더 좋아해");
CREATE TABLE `curriculum` (
`code` INT NOT NULL PRIMARY KEY,
`name` VARCHAR(40) NOT NULL
)ENGINE=InnoDB;
CREATE TABLE IF NOT EXISTS `users` (
`id` varchar(40) NOT NULL,
`password` varchar(40) NOT NULL,
`name` varchar(40) NOT NULL,
`curriculum_code` INT NOT NULL,
CONSTRAINT `curriculum_fk` FOREIGN KEY (`curriculum_code`) REFERENCES `curriculum`(`code`),
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARACTER SET = utf8mb4;
INSERT INTO `curriculum`
VALUES (100, 'Python'), (200, 'Java'), (300, 'Embedded'), (400, 'Mobile');
INSERT INTO users
VALUES ("bzeromo", "1234", "박영규", 200);
commit;
SELECT * FROM users;
🖥 userList.jsp (관리자 페이지)
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>관리자 페이지</title>
<%@ include file="../common/bootstrap.jsp" %>
</head>
<body>
<div class="container">
<h2>회원 목록</h2>
<hr>
<table class="table text-center">
<tr>
<th>ID</th>
<th>PW</th>
<th>NAME</th>
<th>CURRICULUM</th>
</tr>
<c:forEach items="${userList }" var="user">
<tr>
<td>${user.id }</td>
<td>${user.password }</td>
<td>${user.name }</td>
<td>${user.curriculumName }</td>
</tr>
</c:forEach>
</table>
<div class="d-flex justify-content-end">
<a href="${pageContext.request.contextPath }" class="btn btn-outline-warning">홈으로</a>
</div>
</div>
</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>로그인</title>
<%@ include file="../common/bootstrap.jsp" %>
</head>
<body>
<div class="container">
<h2>로그인</h2>
<form action="login" method="POST">
<div class="mb-3">
<label for="id" class="form-label">ID</label>
<input type="text" class="form-control" id="id" name="id">
</div>
<div class="mb-3">
<label for="password" class="form-label">PW</label>
<input type="password" class="form-control" id="password" name="password">
</div>
<button class="btn btn-primary">로그인</button>
</form>
</div>
</body>
</html>
🖥 header.jsp (로그인 여부에 따라 헤더가 달라진다)
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<div>
<c:if test="${empty loginUser }">
<a href="login" class="btn btn-outline-primary">login</a>
<a href="signup" class="btn btn-outline-secondary">sign up</a>
</c:if>
<c:if test="${not empty loginUser }">
${loginUser }님 환영합니다.
<a href="logout" class="btn btn-outline-danger">logout</a>
<c:if test="${'admin' eq loginUser }">
<a href="users">관리자 페이지</a>
</c:if>
</c:if>
</div>
Header는 다른 페이지들 상단에 위치하도록 모든 페이지에 해당 코드를 추가하였다.
<%@ include file ="../common/header.jsp" %>
View 추가는 이정도고, 다음은 user 관련 마이바티스 및 자바 로직이다.
🖥 userMapper.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ssafy.board.model.dao.UserDao">
<!-- 커리큘럼 이름을 가지고 오려면 조인이 필요하다 -->
<select id="selectAll" resultType="User">
SELECT id, password, u.name AS name,
curriculum_code AS curriculumCode,
c.name AS curriculumName
FROM users u, curriculum c
WHERE curriculum_code = code
</select>
<insert id="insertUser" parameterType="User">
INSERT INTO users
VALUES(#{id}, #{password}, #{name}, #{curriculumCode})
</insert>
<select id="selectOne" parameterType="String" resultType="User">
SELECT id, password, name
FROM users
WHERE id = #{id}
</select>
</mapper>
🖥 com.bzeromo.board.model.dto.User
package com.bzeromo.board.model.dto;
public class User {
private String id;
private String password;
private String name;
private int curriculumCode;
private String curriculumName;
public User() {
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
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;
}
public int getCurriculumCode() {
return curriculumCode;
}
public void setCurriculumCode(int curriculumCode) {
this.curriculumCode = curriculumCode;
}
public String getCurriculumName() {
return curriculumName;
}
public void setCurriculumName(String curriculumName) {
this.curriculumName = curriculumName;
}
@Override
public String toString() {
return "User [id=" + id + ", password=" + password + ", name=" + name + ", curriculumCode=" + curriculumCode
+ ", curriculumName=" + curriculumName + "]";
}
}
🖥 com.bzeromo.board.controller.UserController
package com.bzeromo.board.controller;
import javax.servlet.http.HttpSession;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import com.bzeromo.board.model.dto.User;
import com.bzeromo.board.model.service.UserService;
@Controller
public class UserController {
//UserService 주입
@Autowired
private UserService userService;
@GetMapping("users")
public String userList(Model model) {
model.addAttribute("userList", userService.getUserList());
return "/user/userList";
}
@GetMapping("signup")
public String signupForm() {
return "/user/signupform";
}
@PostMapping("signup")
public String signup(User user) {
userService.signup(user);
return "redirect:list";
}
@GetMapping("login")
public String loginForm() {
return "/user/loginform";
}
@PostMapping("login")
public String login(User user, HttpSession session) {
User tmp = userService.login(user);
//로그인 실패 시
if(tmp == null)
return "redirect:login";
session.setAttribute("loginUser", tmp.getName());
return "redirect:list";
}
@GetMapping("logout")
public String logout(HttpSession session) {
session.invalidate();
return "redirect:list";
}
}
🖥 com.bzeromo.board.model.dao.userDao
package com.bzeromo.board.model.dao;
import java.util.List;
import com.bzeromo.board.model.dto.User;
public interface UserDao {
List<User> selectAll();
void insertUser(User user);
User selectOne(String id);
}
🖥 com.bzeromo.board.model.service.userService
package com.bzeromo.board.model.service;
import java.util.List;
import com.bzeromo.board.model.dto.User;
public interface UserService {
List<User> getUserList();
void signup(User user);
User login(User user);
}
🖥 com.bzeromo.board.model.service.userServiceImpl
package com.bzeromo.board.model.service;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.bzeromo.board.model.dao.UserDao;
import com.bzeromo.board.model.dto.User;
@Service
public class UserServiceImpl implements UserService{
@Autowired
private UserDao userDao;
@Override
public List<User> getUserList() {
return userDao.selectAll();
}
@Override
public void signup(User user) {
userDao.insertUser(user);
}
@Override
public User login(User user) {
//DB 해당 ID만 넘겨서 데이터 가지고 오고 가지고 온 User 데이터와 내가 현재 가진 user의 비밀번호 비교
User tmp = userDao.selectOne(user.getId());
if(tmp != null && tmp.getPassword().equals(user.getPassword()))
return tmp;
return null;
}
}
🖨 결과물
로그인을 하면
헤더가 바뀌며 현재 로그인한 유저의 이름과 로그아웃 버튼이 뜬다.
다음은 회원가입이다.
admin 계정으로 로그인하면 헤더에서 관리자페이지를 확인할 수 있다.
관리자 페이지에서 유저 정보를 확인할 수 있다.
REST API를 어서 배우고 싶다.
View 작업을 프론트엔드 선생님들에게 던지고 싶은 마음이 굴뚝같다. 정말.
맞다 나 프론트 출신이지...