✅ 읽기: GET | /board/read?bno=번호
✅ 삭제: POST | /board/remove
✅ 쓰기:
✔️ GET | /board/write : 게시물을 작성하기 위한 빈 화면을 보여줌
✔️ POST | /board/write : 작성한 게시물 저장
✅ 수정:
✔️ GET | /board/modify?bno=번호 : 수정하기 위해 읽어옴
✔️ POST | /board/modify : 수정된 게시물 저장
✴️ URL: 리소스 (전체)경로
✴️ URN: 리소스를 영구적이고 유일하게 식별 가능한 이름
✴️ URI: 통합 자원 식별자, URL + URN
(URL+식별자=URI를 통해 사용자가 원하는 정보에 도달 가능)
board.jsp
<body>
<div style="text-align:center">
<h2>게시물 읽기</h2>
<form action="" id="form">
<%-- 읽어올 때는 readonly 수정할 때는 X --%>
<input type="text" name="bno" value="${boardDto.bno}" readonly="readonly">
<input type="text" name="title" value="${boardDto.title}" readonly="readonly">
<textarea name="content" id="" cols="30" rows="10" readonly="readonly">${boardDto.content}</textarea>
<button type="button" id="writeBtn" class="btn">등록</button>
<button type="button" id="modifyBtn" class="btn">수정</button>
<button type="button" id="removeBtn" class="btn">삭제</button>
<button type="button" id="listBtn" class="btn">목록</button>
</form>
</div>
</body>
boardList.jsp
<td><a href="<c:url value='/board/read?bno=${boardDto.bno}&page=${page}&pageSize=${pageSize}'/>">
${boardDto.title}</a></td>
✅ 목록에서 게시물을 클릭하면 게시물 페이지로 이동
BoardController.java
@GetMapping("/read")
public String read(Integer bno, Integer page, Integer pageSize, RedirectAttributes rattr, Model m) {
try {
BoardDto boardDto = boardService.read(bno);
// m.addAttribute("boardDto", boardDto); // 아래 문장과 동일
m.addAttribute(boardDto);
m.addAttribute("page", page);
m.addAttribute("pageSize", pageSize);
} catch (Exception e) {
e.printStackTrace();
rattr.addAttribute("page", page);
rattr.addAttribute("pageSize", pageSize);
rattr.addFlashAttribute("msg", "READ_ERR");
return "redirect:/board/list";
}
return "board";
}
✅ 게시물 페이지에서 목록 버튼은 누르면 해당 게시물이 있는 알맞는 목록 페이지로 이동
borad.jsp
<head>
<script src="https://code.jquery.com/jquery-1.11.3.js"></script>
</head>
<script>
$(document).ready(function(){
$('#listBtn').on("click", function(){
// alert를 이용하여 실행 테스트
// alert("listBtn clicked");
// 브라우저 주소창에 다음 주소 입력 GET
location.href = "<c:url value='/board/list'/>?page=${page}&pageSize=${pageSize}";
});
});
</script>
BoardController.java
✔️ borad.jsp:
location.href = "<c:url value='/board/list'/>?page=${page}&pageSize=${pageSize}";
✔️ public String list에 추가
m.addAttribute("page", page);
m.addAttribute("pageSize", pageSize);
BoardController.java
@PostMapping("/remove")
public String remove(Integer bno, Integer page, Integer pageSize,
Model m, HttpSession session, RedirectAttributes rattr) {
String writer = (String)session.getAttribute("id");
try {
m.addAttribute("page", page);
m.addAttribute("pageSize", pageSize);
int rowCnt = boardService.remove(bno, writer);
if(rowCnt!=1)
throw new Exception("board remove error");
rattr.addFlashAttribute("msg", "DEL_OK"); //세션에 값을 저장하여 한번쓰고 지움
} catch (Exception e) {
e.printStackTrace();
rattr.addFlashAttribute("msg", "DEL_ERR");
}
return "redirect:/board/list";
}
boardList.jsp
<body>
<script>
// model 사용하여 받을 시 ${param.msg}
let msg = "${msg}"
if(msg=="DEL_OK") alert("성공적으로 삭제되었습니다.");
if(msg=="DEL_ERR") alert("삭제에 실패했습니다.");
</script>
</body>
✅ 게시물 페이지에서 글쓰기 버튼은 누르면 게시물 글쓰기 페이지로 이동
boardList.jsp
<div style="text-align:center">
<%-- onclick function(){location.href=}을 생략하고 그 안의 location.href=만 써줌
location.href 주소 지정, GET방식 --%>
<button type=button" id="writeBtn"token tag"><c:url value="/board/write"/>'">글쓰기</button>
BoardController.java
@Controller
@RequestMapping("/board")
public class BoardController {
@Autowired
BoardService boardService;
@GetMapping("/write")
public String write(Model m){
m.addAttribute("mode","new");
return "board"; // 읽기와 쓰기에 사용, 쓰기 사용 시 mode=new(new가 아닐때는 readonly)
}
}
board.jsp
<body>
<div style="text-align:center">
<h2>게시물 ${mode=="new" ? "글쓰기":"읽기"}</h2>
<form action="" id="form">
<%-- 읽어올 때는 readonly 수정할 때는 X --%>
<input type="hidden" name="bno" value="${boardDto.bno}">
<input type="text" name="title" value="${boardDto.title}" ${mode=="new" ?'':'readonly="readonly"'}>
<textarea name="content" id="" cols="30" rows="10" ${mode=="new" ?'':'readonly="readonly"'}>${boardDto.content}</textarea>
<button type="button" id="writeBtn" class="btn">등록</button>
<button type="button" id="modifyBtn" class="btn">수정</button>
<button type="button" id="removeBtn" class="btn">삭제 </button>
<button type="button" id="listBtn" class="btn">목록</button>
</form>
</div>
<script>
$(document).ready(function(){
$('#writeBtn').on("click", function(){
if(!confirm("정말로 등록하시겠습니까?")) return;
let form = $('#form');
form.attr("action", "<c:url value='/board/write'/>");
form.attr("method", "post");
form.submit();
});
});
</script>
</body>
BoardController.java
@RequestMapping("/board")
public class BoardController {
@Autowired
BoardService boardService;
@PostMapping("/write")
public String write(BoardDto boardDto, Model m, HttpSession session, RedirectAttributes rattr){
String writer = (String)session.getAttribute("id");
boardDto.setWriter(writer);
try {
int rowCnt = boardService.write(boardDto);
if(rowCnt!=1)
throw new Exception("Write failed");
rattr.addFlashAttribute("msg","WRT_OK");
return "redirect:/board/list";
} catch (Exception e) {
e.printStackTrace();
m.addAttribute(boardDto); // "boardDto" 생략
m.addAttribute("msg","WRT_ERR");
return "board";
}
}
}
board.jsp
<script>
let msg = "${msg}";
if(msg=="WRT_ERR") alert("게시물 등록에 실패했습니다. 다시 시도해주세요.");
</script>
boardList.jsp
<script>
let msg = "${msg}";
if(msg=="WRT_OK") alert("성공적으로 등록되었습니다.");
</script>
✅ 게시판 읽기 페이지(readOnly)에서 수정 버튼을 누르면 게시판 수정 페이지(수정버튼->등록버튼)로 변환, 수정하면 해당 페이지 목록으로 redirect
board.jsp
<script>
$(document).ready(function(){
$('#modifyBtn').on("click", function(){
if(!confirm("정말로 수정하시겠습니까?")) return;
// 1. 읽기 상태이면 수정 상태로 변경
let form = $('#form');
let isReadOnly = $("input[name=title]").attr('readonly');
if(isReadOnly=='readonly'){
$("input[name=title]").attr('readonly',false); // title
$("textarea").attr('readonly',false); // content
$("#modifyBtn").html("등록");
$("h2").html("게시글 수정");
return;
}
// 2. 수정 상태이면 수정된 내용을 서버로 전송하고 원래 게시물 목록 페이지로
form.attr("action", "<c:url value='/board/modify'/>?page=${page}&pageSize=${pageSize}");
form.attr("method", "post");
form.submit();
});
});
</script>
boardController.java
@RequestMapping("/board")
public class BoardController {
@Autowired
BoardService boardService;
@PostMapping("/modify")
public String modify(Integer page, Integer pageSize,BoardDto boardDto, Model m,
HttpSession session, RedirectAttributes rattr){
String writer = (String)session.getAttribute("id");
boardDto.setWriter(writer);
try {
int rowCnt = boardService.modify(boardDto);
m.addAttribute("page", page);
m.addAttribute("pageSize", pageSize);
if(rowCnt!=1)
throw new Exception("Modify failed");
rattr.addFlashAttribute("msg","MOD_OK");
return "redirect:/board/list";
} catch (Exception e) {
e.printStackTrace();
m.addAttribute(boardDto); // "boardDto" 생략
m.addAttribute("msg","MOD_ERR");
return "board";
}
}
}
boardMapper.xml
<mapper namespace="com.fastcampus.ch4.dao.BoardMapper">
<update id="update" parameterType="BoardDto">
UPDATE board
SET title = #{title}
, content = #{content}
, up_date = now()
WHERE bno = #{bno} AND writer = #{writer}
</update>
</mapper>
✅ attribute: 태그 내 속성, HTML의 속성
✅ property: java의 iv와 비슷, 생성된 객체의 속성, DOM의 속성
참고) 자바의 정석 | 남궁성과 끝까지 간다