TodoDTO.java
package com.tenco.model;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.ToString;
@Data
@NoArgsConstructor
@AllArgsConstructor
@ToString
@Builder
public class TodoDTO {
private int id;
private int userId;
private String title;
private String description;
private String dueDate;
private String completed;
}
TodoDAO.java
package com.tenco.model;
import java.util.List;
public interface TodoDAO {
// 저장 기능
void addTodo(TodoDTO dto, int principalId);
TodoDTO getTodoById(int id);
// 사용자 아이디 기준으로 출력 todoList를 뽑는다.
List<TodoDTO> getTodosByUserId(int userId);
// 전체 리스트 출력
List<TodoDTO> getALLTodos();
// 사용자 글 업데이트
void updateTodo(TodoDTO dto, int principalId);
// 사용자 글 삭제
void deleteTodo(int id, int principalId);
}
todoForm.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>새 할 일 추가</title>
</head>
<body>
<h1> ToDo Page </h1>
<%-- http://localhost:8080/mvc/todo/add --%>
<form action="add" method="post">
<label for="title">제목: </label>
<input type="text" id="title" name="title" value="코딩연습 무한반복">
<br><br>
<label for="description">설명: </label>
<textarea rows="30" cols="30" id="description" name="description">
그래야 성공하고 높은 연봉은 기본 ... 아니면 워라벨
</textarea>
<br><br>
<label for="dueDate">마감기한: </label>
<input type="date" id="dueDate" name="dueDate" value="2024-07-11">
<br><br>
<label for="completed">완료 여부: </label>
<input type="checkbox" id="completed" name="completed"> <br>
<button type="submit">추가</button>
</form>
<br><br>
<a href="list">목록으로 돌아가기</a>
</body>
</html>
signUp.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>회원가입</title>
<!-- 상대경로 : css/styles.css -->
<link rel="stylesheet" type="text/css" href="../css/styles.css">
</head>
<body>
<h2>회원가입</h2>
<!-- 에러 메세지 출력 -->
<%
// String errorMessage = (String)request.getAttribute("message");
String errorMessage = (String)request.getParameter("message");
if(errorMessage != null){
%>
<p style="color:red"> <%=errorMessage %> </p>
<% } %>
<!-- 절대 경로로 사용 해보기 -->
<form action="/mvc/user/signUp" method="POST">
<label for="username">사용자 이름 : </label>
<input type="text" id="username" name="username" value="야스오1">
<label for="password">비밀번호</label>
<input type="password" id="password" name="password" value="1234">
<label for="email">이메일</label>
<input type="text" id="email" name="email" value="abc@nate.com">
<button type="submit">회원가입</button>
</form>
</body>
</html>
siginIn.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>로그인</title>
</head>
<body>
<!-- // http://localhost:8080/mvc/user/signIn -->
<h1>로그인 JSP 파일 입니다.</h1>
<!-- 회원 가입 성공 메세지 출력 -->
<%
// String errorMessage = (String)request.getAttribute("message");
String success = (String)request.getParameter("message");
if(success != null){
%>
<p style="color:red"> <%=success %> </p>
<% } %>
<!-- 절대 경로로 사용 해보기 -->
<form action="/mvc/user/signIn" method="POST">
<label for="username">사용자 이름 : </label>
<input type="text" id="username" name="username" value="야스오1">
<label for="password">비밀번호</label>
<input type="password" id="password" name="password" value="1234">
<button type="submit">로그인</button>
</form>
</body>
</html>
TodoController
package com.tenco.controller;
import java.io.IOException;
import com.tenco.model.TodoDAO;
import com.tenco.model.TodoDAOImpl;
import com.tenco.model.TodoDTO;
import com.tenco.model.UserDTO;
import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.servlet.http.HttpSession;
//.../mvc/todo/xxx
@WebServlet("/todo/*")
public class TodoController extends HttpServlet {
private static final long serialVersionUID = 1L;
private TodoDAO todoDAO;
public TodoController() {
todoDAO = new TodoDAOImpl(); // 업 캐스팅 된 상태
}
// http://localhost:8080/mvc/todo/form
// http://localhost:8080/mvc/todo/todoform (권장 x) (지금은 이거 사용)
// ex) http://localhost:8080/mvc/todo/formzzz
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String action = request.getPathInfo();
System.out.println("action 확인 : " +action);
switch(action) {
case "/todoForm":
todoFormPage(request, response); // ctr + 1 번 클릭 후 메서드 생성
break;
case "/list":
todoListPage(request, response); // ctr + 1 번 클릭 후 메서드 생성
default:
break;
}
}
// http://localhost:8080/mvc/todo/list
private void todoListPage(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
// 인증 검사
HttpSession session = request.getSession();
UserDTO principal = (UserDTO)session.getAttribute("principal"); // 다운캐스팅
request.getContextPath();
System.out.println("request.getContextPath() : " +request.getContextPath());
if(principal == null) {
response.sendRedirect( request.getContextPath() + "/user/sigIn?message=invaild");
return;
}
// todoList.jsp 페이지로 내부에서 이동 처리
request.getRequestDispatcher("/WEB-INF/views/todoList.jsp").forward(request, response);
}
// http://localhost:8080/mvc/user/signIn
private void todoFormPage(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
// 로그인 한 사용자만 접근을 허용하도록 설계
HttpSession session = request.getSession();
UserDTO principal = (UserDTO)session.getAttribute("principal"); // 다운캐스팅
// 인증검사
if(principal == null) {
// 로그인을 안한 상태
response.sendRedirect("/mvc/user/signIn?message=invalid");
return;
}
request.getRequestDispatcher("/WEB-INF/views/todoForm.jsp").forward(request, response);
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// todo 추가 예정
HttpSession session = request.getSession();
UserDTO principal = (UserDTO)session.getAttribute("principal");
// Princiap -- null 이라면 ---> 로그인 페이지로 이동 처리
todoDAO.addTodo(new TodoDTO(), principal.getId());
}
}
todoList.jsp
<%@page import="java.util.Date"%>
<%@page import="com.tenco.model.TodoDTO"%>
<%@page import="java.util.List"%>
<%@page import="java.util.ArrayList"%>
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>할 일 목록</title>
<link rel="stylesheet" type="text/css" href="../css/style.css">
</head>
<body>
<!-- http://localhost:8080/mvc/todo/todoList.jsp -->
<!-- http://localhost:8080/mvc/user/signIn <-- 여기서 부터 시작 -->
<!-- http://localhost:8080/mvc/todo/list -->
<%
List<TodoDTO> todoList = new ArrayList<TodoDTO>();
TodoDTO todo1 = TodoDTO.builder().id(1).title("할일1")
.description("놀기")
.dueDate(new Date())
.completed(false)
.userId(1)
.build();
TodoDTO todo2 = TodoDTO.builder().id(1).title("할일1")
.description("놀기")
.dueDate(new Date())
.completed(false)
.userId(1)
.build();
TodoDTO todo3 = TodoDTO.builder().id(1).title("할일1")
.description("놀기")
.dueDate(new Date())
.completed(false)
.userId(1)
.build();
todoList.add(todo1);
todoList.add(todo2);
todoList.add(todo3);
// out.print(todoList.toString());
if (todoList != null && !todoList.isEmpty()) {
%>
<h2>할 일 목록</h2>
<a href="todoForm"> 새 할일 추가 </a>
<table border="1">
<tr>
<th>제목</th>
<th>설명</th>
<th>마감일</th>
<th>완료여부</th>
<th>(액션-버튼)</th>
</tr>
<%
for (TodoDTO todo : todoList) {
%>
<tr>
<td><%=todo.getTitle()%></td>
<td><%=todo.getDescription()%></td>
<td><%=todo.getDueDate()%></td>
<td><%=todo.getCompleted() == "true" ? "완료" : "미완료"%></td>
<td><a href="detail?id=<%=todo.getId()%>">상세보기</a> <!-- 삭제 기능 -->
<form action="delete">
<input type="hidden" name="id" value="<%=todo.getId()%> ">
<button type="submit">삭제</button>
</form></td>
</tr>
<%
}
%>
</table>
<%
} else {
%>
<hr>
<p>등록된 할 일이 없습니다.</p>
<%
}
%>
<hr>
<p>등록된 할 일이 없습니다.</p>
</body>
</html>
TodoDAOImpl.java
package com.tenco.model;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.sql.DataSource;
public class TodoDAOImpl implements TodoDAO {
private DataSource dataSource;
public TodoDAOImpl() {
InitialContext ctx;
try {
ctx = new InitialContext();
dataSource = (DataSource)ctx.lookup("java:comp/env/jdbc/MyDB");
} catch (NamingException e) {
e.printStackTrace();
}
}
@Override
public void addTodo(TodoDTO dto, int principalId) {
// sql 작업할 때
String sql = " insert into todos(user_id, title, description, due_date, completed)"
+ "values(?, ?, ?, ?, ?) ";
try(Connection conn = dataSource.getConnection()) {
conn.setAutoCommit(false); // 자동 커밋 x 내가 직접 커밋한다.
try(PreparedStatement pstmt = conn.prepareStatement(sql)) {
pstmt.setInt(1, principalId);
pstmt.setString(2, dto.getTitle());
pstmt.setString(3, dto.getDescription());
pstmt.setString(4, dto.getDueDate()); // TodoDTO의 util을 sql로 변경
pstmt.setString(5, dto.getCompleted());
pstmt.executeUpdate();
conn.commit(); // 커밋
} catch (Exception e) {
e.printStackTrace();
conn.rollback();
}
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
}
@Override
public TodoDTO getTodoById(int id) {
String sql = " SELECT * FROM todos WHERE id = ? ";
TodoDTO dto = null;
try(Connection conn = dataSource.getConnection();) {
PreparedStatement pstmt = conn.prepareStatement(sql);
pstmt.setInt(1, id);
try(ResultSet rs = pstmt.executeQuery()) {
if(rs.next()) {
dto = new TodoDTO();
dto.setId(rs.getInt("id"));
dto.setUserId(rs.getInt("user_id"));
dto.setTitle(rs.getString("title"));
dto.setDescription(rs.getString("description"));
dto.setDueDate(rs.getString("due_date"));
dto.setCompleted(rs.getString("Completed"));
}
} catch (Exception e) {
e.printStackTrace();
}
} catch (Exception e) {
e.printStackTrace();
}
return dto;
} // end of getTodoById()
// ------------------------------------------------
@Override
public List<TodoDTO> getTodosByUserId(int userId) {
String sql = " SELECT * FROM todos WHERE id = ? ";
List<TodoDTO> list = new ArrayList<>();
TodoDTO todoDTO = new TodoDTO();
try(Connection conn = dataSource.getConnection();) {
try(PreparedStatement pstmt = conn.prepareStatement(sql)) {
pstmt.setInt(1, userId);
conn.setAutoCommit(false); // 자동 커밋을 수동으로 변경
ResultSet rs = pstmt.executeQuery(); // rs 에 쿼리 들어가있음
while(rs.next()) {
todoDTO.setId(rs.getInt("id"));
todoDTO.setTitle(rs.getString("title"));
todoDTO.setDescription(rs.getString("description"));
todoDTO.setDueDate(rs.getString("due_date"));
todoDTO.setCompleted(rs.getString("completed"));
todoDTO.setUserId(rs.getInt("user_id"));
list.add(todoDTO);
conn.commit();
}
} catch (Exception e) {
e.printStackTrace();
conn.rollback();
}
} catch (SQLException e) {
e.printStackTrace();
}
return list;
} // end of getTodosByUserId()
@Override
public List<TodoDTO> getALLTodos() {
String sql = " SELECT * FROM todos; ";
List<TodoDTO> list = new ArrayList<>(); // 모든 게시글을 보기 위해서는 리스트를 사용한다.
TodoDTO todoDTO = null; // null 값 오류 방지?
try(Connection conn = dataSource.getConnection();) { // db 연결
// preparestatemet에 db에 연결하고 sql 쿼리문을 던진다.
PreparedStatement pstmt = conn.prepareStatement(sql);
// pstmt 쿼리문을 executeQuery 실행한다.
ResultSet resultSet = pstmt.executeQuery();
System.out.println(resultSet);
while(resultSet.next()) {
todoDTO = new TodoDTO();
todoDTO.setId(resultSet.getInt("id"));
todoDTO.setUserId(resultSet.getInt("user_id"));
todoDTO.setTitle(resultSet.getString("title"));
todoDTO.setDescription(resultSet.getString("description"));
todoDTO.setDueDate(resultSet.getString("due_date"));
todoDTO.setCompleted(resultSet.getString("completed"));
todoDTO.setUserId(resultSet.getInt("user_id"));
list.add(todoDTO);
}
} catch (SQLException e) {
e.printStackTrace();
}
return list;
} // end of getALLTodos()
@Override
public void updateTodo(TodoDTO dto, int principalId) {
String sql = " UPDATE todos SET title = ?, description = ? WHERE id = ? ";
dto = new TodoDTO();
try(Connection conn = dataSource.getConnection()) {
PreparedStatement pstmt = conn.prepareStatement(sql);
pstmt.setString(1, "구름" );
pstmt.setString(2, "날씨가 맑다" );
pstmt.setInt(3, principalId);
pstmt.executeUpdate();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} // end of updateTodo()
@Override
public void deleteTodo(int id, int principalId) {
String sql = "delete from todos where id = ? and user_id = ? ";
try {
Connection conn = dataSource.getConnection();
PreparedStatement pstmt = conn.prepareStatement(sql);
pstmt.setInt(1, id);
pstmt.setInt(2, principalId);
pstmt.executeUpdate();
} catch (SQLException e) {
e.printStackTrace();
}
}
}