Git Clone

참고 사이트
게시글 목록보기, 수정화면 이동
index 수정
{{> layout/header}}
<div class="container p-5">
<table class="table table-striped">
<thead>
<tr>
<th>번호</th>
<th>제목</th>
<th>내용</th>
<th>작성자</th>
<th></th>
</tr>
</thead>
<tbody>
</tbody>
</table>
</div>
<script></script>
{{> layout/footer}}
BoardApiController 생성
api에 주소에는 보통 복수형을 쓴다.

@RequiredArgsConstructor
@RestController
public class BoardApiController {
private final BoardRepository boardRepository;
@GetMapping("/api/boards")
public void findAll(){
List<Board> boardList = boardRepository.selectAll();
}
}
ApiUtil 생성
- Api에서 Header에 상태코드가 있지만 Body에도 상태코드를 담아서 보내줘야 한다.
- Body를 파싱해서 Client에게 error message를 보내줘야 하기 때문
- Header의 상태코드에 상관없이 Body를 파싱한다.
@Data
public class ApiUtil<T> {
private Integer status; // 200, 400, 404, 405
private String msg; // 성공, 실패 시 -> 정확한 메시지
private T body;
public ApiUtil(T body) {
this.status = 200;
this.msg = "성공";
this.body = body;
}
public ApiUtil(Integer status, String msg) {
this.status = status;
this.msg = msg;
this.body = null;
}
}
BoardApiController 수정
@RequiredArgsConstructor
@RestController
public class BoardApiController {
private final BoardRepository boardRepository;
@GetMapping("/api/boards")
public ApiUtil<?> findAll() {
List<Board> boardList = boardRepository.selectAll();
return new ApiUtil<>(boardList);
}
}
실행 해보기

MessageConverter가 발동하여 JSON으로 바뀌는 것을 확인
jQuery, FontAwesome 추가
header.mustache head에 추가
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.1/css/all.min.css">
jQuery 코드 작성

index.mustache
$.ajax({
url: "/api/boards",
type: "get"
}).done((res) => {
console.log("통신 성공");
console.log(res);
}).fail((res) => {
console.log("통신 실패")
// console.log(res);
alert(res.responseJSON.msg);
// location.href = "/loginForm";
});

getboard → render 함수 수정

한줄이 board


function render(board) {
return `
<tr id="board-${board.id}">
<td>${board.id}</td>
<td>${board.title}</td>
<td>${board.content}</td>
<td>${board.author}</td>
<td>
<div class="d-flex">
<button onclick="del(${board.id})" class="btn btn-danger">삭제</button>
<form action="/board/${board.id}/updateForm" method="get">
<button class="btn btn-warning">수정</button>
</form>
</div>
</td>
</tr>
`;
}


let boardList = res.body;
boardList.forEach((board)=>{
$("#board-box").append(render(board));
});
게시글 삭제
BoardApiController

@DeleteMapping("/api/boards/{id}")
public ApiUtil<?> deleteById(@PathVariable Integer id){
boardRepository.deleteById(id);
return new ApiUtil<>(null);
}
BoardRepository - deleteById 만들기

@Transactional
public void deleteById(Integer id) {
Query query = em.createNativeQuery("delete from board_tb where id = ?");
query.setParameter(1, id);
query.executeUpdate();
}
ajax 코드 작성

function del(boardId) {
$.ajax({
url: `api/boards/${boardId}`,
type: "delete"
}).done((res) => {
$(`#board-${boardId}`).remove();
}).fail((res) => {
alert(res.response.JSON.msg);
location.reload(); // F5
});
}
BoardApiController 수정

게시글 쓰기
JSON은 form태그 사용 불가능
saveForm.mustache 수정

버튼의 type을 button으로 하거나, form태그를 없애준다.
<div class="container p-5">
<div class="card">
<div class="card-header"><b>익명 글쓰기 화면입니다</b></div>
<div class="card-body">
<form>
<div class="mb-3">
<input type="text" class="form-control" placeholder="Enter author" id="author">
</div>
<div class="mb-3">
<input type="text" class="form-control" placeholder="Enter title" id="title">
</div>
<div class="mb-3">
<textarea class="form-control" rows="5" id="content"></textarea>
</div>
<button onclick="btnWrite()" type="button" class="btn btn-primary form-control">글쓰기완료</button>
</form>
</div>
</div>
</div>
btnWrite 함수 작동되는지 확인


BoardApiController

BoardRequest 생성

public class BoardRequest {
@Data
public static class WriteDTO{
private String title;
private String content;
private String author;
}
}
PostMapping 수정

insert 수정

테스트 코드 수정

POSTMAN으로 요청해보기


ajax 작성

<script>
function btnWrite(){
// JavaScript Object
let board = {
title: $("#title").val(),
content: $("#content").val(),
author: $("#author").val()
};
console.log(board);
// JavaScript Object -> JSON으로 바꾸기
// let boardJson = JSON.stringify(board);
// console.log(boardJson);
$.ajax({
url: "/api/boards",
type: "POST" ,
data: JSON.stringify(board),
contentType: "application/json; charset=utf-8"
}).done((res)=>{
location.href = "/";
}).fail((res)=>{
alert(res.responseJSON.msg);
});
}
</script>
게시글 수정
updateForm.mustache 수정
<div class="container p-5">
<div class="card">
<div class="card-header"><b>익명 글수정 화면입니다</b></div>
<div class="card-body">
<form>
<div class="mb-3">
<input type="text" class="form-control" placeholder="Enter author" id="author">
</div>
<div class="mb-3">
<input type="text" class="form-control" placeholder="Enter title" id="title">
</div>
<div class="mb-3">
<textarea class="form-control" rows="5" id="content"></textarea>
</div>
<button onclick="btnUpdate()" type="button" class="btn btn-primary form-control">글수정완료</button>
</form>
</div>
</div>
</div>
btnUpdate() 함수 작동 확인
<script>
function btnUpdate(){
alert("클릭되나");
}
</script>

BoardApiController

BoardRepository update 틀 만들기

UpdateDTO와 WriteDTO가 같으므로 WriteDTO 이름 변경


DTO의 구성이 같더라도 새로운 DTO를 하나 더 만드는 것이 좋다.
변경될 수도 있기 때문에(수정은 제목과 내용만 하는 것으로) → 사용자 관점
update 완성

BoardApiController

@PutMapping("/api/boards/{id}")
public ApiUtil<?> update(@RequestBody BoardRequest.WriteAndUpdateDTO requestDTO, @PathVariable Integer id){
boardRepository.update(requestDTO, id);
return new ApiUtil<>(null);
}
postman 요청


ajax 코드 수정
<script>
function btnUpdate(){
// JavaScript Object
let board = {
title: $("#title").val(),
content: $("#content").val(),
author: $("#author").val()
};
// console.log(board);
// JavaScript Object -> JSON으로 바꾸기
// let boardJson = JSON.stringify(board);
// console.log(boardJson);
$.ajax({
url: `/api/boards/{{id}}`,
type: "PUT" ,
data: JSON.stringify(board),
contentType: "application/json; charset=utf-8"
}).done((res)=>{
location.href = "/";
}).fail((res)=>{
alert(res.responseJSON.msg);
});
}
</script>
BoardApiController update 수정
id를 가져오기 위해 setAttribute 해야함

@PutMapping("/api/boards/{id}")
public ApiUtil<?> update(@RequestBody BoardRequest.WriteAndUpdateDTO requestDTO, @PathVariable Integer id, HttpServletRequest request){
boardRepository.update(requestDTO, id);
request.setAttribute("id",id);
return new ApiUtil<>(null);
}

@GetMapping("/board/{id}/updateForm")
public String updateForm(@PathVariable int id, HttpServletRequest request) {
Board board = boardRepository.selectOne(id);
request.setAttribute("board",board);
return "board/updateForm";
}
UpdateForm 수정

<div class="container p-5">
<div class="card">
<div class="card-header"><b>익명 글수정 화면입니다</b></div>
<div class="card-body">
<form>
<div class="mb-3">
<input type="text" class="form-control" placeholder="Enter author" id="author" value="{{board.author}}">
</div>
<div class="mb-3">
<input type="text" class="form-control" placeholder="Enter title" id="title" value="{{board.author}}">
</div>
<div class="mb-3">
<textarea class="form-control" rows="5" id="content">{{board.author}}</textarea>
</div>
<button onclick="btnUpdate()" type="button" class="btn btn-primary form-control">글수정완료</button>
</form>
</div>
</div>
</div>
Share article