JSP서블릿 11일차

한 일

  • Todo App -4-
  • 할일 삭제
  • 로그아웃하면 세션의 로그인 정보삭제하기
  • todo리스트의 현재상태를 진행중, 완료됨 으로 출력하기
  • 할일 목록 진행상태에 따른 파이차트 추가하기

Todo App 만들기 -4-

할일 삭제

todo-list.jsp페이지의 forEach문 아래의 삭제에 해당하는 a태그의 속성을 추가하여 사용자의 확인을 한 번 받은 후 TodoController서블릿의 deleteTodo메서드로 넘어감

-todo-list.jsp-

<c:forEach var="todo" items="${listTodo}">
  <tr>
    <td><c:out value="${todo.title}" /></td>
    <td><c:out value="${todo.targetDate}" /></td>
    <td><c:out value="${todo.status}" /></td>
    <td>
      <a href="<%=request.getContextPath()%>/todos?action=edit&id=<c:out value='${todo.id}'/>" class="btn btn-outline-info btn-sm">수정</a>
      <a href="<%=request.getContextPath()%>/todos?action=delete&id=<c:out value='${todo.id}'/>" onclick="if(!confirm('정말로 삭제하시겠습니까?')) return false" class="btn btn-outline-danger btn-sm">삭제</a>
      <!-- ㄴ자바스크립트가 먼저 동작하므로 confirm창에서 확인을 누르면 a태그의 주소로 값이 넘어가 메서드를 차례로 실행하게 된다. 취소를 누르면 false값을 받도록 작성하여 아무일도 없도록 함 -->
    </td>
  </tr>
</c:forEach>


위 사진처럼 확인 창이 뜨고 '확인'을 누르면 action속성에 값을 가지고 doGet메서드로 이동한다.
'취소'를 누를 경우 값이 false가 되도록 하였으므로 동작이 없다.

-TodoController서블릿 doGet메서드-

// 요청주소가 localhost:8090/TODO/new 이면 => "/new"가 action의 값이 된다(ContextPath의 주소 이후만 action에 넣는다는뜻)
String action = request.getParameter("action");	 // 주소가 TODO/todos?=text일때 text의 값을 action에 저장
System.out.println(action);

switch(action) {
case "new":
	showNewForm(request, response);
	break;
case "post":
	insertTodo(request, response);
	break;
case "delete":
	deleteTodo(request, response);
	break;
case "edit":	// 수정form을 보여줌
	showEditForm(request, response);
	break;
case "update":
	updateTodo(request, response);
	break;
case "list":	// localhost:8090/TODO/todos/list
	listTodo(request, response);
	break;
default:	// 요청 주소가 기본(/)이거나 잘못되었을 경우, action이 없을때 로그인 페이지로 이동. 로그아웃시에도 여기로 오게된다.
	HttpSession session = request.getSession();
	session.invalidate();	// session에 저장된 로그인 정보를 전체삭제
	RequestDispatcher dispatcher = request.getRequestDispatcher("login/login.jsp");
	dispatcher.forward(request, response);
	break;
}// switch문 끝

여기서 delete에 해당하므로 같은 서블릿의 deleteTodo메서드로 이동

-TodoController서블릿 deleteTodo메서드-

private void deleteTodo(HttpServletRequest request, HttpServletResponse response) throws IOException {
	// 삭제기능은 js를 통해 한번 확인작업을 거치는데 자바스크립트가 먼저 동작하기때문에 confirm창에서 확인을 눌러야 여기까지넘어오게 된다
	Long id = Long.parseLong(request.getParameter("id"));	// id를 받음
	todoDAO.deleteTodo(id);
	response.sendRedirect("todos?action=list");	// 삭제 후 다시 todo-list.jsp페이지로 돌아감
}

받아온 id값을 이용해 deleteTodo메서드로 해당 id의 DB의 데이터 한 행을 삭제한다.
삭제 후 단순 페이지 이동으로 todo-list.jsp페이지로 돌아가 현재 DB에 저장된 할일을 다시 출력한다.


로그아웃하면 세션의 로그인 정보삭제하기

로그아웃버튼을 누르면 action=logout의 값이 TodoController서블릿 doGet메서드로 넘어가 default로 설정된 값이 동작하게 된다.(바로위의 doGet메서드 참고)

-TodoController서블릿 doGet메서드의 일부-

// 요청 주소가 기본(/)이거나 잘못되었을 경우, action이 없을때 로그인 페이지로 이동. 로그아웃시에도 여기로 오게된다.
default:
	HttpSession session = request.getSession();
	session.invalidate();	// session에 저장된 로그인 정보를 전체삭제
	RequestDispatcher dispatcher = request.getRequestDispatcher("login/login.jsp");
	dispatcher.forward(request, response);
	break;
  • 세션에 저장된 정보 전체삭제: session.invalidate()

invalidate()는 세션에 저장된 모든 정보를 삭제할 수 있는 메서드로,
session.invalidate() 과정을 거치면 세션에 저장되어있던 로그인 정보가 모두 삭제된다.
세션이 삭제된 후 forward로 login.jsp로 페이지를 이동한다.

참고. 세션에서 key값을 삭제할때:
session.removeAttribute(String key)


로그아웃을 마치면 login.jsp페이지로 forward방식으로 이동하게 된다.

질문.이전 페이지에서 반드시 받아와야하는 값이 없으므로 sendRedirect로 단순이동만 해도 괜찮지 않을까?


todo리스트의 현재상태를 진행중, 완료됨 으로 출력하기

자바스크립트를 이용해 true이면 '완료됨', false이면 '진행중'으로 표시하도록 수정.

-todo-list.jsp-

<tr>
  <td><c:out value="${todo.title}" /></td>
  <td><c:out value="${todo.targetDate}" /></td>
  <td class="status"><c:out value="${todo.status}" /></td>
  <td>
    <a href="<%=request.getContextPath()%>/todos?action=edit&id=<c:out value='${todo.id}'/>" class="btn btn-outline-info btn-sm">수정</a>
    <a href="<%=request.getContextPath()%>/todos?action=delete&id=<c:out value='${todo.id}'/>" onclick="if(!confirm('정말로 삭제하시겠습니까?')) return false" class="btn btn-outline-danger btn-sm">삭제</a>
    <!-- ㄴ자바스크립트가 먼저 동작하므로 confirm창에서 확인을 누르면 a태그의 주소로 값이 넘어가 메서드를 차례로 실행하게 된다. 취소를 누르면 false값을 받도록 작성하여 아무일도 없도록 함 -->
  </td>
</tr>
~~~ 생략 ~~~
<script src="<%=request.getContextPath()%>/js/todo.js"></script>

현재상태 항목인 3번째 td에 status클래스 부여.
맨 아래 script 링크에 todo.js링크 추가.

-todo.js-

const statuses = document.querySelectorAll('.status'); // status클래스들을 변수 status에 배열로 저장
statuses.forEach((td) => {
  if (td.textContent == 'false') td.textContent = '진행중';
  else td.textContent = '완료됨';
});

querySelectorAll로 status클래스를 가진 모든 항목을 변수 statuses에 배열로 저장.
forEach문을 통해 모든 값을 if문으로 검사해 text가 false이면 '진행중', true이면 '완료됨'으로 수정해줌.

=> 수정하면 현재상태가 진행중, 완료됨 중 하나의 문구를 출력한다.


할일 목록 진행상태에 따른 파이차트 추가하기

파이차트 참고사이트 링크
진행중, 완료의 갯수에 따라 파이차트로 표기.

-todo-list.jsp-

<br />
<table class="table table-bordered">
~~~ 생략 ~~~
</table>
<div class="row mt-5">
  <div class="col-4 mx-auto">
    <canvas id="myChart"></canvas>
  </div>
</div>
~~~ 생략 ~~~
<script src="<%=request.getContextPath()%>/js/bootstrap.bundle.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<script src="<%=request.getContextPath()%>/js/todo.js"></script>

table태그가 끝나는 아래 div클래스 추가.
bootstrap.bundle.js파일 링크아래에 chart.js링크 추가.

-todo.js-

let 진행 = 0;
let 완료 = 0;

statuses.forEach((td) => {
  if (td.textContent == 'false') {
    진행++;
    td.textContent = '진행중';
  } else {
    완료++;
    td.textContent = '완료됨';
  }
});
const data = {
  labels: ['진행중', '완료됨'],
  datasets: [
    {
      label: 'My First Dataset',
      data: [진행, 완료],
      backgroundColor: ['rgb(255, 99, 132)', 'rgb(54, 162, 235)'],
      hoverOffset: 4,
    },
  ],
};

const config = { type: 'pie', data: data, };
const myChart = new Chart(document.getElementById('myChart'), config);

todo.js파일에 코드를 추가, 수정.
forEach반복문을 통해 모든 .status들이 if-else문을 통해 true와 false를 판별할 때 각각 변수 '진행'과 '완료'에 1씩 더해 파이차트에 비율을 반영한다.

=> 결과화면.

좋은 웹페이지 즐겨찾기