본문 바로가기

BackEnd/Spring

[코드로 배우는 스프링 웹 프로젝트] ch11 화면 처리 3

728x90
반응형

https://bobo12.tistory.com/303

 

(2) 재전송(redirect) 처리 및 모달(Modal)창 보여주기

   ▷ 등록 과정에서 POST 방식으로 데이터가 처리되는 과정을 그림으로 표현하면 아래와 같음


▷ BoardController에서 register() 메소드는 'redirect:/board/list'를 전송하는데 브라우저는 이를 통보 받은 후 '/board/list'로 이동

 만약 위와 같이 재전송을 하지 않으면 사용자는 브라우저의 '새로고침'을 통해 동일한 내용을 계속 서버에 등록할 수 있어서 문제가 발생함.

 브라우저에서는 이런 경우 경고창을 보여주기는 하지만 근본적으로 차단하지는 않음
따라서 등록, 수정, 삭제 작업은 처리가 완료된 후 다시 동일한 내용을 전송할 수 없도록 브라우저의 URL을 이동하는 방식을 이용

 

◎ list.jsp 수정

   ▷ 페이지의 아래쪽에 <script> 태그를 이용해서 상황에 따른 메시지를 확인할 수 있음

◎ 모달창 html 및 css 적용

   <!-- Modal  추가 -->
	<div class="modal fade" id="myModal" tabindex="-1" role="dialog"
		aria-labelledby="myModalLabel" aria-hidden="true">
		<div class="modal-dialog">
			<div class="modal-content">
				<div class="modal-header">
					<button type="button" class="close" data-dismiss="modal"
						aria-hidden="true">&times;</button>
					<h4 class="modal-title" id="myModalLabel">Modal title</h4>
				</div>
				<div class="modal-body">처리가 완료되었습니다.</div>
				<div class="modal-footer">
					<button type="button" class="btn btn-default"
						data-dismiss="modal">Close</button>
					<button type="button" class="btn btn-primary">Save
						changes</button>
				</div>
			</div>
			<!-- /.modal-content -->
		</div>
		<!-- /.modal-dialog -->
	</div>
	<!-- /.modal -->



◎ 모달창 jQuery 처리

...(생략)...

<script type="text/javascript">
	$(document).ready(function(){
		var result = '<c:out value="${result}"/>';
		
		checkModal(result);
		
		function checkModal(result) {
			if (result === '') {
				return;
			}
			
			if (parseInt(result) > 0) {
				$(".modal-body").html("게시글 " + parseInt(result) + " 번이 등록되었습니다.");
			}
			$("#myModal").modal("show");
		}
	});
</script>

<%@include file="../includes/footer.jsp" %>



수정했을 시 '/board/list'로 이동하면서 모달창이 보입니다.

 

 

(3) 목록에서 버튼으로 이동하기

   ▷ 목록 페이지 상단에 버튼을 추가해 등록 작업이 가능하도록 함

 

◎ list.jsp 수정

◎ HTML 구조 수정

<div class="panel-heading">Board List Page
   <button id='regBtn' type="button" class="btn btn-xs pull-right">Register New Board</button>
</div>


◎ jQuery 버튼 동작 정의

<script type="text/javascript">
	$(document).ready(
		function() {
			var result = '<c:out value="${result}"/>';
			checkModal(result);

			history.replaceState({}, null, null);

			function checkModal(result) {

				if (result === '' || history.state) {
					return;
				}

				if (parseInt(result) > 0) {
					$(".modal-body").html(
							"게시글 " + parseInt(result)
									+ " 번이 등록되었습니다.");
				}

				$("#myModal").modal("show");
			}						
			$("#regBtn").on("click", function() {

				self.location = "/board/register";

			});
});
</script>

 


Register New Board를 누르면 Board Register(http://localhost:8080/board/register) 페이지로 넘어갑니다.

 

 

4. 조회 페이지와 이동

   ▷ 목록 페이지에서 링크를 통해 get 방식으로 특정한 번호의 게시물을 조회할 수 있는 기능 작성

 

(1) 조회 페이지 작성

   ▷ 입력 페이지와 유사하지만 게시물 번호(bno)가 출력된다는 점, 모든 데이터가 읽기 전용으로 처리된다는 점이 다름

 

◎ src/main/java → org.codehows.controller → BoardController 메소드 추가

...(생략)...
	@GetMapping("/get")
	public void get(@RequestParam("bno") Long bno, Model model) {
		
		log.info("/get");
		model.addAttribute("board", service.get(bno));
	}
}

 

◎ src/main/webapp/WEB-INF/views/board → get.jsp 생성

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %>
<%@ include file="../includes/header.jsp" %>

<div class="row">
	<div class="col-lg-12">
		<h1 class="page-header">Board Read</h1>
	</div>
</div>
<!-- /.row -->

<div class="row">
	<div class="col-lg-12">
		<div class="panel panel-default">
		
			<div class="panel-heading">Board Read Page</div>
			<!-- /.panel-heading -->
			<div class="panel-body">
				
				<div class="form-group">
		          <label>Bno</label> <input class="form-control" name='bno'
		            value='<c:out value="${board.bno }"/>' readonly="readonly">
		        </div>
						
				<div class="form-group">
		          <label>Title</label> <input class="form-control" name='title'
		            value='<c:out value="${board.title }"/>' readonly="readonly">
		        </div>
				
				<div class="form-group">
		          <label>Text area</label>
		          <textarea class="form-control" rows="3" name='content'
		            readonly="readonly"><c:out value="${board.content}" /></textarea>
		        </div>
				
				<div class="form-group">
					<label>Writer</label> <input class="form-control" name='writer'
					  value='<c:out value="${board.writer}"/>' readonly="readonly" >
				</div>
				
				<button data-oper='modify' class="btn btn-default"
					onclick="location.href='/board/modify?bno=<c:out value="${board.bno}"/>'">Modify</button>
				<button data-oper='list' class="btn btn-default"
					onclick="location.href='/board/list'">List</button>
					
				<form id='operForm' action="/board/modify" method="get">
					<input type='hidden' id='bno' name='bno' value='<c:out value="${board.bno}"/>'>
				</form>
							
			</div>		
			<!--  end panel-body -->
		</div>
		<!--  end panel-body -->
	</div>
	<!--  end panel -->
</div>
<!--  /.row -->


<!-- /board/list 와 /board/modify?bno=xx 와 같이 이동하는 링크 추가 -->
<script type="text/javascript">
$(document).ready(function() {
	var operForm = $("#operForm");
	
	$("button[data-oper='modify']").on("click", function(e){
		operForm.attr("action","/board/modify").submit();
	});
	
	$("button[data-oper='list']").on("click", function(e){
		operForm.find("#bno").remove();
		operForm.attr("action","/board/list")
		operForm.submit();
	});
})
</script>

<%@include file="../includes/footer.jsp" %>


http://localhost:8080/board/get?bno=1

위의 경로로 접속시 아래와 같이 해당 게시물의 내용을 볼 수 있는 페이지로 넘어갑니다.

 

(2) 목록에서 조회 페이지로 이동

 

◎ list.jsp 페이지 수정

<tr>
	<td><c:out value="${board.bno}" /></td>
	<td><a href='/board/get?bno=<c:out value="${board.bno}"/>' ><c:out value="${board.title}" /></a></td>
	<td><c:out value="${board.writer}" /></td>
	<td><fmt:formatDate pattern="yyyy-MM-dd" value="${board.regDate}" /></td>
	<td><fmt:formatDate pattern="yyyy-MM-dd" value="${board.updateDate}" /></td>
</tr>

 

◎ 뒤로 가기의 문제

   ▷ 동일한 페이지 내에서 목록 페이지와 조회 페이지의 이동은 정상적으로 처리된 것 같아 보이지만 한 가지 문제가 있음

   ▷ '등록 -> 목록 -> 조회' 까지는 순조롭지만 브라우저의 뒤로가기를 선택하는 순간 다시 게시물의 등록 결과를 확인하는 방식으로 동작한다는 것

 

 

   ▷ 원인은 브라우저에서 뒤/앞으로 가기를 하면 서버를 다시 호출하는게 아니라 과거에 자신이 가진 모든데이터를 활용하기 때문

   ▷ 브라우저에서 조회/목록 페이지를 여러번 앞뒤로 이동해도 서버에서는 처음 호출을 제외하고 별 다른 변화가 없는 것을 확인할 수 있음

 

   ▷ 문제를 해결하려면 window의 history 객체를 이용해서 현재 페이지는 모달창을 띄울 필요가 없다고 표시를 해 두는 방식을 이용해야 함

 

◎ list.jsp 수정

   ▷ window.history 객체를 조작하는 것은 이론으로 복잡해 보이지만 코드는 약간의 변화만 있음

... (생략) ...

<script type="text/javascript">
	$(document).ready(function(){
		var result = '<c:out value="${result}"/>';
		
		checkModal(result);
		
		history.replaceState({},null,null);	<< 추가
		
		function checkModal(result) {
			if (result === '' || history.state) {		<< 수정
				return;
			}
			
			if (parseInt(result) > 0) {
				$(".modal-body").html("게시글 " + parseInt(result) + " 번이 등록되었습니다.");
			}
			$("#myModal").modal("show");
		}
		$("#regBtn").on("click", function() {
			self.location ="/board/register";
		});
	});
</script>

 

list.jsp 내용을 수정하면서 테이블값의 목록을 출력 및 조회의 기능을 사용할 수 있게 만들었습니다.

 

이어서 내용들을 추가해볼게요!!

 

많은 분들의 피드백은 언제나 환영합니다!  많은 댓글 부탁드려요~~

 

 

 

728x90
반응형