지난시간
BoardMapperTest
package org.zerock.mapper.project1;
import static org.junit.Assert.*;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.zerock.domain.project1.BoardVO;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("file:src/main/webapp/WEB-INF/spring/root-context.xml")
public class BoardMapperTest {
@Autowired
public BoardMapper mapper;
@Test
public void mapperTest() {
assertNotNull(mapper);
}
@Test
public void insertTest() {
BoardVO vo = new BoardVO();
vo.setTitle("test 용 제목");
vo.setContent("test 용 본문");
vo.setWriter("tester");
int cnt = mapper.insert(vo);
assertEquals(1, cnt);
}
}
test 메소드는 public, void 로 설정, @Test 어노테이션을 붙여주기
실행하면 모든 테스트메소드가 실행되며,
하나만 실행하고 싶은 경우 메소드 우클릭 - Run As - JUnit Test
insertAndSelectTest 메소드
@Test
public void insertAndSelectTest() {
BoardVO vo = new BoardVO();
vo.setTitle("test 용 제목" + Math.random());
vo.setContent("테스트 용 본문" + Math.random());
vo.setWriter("tester");
mapper.insert(vo);
assertNotNull(vo.getId());
assertNotEquals(0, vo.getId().intValue());
BoardVO lastInserted = mapper.read(vo.getId());
assertEquals(vo.getTitle(), lastInserted.getTitle());
assertEquals(vo.getContent(), lastInserted.getContent());
assertEquals(vo.getWriter(), lastInserted.getWriter());
}
* 만약 테스트 실패하면 다음의 모양을 클릭하여 콘솔창에서 로그 확인해본다
updateTest 메소드
@Test
public void updateTest() {
BoardVO vo = new BoardVO();
vo.setTitle("test 용 제목" + Math.random());
vo.setContent("테스트 용 본문" + Math.random());
vo.setWriter("tester");
mapper.insert(vo);
assertNotNull(vo.getId());
assertNotEquals(0, vo.getId().intValue());
String newTitle = "update 용 제목" + Math.random();
String newContent = "update 용 본문" + Math.random();
vo.setTitle(newTitle);
vo.setContent(newContent);
mapper.update(vo);
BoardVO updatedVO = mapper.read(vo.getId());
assertEquals(newTitle, updatedVO.getTitle());
assertEquals(newContent, updatedVO.getContent());
}
> inserted, updated 컬럼 not null 로 변경하기
mysql > preferences > SQL Editor 에서 Safe Updates (rejects UPDATEs and DELETEs with no restrictions) 체크 해제
USE test;
DELETE FROM Board WHERE (id) IN (SELECT id FROM Board WHERE inserted IS NULL);
DELETE FROM Board WHERE updated IS NULL;
ALTER TABLE Board MODIFY COLUMN inserted DATETIME NOT NULL DEFAULT NOW();
ALTER TABLE Board MODIFY COLUMN updated DATETIME NOT NULL DEFAULT NOW();
mysql > preferences > SQL Editor 에서 Safe Updates (rejects UPDATEs and DELETEs with no restrictions) 다시 체크
insertAndDeleteTest 메소드
@Test
public void insertAndDeleteTest() {
BoardVO vo = new BoardVO();
vo.setTitle("삭제용 제목");
vo.setContent("삭제용 본문");
vo.setWriter("tester");
int cnt = mapper.insert(vo);
assertEquals(1, cnt);
cnt = mapper.delete(vo.getId());
assertEquals(1, cnt);
BoardVO deleted = mapper.read(vo.getId());
assertNull(deleted);
}
getListTest 메소드
@Test
public void getListTest() {
List<BoardVO> list = mapper.getList();
assertNotNull(list);
assertTrue(list.size() > 0);
BoardVO vo = new BoardVO();
vo.setTitle("list 테스트용 ");
vo.setContent("list 테스트용 본문");
vo.setWriter("tester");
mapper.insert(vo);
List<BoardVO> list2 = mapper.getList();
assertEquals(list.size() + 1, list2.size());
for (BoardVO item : list2) {
assertNotNull(item.getId());
assertNotNull(item.getTitle());
assertNotNull(item.getContent());
assertNotNull(item.getWriter());
assertNotNull(item.getInserted());
assertNotNull(item.getUpdated());
}
}
보통 controller 는 servlet-context.xml 에, service 와 mapper 는 root-context.xml 에 저장
org.zerock.service.project1 패키지 생성
패키지 우클릭 - new - class (name : BoardService)
BoardService
package org.zerock.service.project1;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.zerock.mapper.project1.BoardMapper;
import lombok.Setter;
@Service
public class BoardService {
@Setter(onMethod_=@Autowired)
private BoardMapper mapper;
}
src/test/java 폴더 안에 org.zerock.service.project1 패키지 생성
패키지 우클릭 - new - JUnit Test Case (name : BoardServiceTest)
BoardServiceTest
package org.zerock.service.project1;
import static org.junit.Assert.*;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("file:src/main/webapp/WEB-INF/spring/root-context.xml")
public class BoardServiceTest {
@Autowired
public BoardService service;
@Test
public void hasService() {
assertNotNull(service);
}
}
> root-context.xml 파일에 다음 코드를 추가
→ BoardServiceTest 실행하면 잘 작동한다
BoardService (작성 완료)
package org.zerock.service.project1;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.zerock.domain.project1.BoardVO;
import org.zerock.mapper.project1.BoardMapper;
import lombok.Setter;
@Service
public class BoardService {
@Setter(onMethod_=@Autowired)
private BoardMapper mapper;
public boolean register(BoardVO board) {
return mapper.insert(board) == 1;
}
public BoardVO get(Integer id) {
return mapper.read(id);
}
public boolean modify(BoardVO board) {
return mapper.update(board) == 1;
}
public boolean remove(Integer id) {
return mapper.delete(id) == 1;
}
public List<BoardVO> getList() {
return mapper.getList();
}
}
! 참고 : @Setter 어노테이션은
import org.springframework.beans.factory.annotation.Autowired;
가 import 되어있는지 확인해야 함
org.zerock.controller.project1 패키지 생성
패키지 우클릭 - new - class (name : BoardController)
BoardController
package org.zerock.controller.project1;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.zerock.domain.project1.BoardVO;
import org.zerock.service.project1.BoardService;
import lombok.Setter;
@Controller
@RequestMapping("/board")
public class BoardController {
@Setter(onMethod_=@Autowired)
private BoardService service;
@GetMapping("/list")
public void list(Model model) {
//3. business logic
//게시물 (Board) 목록 조회
List<BoardVO> list = service.getList();
//4. add attribute
model.addAttribute("list", list);
//5. forward / redirect
//jsp path : /WEB-INF/views/board/list.jsp
}
}
@GetMapping("/list") - 이번에는 RequestMapping 말고 GetMapping 사용 (get 방식으로 요청이 오면 실행)
WEB-INF > views 안에 board 폴더 생성, 그 안에 list.jsp 파일 생성 (new - other - jsp)
list.jsp
<body>
<!-- .container>.row>.col>h1{게시물 목록} -->
<div class="container">
<div class="row">
<div class="col">
<h1>게시물 목록</h1>
<!-- table.table>thead>tr>th*4^^tbody -->
<table class="table">
<thead>
<tr>
<th>
<i class="fab fa-slack-hash"></i>
</th>
<th>제목</th>
<th><i class="fas fa-user"></i></th>
<th>작성일</th>
</tr>
</thead>
<tbody>
<c:forEach items="${list }" var="board">
<tr>
<td>${board.id }</td>
<td>${board.title }</td>
<td>${board.writer }</td>
<td>${board.inserted }</td>
</tr>
</c:forEach>
</tbody>
</table>
</div>
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/jquery@3.5.1/dist/jquery.slim.min.js" integrity="sha384-DfXdz2htPH0lsSSs5nCTpuj/zy4C+OGpamoFVy38MVBnE+IbbVYUew+OrCXaRkfj" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@4.6.1/dist/js/bootstrap.bundle.min.js" integrity="sha384-fQybjgWLrvvRgtW6bFlB7jaZrFsaBXjsOMm/tB9LTS58ONXgqbR9W8oWht/amnpF" crossorigin="anonymous"></script>
</body>
요청 : /board/list
BoardController 추가
// /board/get?id=10 와 같이 요청옴
@GetMapping("/get")
public void get(@RequestParam("id") Integer id, Model model) {
BoardVO board = service.get(id);
model.addAttribute("board", board);
}
@RequestParam("id") 생략가능
경로와 이름이 같은 jsp 파일로 포워딩 ↓
views > board 안에 get.jsp 파일 생성
get.jsp
<body>
<!-- .container>.row>.col>h1{게시물 조회} -->
<div class="container">
<div class="row">
<div class="col">
<h1>게시물 조회</h1>
<div class="board-view">
<!-- .form-group*3>label[for=input$]+input.form-control#input$[readonly] -->
<div class="form-group">
<label for="input1">제목</label>
<input type="text" class="form-control" id="input1" readonly value="${board.title }">
</div>
<div class="form-group">
<label for="input2">내용</label>
<textarea class="form-control" id="input2" readonly>${board.content }</textarea>
</div>
<div class="form-group">
<label for="input3">작성자</label>
<input type="text" class="form-control" id="input3" readonly value="${board.nickName }">
</div>
</div>
</div>
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/jquery@3.5.1/dist/jquery.slim.min.js" integrity="sha384-DfXdz2htPH0lsSSs5nCTpuj/zy4C+OGpamoFVy38MVBnE+IbbVYUew+OrCXaRkfj" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@4.6.1/dist/js/bootstrap.bundle.min.js" integrity="sha384-fQybjgWLrvvRgtW6bFlB7jaZrFsaBXjsOMm/tB9LTS58ONXgqbR9W8oWht/amnpF" crossorigin="anonymous"></script>
</body>
요청 : /board/get?id=3
그런데 우리는 list 화면에서 제목을 클릭하면
get 화면으로 이어지도록 하고싶음
list.jsp 수정(추가)
<td>
<a href="get?id=${board.id }">
${board.title }
</a>
</td>
이제 연결된다
WEB-INF > tags > board 폴더 생성, 그 안에 new - other - tag 검색 - JSP Tag 선택 (name : navBar.tag) 파일 생성
navBar.tag
<%@ tag language="java" pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions"%>
<c:url value="/board/list" var="listUrl"></c:url>
<c:url value="/board/register" var="registerUrl"></c:url>
<nav class="navbar navbar-expand-lg navbar-light bg-light">
<ul class="navbar-nav mr-auto">
<li class="nav-item active">
<a class="nav-link" href="${listUrl }">목록</a>
</li>
<li class="nav-item active">
<a class="nav-link" href="${registerUrl }">글쓰기</a>
</li>
</ul>
</nav>
list.jsp 수정 (추가)
<%@ taglib prefix="b" tagdir="/WEB-INF/tags/board"%>
<body>
<b:navBar></b:navBar>
</body>
get.jsp 수정 (추가)
<%@ taglib prefix="b" tagdir="/WEB-INF/tags/board"%>
<body>
<b:navBar></b:navBar>
</body>
"글쓰기" 클릭하면 다음과 같이 뜨는데,
주소가 board/register 이다
BoardController 추가
@GetMapping("/register")
public void register() {
}
views > board 폴더에 register.jsp 파일 생성
register.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ page import="java.util.*" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>
<%@ taglib prefix="b" tagdir="/WEB-INF/tags/board"%>
<% request.setCharacterEncoding("utf-8"); %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<link rel="stylesheet" href="<%= request.getContextPath() %>/resource/css/icon/css/all.css">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.6.1/dist/css/bootstrap.min.css" integrity="sha384-zCbKRCUGaJDkqS1kPbPd7TveP5iyJE0EjAuZQTgFLD2ylzuqKfdKlfG/eSrtxUkn" crossorigin="anonymous">
<title>Insert title here</title>
</head>
<body>
<b:navBar></b:navBar>
<!-- .container>.row>.col>h1{게시물 작성} -->
<div class="container">
<div class="row">
<div class="col">
<h1>게시물 작성</h1>
<!-- form>.form-group*3>label[for=input$]+input.form-control#input$ -->
<form method="post">
<div class="form-group">
<label for="input1">제목</label>
<input type="text" class="form-control" id="input1" name="title">
</div>
<div class="form-group">
<label for="input2">내용</label>
<textarea class="form-control" id="input2" name="content"></textarea>
</div>
<div class="form-group">
<label for="input3">작성자</label>
<input type="text" class="form-control" id="input3" name="writer">
</div>
<button class="btn btn-outline-primary" type="submit">등록</button>
</form>
</div>
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/jquery@3.5.1/dist/jquery.slim.min.js" integrity="sha384-DfXdz2htPH0lsSSs5nCTpuj/zy4C+OGpamoFVy38MVBnE+IbbVYUew+OrCXaRkfj" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@4.6.1/dist/js/bootstrap.bundle.min.js" integrity="sha384-fQybjgWLrvvRgtW6bFlB7jaZrFsaBXjsOMm/tB9LTS58ONXgqbR9W8oWht/amnpF" crossorigin="anonymous"></script>
</body>
</html>
BoardController 추가
@PostMapping("/register")
public String register(BoardVO board, RedirectAttributes rttr) {
// 3. business logic
service.register(board);
// 4. add attribute
rttr.addFlashAttribute("result", board.getId() + "번 게시글이 등록되었습니다.");
// 5. forward / redirect
// 책: 목록으로 redirect
return "redirect:/board/list";
}
→ 한글도 등록이 가능하도록 하게 하기 위해 (HttpServletRequest req) 작성
@PostMapping("/register")
public String register(BoardVO board, RedirectAttributes rttr, HttpServletRequest req) {
// 3. business logic
service.register(board);
// 4. add attribute
rttr.addFlashAttribute("result", board.getId() + "번 게시글이 등록되었습니다.");
// 5. forward / redirect
// 책: 목록으로 redirect
return "redirect:/board/list";
}
web.xml 에 filter 작성 (교재 243p 코드 그대로 작성)
<filter>
<filter-name>encoding</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>encoding</filter-name>
<servlet-name>appServlet</servlet-name>
</filter-mapping>
/board/register
등록하면 자동으로 list 화면으로 리디렉트됨
게시물 조회 창에 수정/삭제 버튼 추가하기
get.jsp 추가
<a href="modify?id=${board.id }" class="btn btn-outline-secondary">
수정/삭제
</a>
버튼 클릭 시 다음과 같은 화면
주소는 board/modify?id=16 (href="modify?id=${board.id }" 로 작성했으므로)
수정/삭제 화면 만들기
BoardController 추가
@GetMapping({"/get", "/modify"})
public void get(@RequestParam("id") Integer id, Model model) {
BoardVO board = service.get(id);
model.addAttribute("board", board);
}
/get 과 코드가 동일하여 한번에 작성하도록 함
modify.jsp
<body>
<b:navBar></b:navBar>
<!-- .container>.row>.col>h1{게시물 수정} -->
<div class="container">
<div class="row">
<div class="col">
<h1>게시물 수정</h1>
<!-- form>.form-group*3>label[for=input$]+input.form-control#input$ -->
<form method="post">
<input type="hidden" name="id" value="${board.id }">
<div class="form-group">
<label for="input1">제목</label>
<input type="text" class="form-control" value="${board.title }" id="input1" name="title">
</div>
<div class="form-group">
<label for="input2">내용</label>
<textarea class="form-control" id="input2" name="content">${board.content }</textarea>
</div>
<div class="form-group">
<label for="input3">작성자</label>
<input type="text" class="form-control" id="input3" name="writer" value="${board.writer }" readonly>
</div>
<button class="btn btn-outline-primary" type="submit">수정</button>
</form>
</div>
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/jquery@3.5.1/dist/jquery.slim.min.js" integrity="sha384-DfXdz2htPH0lsSSs5nCTpuj/zy4C+OGpamoFVy38MVBnE+IbbVYUew+OrCXaRkfj" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@4.6.1/dist/js/bootstrap.bundle.min.js" integrity="sha384-fQybjgWLrvvRgtW6bFlB7jaZrFsaBXjsOMm/tB9LTS58ONXgqbR9W8oWht/amnpF" crossorigin="anonymous"></script>
</body>
register.jsp 와 유사하기 때문에 복붙한 뒤 일부 수정했음
주목할 점은, 이미 id 가 있는 게시물이므로 id 를 같이 전달해야 함
→ <input type="hidden" name="id" value="${board.id }"> 작성
BoardController 추가
@PostMapping("/modify")
public String modify(BoardVO board, RedirectAttributes rttr) {
if (service.modify(board)) {
rttr.addFlashAttribute("result", board.getId() + "번 게시글이 수정되었습니다.");
}
return "redirect:/board/list";
}
수정된 뒤에 list 로 리디렉트 (게시물 조회로 리디렉트하려면
rttr.addAttribute("id", board.getId());
return "redirect:/board/get";
와 같이 작성)
게시물 수정 창에 삭제 버튼 추가하기
BoardController 추가
@PostMapping("/remove")
public String remove(@RequestParam("id") Integer id, RedirectAttributes rttr) {
if (service.remove(id)) {
rttr.addFlashAttribute("result", id + "번 게시글이 삭제되었습니다.");
}
return "redirect:/board/list";
}
modify.jsp 추가
<button id="removeSubmitButton" class="btn btn-outline-danger" >삭제</button>
button 은 기본적으로 submit 기능을 하기 때문에 그렇게 하지 않도록 설정해야 함
위의 button 추가하고 form, 수정 button 에도 각각 id 설정
그리고 아래와 같이 script 작성 (java script)
<script>
$(document).ready(function() {
$("#removeSubmitButton").click(function(e) {
e.preventDefault(); // 기본 동작을 진행하지 않도록 함.
$("#modifyForm").attr("action", "remove").submit();
});
$("#modifySubmitButton").click(function(e) {
e.preventDefault();
$("#modifyForm").attr("action", "modify").submit();
});
});
</script>
삭제 버튼을 누르면 게시물이 삭제됨
< bootstrap - modal >
https://getbootstrap.com/docs/4.6/components/modal/
Modal
Use Bootstrap’s JavaScript modal plugin to add dialogs to your site for lightboxes, user notifications, or completely custom content.
getbootstrap.com
list.jsp 추가
<c:if test="${not empty result }">
<div class="modal" tabindex="-1" id="modal1">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">처리 결과</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<p>${result }</p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">닫기</button>
</div>
</div>
</div>
</div>
</c:if>
<script>
$(document).ready(function() {
if (history.state == null) {
$("#modal1").modal('show');
history.replaceState({}, null);
}
});
</script>
1. bootstrap 에서 코드 복사하여 일부 수정
- title 은 처리 결과, body 는 ${result }, div 태그에 id="modal1" 추가 (script 에서 설정하기 위해)
2. 모달이 뜨게 하기 위해서 script 작성
3. <c:if> 태그로 result 가 있을 때에만 모달이 뜨도록 설정 (controller 에서 result 전달)
글을 등록해보았음, 다음과 같이 모달이 표시됨 ↓
만약, 모달을 닫고 게시글을 눌렀다가 뒤로가기를 하면 모달이 떠있는 문제가 있음
해결? history - state 를 이용하여 script 작성
<script>
$(document).ready(function() {
$("#modal1").modal('show');
});
</script>
-> if 문 (조건) 추가
<script>
$(document).ready(function() {
if (history.state == null) {
$("#modal1").modal('show');
history.replaceState({}, null);
}
});
</script>
if 문은 이를 해결하기 위해 추가된 코드임
< 여기까지 작성된 코드 전체 >
BoardController
package org.zerock.controller.project1;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;
import org.zerock.domain.project1.BoardVO;
import org.zerock.service.project1.BoardService;
import lombok.Setter;
@Controller
@RequestMapping("/board")
public class BoardController {
@Setter(onMethod_=@Autowired)
private BoardService service;
@GetMapping("/list")
public void list(Model model) {
//3. business logic
//게시물 (Board) 목록 조회
List<BoardVO> list = service.getList();
//4. add attribute
model.addAttribute("list", list);
//5. forward / redirect
//jsp path : /WEB-INF/views/board/list.jsp
}
// /board/get?id=10 와 같이 요청옴
@GetMapping({"/get", "/modify"})
public void get(@RequestParam("id") Integer id, Model model) {
BoardVO board = service.get(id);
model.addAttribute("board", board);
}
@GetMapping("/register")
public void register() {
}
@PostMapping("/register")
public String register(BoardVO board, RedirectAttributes rttr, HttpServletRequest req) {
// 3. business logic
service.register(board);
// 4. add attribute
rttr.addFlashAttribute("result", board.getId() + "번 게시글이 등록되었습니다.");
// 5. forward / redirect
// 책: 목록으로 redirect
return "redirect:/board/list";
}
@PostMapping("/modify")
public String modify(BoardVO board, RedirectAttributes rttr) {
if (service.modify(board)) {
rttr.addFlashAttribute("result", board.getId() + "번 게시글이 수정되었습니다.");
}
return "redirect:/board/list";
}
@PostMapping("/remove")
public String remove(@RequestParam("id") Integer id, RedirectAttributes rttr) {
if (service.remove(id)) {
rttr.addFlashAttribute("result", id + "번 게시글이 삭제되었습니다.");
}
return "redirect:/board/list";
}
}
list.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ page import="java.util.*" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>
<%@ taglib prefix="b" tagdir="/WEB-INF/tags/board"%>
<% request.setCharacterEncoding("utf-8"); %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<link rel="stylesheet" href="<%= request.getContextPath() %>/resource/css/icon/css/all.css">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.6.1/dist/css/bootstrap.min.css" integrity="sha384-zCbKRCUGaJDkqS1kPbPd7TveP5iyJE0EjAuZQTgFLD2ylzuqKfdKlfG/eSrtxUkn" crossorigin="anonymous">
<title>Insert title here</title>
</head>
<body>
<b:navBar></b:navBar>
<!-- .container>.row>.col>h1{게시물 목록} -->
<div class="container">
<div class="row">
<div class="col">
<h1>게시물 목록</h1>
<!-- table.table>thead>tr>th*4^^tbody -->
<table class="table">
<thead>
<tr>
<th>
<i class="fab fa-slack-hash"></i>
</th>
<th>제목</th>
<th><i class="fas fa-user"></i></th>
<th>작성일</th>
</tr>
</thead>
<tbody>
<c:forEach items="${list }" var="board">
<tr>
<td>${board.id }</td>
<td>
<a href="get?id=${board.id }">
${board.title }
</a>
</td>
<td>${board.writer }</td>
<td>${board.inserted }</td>
</tr>
</c:forEach>
</tbody>
</table>
</div>
</div>
</div>
<c:if test="${not empty result }">
<div class="modal" tabindex="-1" id="modal1">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">처리 결과</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<p>${result }</p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">닫기</button>
</div>
</div>
</div>
</div>
</c:if>
<script src="https://cdn.jsdelivr.net/npm/jquery@3.5.1/dist/jquery.slim.min.js" integrity="sha384-DfXdz2htPH0lsSSs5nCTpuj/zy4C+OGpamoFVy38MVBnE+IbbVYUew+OrCXaRkfj" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@4.6.1/dist/js/bootstrap.bundle.min.js" integrity="sha384-fQybjgWLrvvRgtW6bFlB7jaZrFsaBXjsOMm/tB9LTS58ONXgqbR9W8oWht/amnpF" crossorigin="anonymous"></script>
<script>
$(document).ready(function() {
if (history.state == null) {
$("#modal1").modal('show');
history.replaceState({}, null);
}
});
</script>
</body>
</html>
get.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ page import="java.util.*" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>
<%@ taglib prefix="b" tagdir="/WEB-INF/tags/board"%>
<% request.setCharacterEncoding("utf-8"); %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<link rel="stylesheet" href="<%= request.getContextPath() %>/resource/css/icon/css/all.css">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.6.1/dist/css/bootstrap.min.css" integrity="sha384-zCbKRCUGaJDkqS1kPbPd7TveP5iyJE0EjAuZQTgFLD2ylzuqKfdKlfG/eSrtxUkn" crossorigin="anonymous">
<title>Insert title here</title>
</head>
<body>
<b:navBar></b:navBar>
<!-- .container>.row>.col>h1{게시물 조회} -->
<div class="container">
<div class="row">
<div class="col">
<h1>게시물 조회</h1>
<div class="board-view">
<!-- .form-group*3>label[for=input$]+input.form-control#input$[readonly] -->
<div class="form-group">
<label for="input1">제목</label>
<input type="text" class="form-control" id="input1" readonly value="${board.title }">
</div>
<div class="form-group">
<label for="input2">내용</label>
<textarea class="form-control" id="input2" readonly>${board.content }</textarea>
</div>
<div class="form-group">
<label for="input3">작성자</label>
<input type="text" class="form-control" id="input3" readonly value="${board.nickName }">
</div>
<a href="modify?id=${board.id }" class="btn btn-outline-secondary">
수정/삭제
</a>
</div>
</div>
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/jquery@3.5.1/dist/jquery.slim.min.js" integrity="sha384-DfXdz2htPH0lsSSs5nCTpuj/zy4C+OGpamoFVy38MVBnE+IbbVYUew+OrCXaRkfj" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@4.6.1/dist/js/bootstrap.bundle.min.js" integrity="sha384-fQybjgWLrvvRgtW6bFlB7jaZrFsaBXjsOMm/tB9LTS58ONXgqbR9W8oWht/amnpF" crossorigin="anonymous"></script>
</body>
</html>
register.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ page import="java.util.*" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>
<%@ taglib prefix="b" tagdir="/WEB-INF/tags/board"%>
<% request.setCharacterEncoding("utf-8"); %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<link rel="stylesheet" href="<%= request.getContextPath() %>/resource/css/icon/css/all.css">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.6.1/dist/css/bootstrap.min.css" integrity="sha384-zCbKRCUGaJDkqS1kPbPd7TveP5iyJE0EjAuZQTgFLD2ylzuqKfdKlfG/eSrtxUkn" crossorigin="anonymous">
<title>Insert title here</title>
</head>
<body>
<b:navBar></b:navBar>
<!-- .container>.row>.col>h1{게시물 작성} -->
<div class="container">
<div class="row">
<div class="col">
<h1>게시물 작성</h1>
<!-- form>.form-group*3>label[for=input$]+input.form-control#input$ -->
<form method="post">
<div class="form-group">
<label for="input1">제목</label>
<input type="text" class="form-control" id="input1" name="title">
</div>
<div class="form-group">
<label for="input2">내용</label>
<textarea class="form-control" id="input2" name="content"></textarea>
</div>
<div class="form-group">
<label for="input3">작성자</label>
<input type="text" class="form-control" id="input3" name="writer">
</div>
<button class="btn btn-outline-primary" type="submit">등록</button>
</form>
</div>
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/jquery@3.5.1/dist/jquery.slim.min.js" integrity="sha384-DfXdz2htPH0lsSSs5nCTpuj/zy4C+OGpamoFVy38MVBnE+IbbVYUew+OrCXaRkfj" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@4.6.1/dist/js/bootstrap.bundle.min.js" integrity="sha384-fQybjgWLrvvRgtW6bFlB7jaZrFsaBXjsOMm/tB9LTS58ONXgqbR9W8oWht/amnpF" crossorigin="anonymous"></script>
</body>
</html>
modify.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ page import="java.util.*" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>
<%@ taglib prefix="b" tagdir="/WEB-INF/tags/board"%>
<% request.setCharacterEncoding("utf-8"); %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<link rel="stylesheet" href="<%= request.getContextPath() %>/resource/css/icon/css/all.css">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.6.1/dist/css/bootstrap.min.css" integrity="sha384-zCbKRCUGaJDkqS1kPbPd7TveP5iyJE0EjAuZQTgFLD2ylzuqKfdKlfG/eSrtxUkn" crossorigin="anonymous">
<title>Insert title here</title>
</head>
<body>
<b:navBar></b:navBar>
<!-- .container>.row>.col>h1{게시물 수정} -->
<div class="container">
<div class="row">
<div class="col">
<h1>게시물 수정</h1>
<!-- form>.form-group*3>label[for=input$]+input.form-control#input$ -->
<form id="modifyForm" method="post">
<input type="hidden" name="id" value="${board.id }">
<div class="form-group">
<label for="input1">제목</label>
<input type="text" class="form-control" value="${board.title }" id="input1" name="title">
</div>
<div class="form-group">
<label for="input2">내용</label>
<textarea class="form-control" id="input2" name="content">${board.content }</textarea>
</div>
<div class="form-group">
<label for="input3">작성자</label>
<input type="text" class="form-control" id="input3" name="writer" value="${board.writer }" readonly>
</div>
<button id="modifySubmitButton" class="btn btn-outline-primary" type="submit">수정</button>
<button id="removeSubmitButton" class="btn btn-outline-danger" >삭제</button>
</form>
</div>
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/jquery@3.5.1/dist/jquery.slim.min.js" integrity="sha384-DfXdz2htPH0lsSSs5nCTpuj/zy4C+OGpamoFVy38MVBnE+IbbVYUew+OrCXaRkfj" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@4.6.1/dist/js/bootstrap.bundle.min.js" integrity="sha384-fQybjgWLrvvRgtW6bFlB7jaZrFsaBXjsOMm/tB9LTS58ONXgqbR9W8oWht/amnpF" crossorigin="anonymous"></script>
<script>
$(document).ready(function() {
$("#removeSubmitButton").click(function(e) {
e.preventDefault(); // 기본 동작을 진행하지 않도록 함.
$("#modifyForm").attr("action", "remove").submit();
});
$("#modifySubmitButton").click(function(e) {
e.preventDefault();
$("#modifyForm").attr("action", "modify").submit();
});
});
</script>
</body>
</html>
그 밖에도, BoardVO(domain), BoardMapper(java, xml), BoardService 가 있음
BoardVO
package org.zerock.domain.project1;
import java.time.LocalDateTime;
import java.time.ZoneId;
import lombok.Data;
@Data
public class BoardVO {
private Integer id;
private String title;
private String content;
private String writer;
private LocalDateTime inserted;
private LocalDateTime updated;
private String nickName;
public String getCustomInserted() {
// 현재일시
LocalDateTime now = LocalDateTime.now(ZoneId.of("+09:00"));
LocalDateTime beforeOneDayFromNow = now.minusDays(1);
if (inserted.isBefore(beforeOneDayFromNow)) {
return inserted.toLocalDate().toString();
} else {
return inserted.toLocalTime().toString();
}
}
}
BoardService
package org.zerock.service.project1;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.zerock.domain.project1.BoardVO;
import org.zerock.mapper.project1.BoardMapper;
import lombok.Setter;
@Service
public class BoardService {
@Setter(onMethod_=@Autowired)
private BoardMapper mapper;
public boolean register(BoardVO board) {
return mapper.insert(board) == 1;
}
public BoardVO get(Integer id) {
return mapper.read(id);
}
public boolean modify(BoardVO board) {
return mapper.update(board) == 1;
}
public boolean remove(Integer id) {
return mapper.delete(id) == 1;
}
public List<BoardVO> getList() {
return mapper.getList();
}
}
'course 2021 > Spring' 카테고리의 다른 글
Spring09 - 12/14 (0) | 2021.12.27 |
---|---|
Spring08 - 12/13 (0) | 2021.12.26 |
Spring06 - 12/09 (0) | 2021.12.21 |
Spring05 - 12/08(controller09~11) (0) | 2021.12.21 |
Spring04 - 12/07(controller07~09) (0) | 2021.12.20 |