Java

2024.07.10 JSP 프로그래밍 기본 JSP와 MVC 패턴 Todo 프로젝트(2)

정훈5 2024. 7. 10. 10:38

 

class_41.sql
0.00MB

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();
		}
		
		
	}
	
	

}