-
[3-ch11 Spring view] 게시판 목록, 등록 jsp 화면 처리하기, jQuery 통해 Modal 창 띄우기Back-End/Spring Legacy 2022. 8. 24. 16:46
화면 처리 템플릿
화면을 개발하기 전에는 반드시 전체 레이아웃이나 디자인이 반영된 상태에서 개발하는 것을 추천한다. 웹 디자이너가 같이 참여하지 못한다면 BootStrap을 이용한 무료 디자인을 찾아보는 것도 좋다. 오늘 포스팅할 페이지들은 모두 아래 파일을 베이스로 잡아두었다.
목록 페이지 작업과 includes
스프링 MVC의 JSP를 처리하는 설정을 servlet-context.xml에 아래와 같이 작성되어 있다.
<beans:bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <beans:property name="prefix" value="/WEB-INF/views/" /> <beans:property name="suffix" value=".jsp" /> </beans:bean>
스프링 MVC의 설정에서 화면 설정은 ViewResolver라는 객체를 통해 이뤄지는데, 위의 설정을 보면 '/WEB-INF/viesws'를 이용하는 것을 볼 수 있다. WEB-INF 경로는 브라우저에서 직접 접근할 수 없는 경로이므로 반드시 Controller를 이용하는 모델 2방식에서 기본적으로 사용하는 방식이다.
list.jsp 파일을 /WEB-INF/viesws/board 경로에 추가한다.
WAS를 실행해서 경로를 입력할 때 /controller라는 경로를 갖게 되는데 이는 Tomcat 설정에서 web setting을 통해 /로 변경해줘야 한다. 그래야 나중에 혼돈이 없음.
resources
org.zerock.config.WebConfig 클래스에는 CSS나 JS 파일과 같이 정적인(static) 자원들의 경로를 'resources'라는 경로로 지정하고 있다.
<resources mapping="/resources/**" location="/resources/" />
src\main\webapp\resources 폴더 내 위의 파일의 압축을 풀어 모두 복사해서 넣는다. resources가 여러개 있기 때문에 넣을 때 경로 주의한다.
header, footer
jsp를 작성할 때 많은 양의 HTML 코드를 이용하는 것을 피하기 위해 JSP의 include 지시자를 활용해서 페이지 제작 시에 필요한 내용만을 작성할 수 있게 사전 작업을 해야한다.
header, footer 모두 작성했다면 list.jsp 같이 메인 jsp 파일에 <%@include file="../includes/header.jsp"%> 이렇게 윗부분에 넣어줘야 한다. footer는 아랫부분에!
컨트롤러에서 Model에 저장한 값 출력
'/board/list'를 실행했을 때 이미 BoardController는 Model을 이용해 게시물의 목록을 'list'라는 이름으로 담아서 전달했으므로 list.jsp에서는 이를 출력한다. 출력은 JSTL을 이용해서 처리한다.
위의 그림을 설명해보자면 )
1. 사용자가 board/list라는 url을 호출했다.
2. 컨트롤러에 mapping이 list인 메서드가 실행되는 것.
3. service.getList()가 Service 인터페이스를 호출한다.
4. Service 인터페이스는 BoardServiceImpl에서 재정의
5. getList() 메서드에서 mapper.getList()를 호출한다.
6. BoardMapper 인터페이스의 getList() 메서드 호출
7. BoardMapper.xml에서 select id가 getList인 쿼리문 실행 tbl_board에서 bno>0인 행들, 데이터들을 조회해서 다시 service에게 값을 반환
즉) controller -> service -> mapper -> service -> controller -> list.jsp
8. list.jsp에서 컨트롤러의 키가 list인 model 속성에 getList를 통해 조회한, 게시글 목록을 저장한다. 이말은 list라는 key에 value 값으로 저장한다.
9. list.jsp에서 el 표현식을 사용해 list에 저장된 각각 속성값( title, content, bno ,,,,,, )들을 화면에 출력한다.
등록 입력 페이지와 등록 처리
게시물의 등록 작업은 POST 방식으로 처리하지만, 화면의 입력을 받아야 하므로 GET 방식으로 입력 페이지를 볼 수 있도록 BoardController에 메서드를 추가한다.
@GetMapping("/register") public void register() { }
그다음 게시물을 등록하기위한 view 화면 register.jsp 페이지를 만들어 준다.
register.jsp 페이지에서는 <form> 태그를 이용해 필요한 데이터를 전송한다 .form 태그에서 action은 submint 버튼을 클릭했을 때 사용자가 입력한 값들이 전송되는 페이지를 말한다. post 방식으로 전송되므로 컨트롤러에서 아래 메서드가 호출된다.
@PostMapping("/register") public String register(BoardVO board, RedirectAttributes rttr) { log.info("register........" + board); service.register(board); rttr.addFlashAttribute("result", board.getBno()); return "redirect:/board/list"; }
<input>이나 <textarea>의 name 속성은 BoardVO 클래스의 변수와 일치시켜 준다.
<%@ 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 Register</h1> </div> </div> <div> <div class="col-lg-12"> <div class="panel-heading">Board Register</div> <div class="panel-body"> <form role="form" action="/board/register" method="post"> <div class="form-group"> <label>Title</label> <input class="form-control" name='title'> </div> <div class="form-group"> <label>Text area</label> <textarea class="form-control" rows="3" name='content'></textarea> </div> <div class="form-group"> <label>Writer</label> <input class="form-control" name='writer'> </div> <button type="submit" class="btn btn-default">Submit Button</button> </form> </div> </div> </div> <%@include file="../includes/footer.jsp" %>
제출 버튼을 클릭하면 BoardController에서 register() 메서드에 의해 반환할 view 페이지가 보여지게 되는데 register()는 redirect 시키는 방식을 사용하므로, 게시물 등록 시킨 후 '/board/list'로 이동하게 된다.
BaordConroller에서 redirect를 처리할 때 RedirectAttributes라는 특별한 타입의 객체를 이용한다. addFlashAttribute()의 경우 이러한 처리에 적합한데, 그 이유는 일회성으로 데이터를 전달하기 때문이다. addFlashAttribute()로 보관된 데이터는 단 한 번만 사용할 수 있게 보관된다.
list.jsp 페이지 아래쪽에 <script> 태그를 이용해 상황에 따른 메시지를 확인할 수 있다.
<script type="text/javascript"> $(document).ready( function() { //컨트롤러에서 bno 값을 result에 저장해뒀다. //c:out을 쓰는 이유는 크로스 사이트 스크립팅 방지하기 위해서 var result = '<c:out value="${result}"/>'; }); </script>
새로운 게시물의 번호는 addFlashAttribute()로 저장되었기 때문에 한 번도 사용된적이 없다면 위와 같이 값을 만들어 내지만 사요앚가 '/board/list'를 호출하거나 '새로고침'을 통해서 호출하는 경우는 우측과 같이 아무 값도 없게 된다. 따라서 addFlashAttribute()를 이용해 일회성으로만 데이터를 사용할 수 있기 때문에 이를 이용해 경고창이나 모달창 등을 보여주는 방식으로 처리할 수 있다.
모달(Modal) 창 보여주기
최근 브라우저에서 경고창(alert)를 띄우는 방식보단 모달창(Modal)을 보여주는 방식을 많이 사용한다. BootStrap은 모달창을 사용할 수 있으므로 목록 화면에서 필요한 메시지를 보여주는 방법을 사용해본다.
모달창은 기본적으로 <div> 를 화면에 특정 위치에 보여주고, 배경이 되는 <div>에 배경색을 입혀서 처리한다. 모달창은 활성화된 <div>를 선택하지 않고는 다시 원래의 화면을 볼 수 없도록 막기 때문에 메시지를 보여주는데 효과적인 방식이다.
board/list.jsp
<!-- 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">×</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 끝-->
아래부분에 script 태그 이용해서 jQuery 이용해 처리한다. checkModal() 함수는 파라미터에 따라서 모달창을 보여주거나 내용을 수정한 뒤 보이도록 작성한다. checkModal()에서는 새로운 게시글이 작성되는 경우 RedirectAttributes로 게시물의 번호가 전송되므로 이를 이용해 모달창의 내용을 수정한다. $("#myModal").modal("show");를 호출하면 모달창이 보이게 된다.
<script type="text/javascript"> $(document).ready( function() { //컨트롤러에서 bno 값을 result에 저장해뒀다. //c:out을 쓰는 이유는 크로스 사이트 스크립팅 방지하기 위해서 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 = window.location self.location = "/board/register"; }); }); </script>
반응형'Back-End > Spring Legacy' 카테고리의 다른 글
[3-ch12 Spring web 게시판] 페이징 처리, 힌트(hint), ROWNUM & 인라인뷰 적용 (0) 2022.08.28 [3-ch11 Spring view] 게시글 조회, 수정/삭제, 뒤로가기 처리 (0) 2022.08.26 [3-ch10 스프링] 프레젠테이션(웹) 계층의 CRUD 구현 (0) 2022.08.23 [Spring] GET/POST 두 방식의 특징과 차이점 알아보기 (0) 2022.08.23 [3-ch9 비즈니스 계층] Service의 생성과 설정 (0) 2022.08.19