View 먼저 확인
updateForm.mustache 코드 구현
saveForm.mustache를 복붙해서 updateForm.mustache을 만들어 준다.
action 링크 확인 → 1은 변수로 바꿔야 된다.
method → post
enctype → xform 데이터
키값 확인 → title, content
button 타입확인 → submit은 폼태그 안에 있으면 양식을 제출한다.
updateForm.mustache 코드
글 수정화면으로 사용하기 때문에, 메시지도 아래처럼 수정해준다.
{{> layout/header}}
<div class="container p-5">
<div class="card">
<div class="card-header"><b>수정하기 화면입니다</b></div>
<div class="card-body">
<form action="/board/{id}/update" method="post" enctype="application/x-www-form-urlencoded">
<div class="mb-3">
<input type="text" class="form-control" placeholder="Enter title" name="title" value="제목1">
</div>
<div class="mb-3">
<textarea class="form-control" rows="5" name="content">내용 1</textarea>
</div>
<button type="submit" class="btn btn-primary form-control">수정완료</button>
</form>
</div>
</div>
</div>
{{> layout/footer}}
HTML
복사
updateForm로직
@RequiredArgsConstructor
@Controller
public class BoardController {
private final HttpSession session;
private final BoardRepository boardRepository;
// 게시글 수정 페이지 정보를 조회해서 뿌리는 책임을 가진다.
// @PathVariable 사용해서 동적으로 할당한다.
@GetMapping("/board/{id}/updateForm")
public String updateForm (@PathVariable int id, HttpServletRequest request) {
// 인증 체크
User sessionUser = (User) session.getAttribute("sessionUser");
if (sessionUser == null) {
return "redirect:/loginForm";
}
// 모델 위임 (id로 board를 조회)
// 권한 체크
BoardResponse.DetailDTO detailDTO = boardRepository.findById(id);
if (sessionUser.getId() != detailDTO.getUserId()){
request.setAttribute("msg", "권한이 없습니다.");
request.setAttribute("status", 403);
}
// 가방에 담기
// 가방에 담아서 View에 전달하는 것이 핵심로직이다
request.setAttribute("board", detailDTO);
return "board/updateForm";
}
Java
복사
Additional Notes
DB를 조회하기 위해서 번호가 필요하다.
Join을 사용하게 되면 DB부하가 커진다. 조심해서 사용!!
서버부하가 커지는 쿼리 → join, group by, sub쿼리
PK로 조회하면 인덱스로 조회하기 때문에 엄청 빠르다.
평점이라는 기능 역시 사람들의 평가가 필요하므로 스칼라가 아닌 테이블로 만들어야된다.
DetailDTO를 board에 할당하기
View에 연동하기
수정버튼에 updateForm으로 이동기능 만들기
테스트
수정을 클릭하면 URL이 게시글 번호를 받아서 updateForm페이지로 가야된다.
성공!
수정화면의 내부역시 DB로 조회된 내용을 화면에 출력해야 된다.
/board/3/update으로 URL 잘 적용이 되었다.
3번 게시물이므로 제목3, 내용3이 표현되었고 잘 적용이 된 것 같다!
게시물 수정기능 구현하기(액션)
DTO만들기
게시물 제목과 내용을 수정하여 버튼을 클릭하면 전달되는 정보는 title과 content이다. 이를 위한 DTO를 따로 만들어 최대한 SRP원칙을 지키도록 한다.
package shop.mtcoding.blog.board;
import lombok.Data;
public class BoardResponse {
// 게시물 제목과 내용을 적어서 버튼을 클릭하면
// 전달되는 정보는 title과 content이다.
@Data
public static class UpdateDTO {
private String title;
private String content;
}
Java
복사
컨트롤러>>update() 메소드 핵심로직 먼저 만들기
@RequiredArgsConstructor
@Controller
public class BoardController {
private final BoardRepository boardRepository;
private final HttpSession session;
@PostMapping("board/{id}/update")
public String update (@PathVariable int id, BoardResponse.UpdateDTO requestDTO){
//1. 인증 체크
//2. 권한 체크
//3. 핵심 로직
// 쿼리 >> update board_tb set title=? , content=? where id=?
boardRepository.update(id, requestDTO);
return "redirect:/board/" + id;
}
}
Java
복사
DB연결하기
@Transactional // DB변경이기 때문에 최소작업단위로 묶어야된다.
public void update(int id, BoardRequest.UpdateDTO requestDTO) {
Query query = em.createNativeQuery("update board_tb set title=? , content=? where id=? ");
query.setParameter(1, requestDTO.getTitle());
query.setParameter(2, requestDTO.getContent());
query.setParameter(3, id);
query.executeUpdate();
}
Java
복사
테스트 하기
이 수정 완료 버튼에는 폼태그(<form></form>)로 post요청과 submit이 들어가있기 때문에, 브라우저에서 바로 테스트 해볼 수 있다.
TransactionRequiredException에러가 생길경우!
해결방법 펼쳐보기
수정 테스트 확인완료!
update()메소드 부가로직 구현
부가로직은 다음과 같다.
로그인 여부 검사 → 인증 테스트, 401
게시물 주인 판단 검사 → 권한 테스트, 403
@RequiredArgsConstructor
@Controller
public class BoardController {
private final BoardRepository boardRepository;
private final HttpSession session;
@PostMapping("board/{id}/update")
public String update (@PathVariable int id, BoardResponse.UpdateDTO requestDTO, HttpServletRequest request){
//1. 인증 체크
User sessionUser = (User) session.getAttribute("sessionUser");
if (sessionUser == null){
return "redirect:/loginForm";
}
//2. 권한 체크
BoardResponse.DetailDTO board = boardRepository.findById(id);
if (board.getUserId()!=sessionUser.getId()){
request.setAttribute("msg", "권한이 없습니다.");
request.setAttribute("status", 403);
return "error/40x";
}
//3. 핵심 로직
// 쿼리 >> update board_tb set title=? , content=? where id=?
boardRepository.update(id, requestDTO);
return "redirect:/board/" + id;
}
Java
복사
Additional Notes - @RequestBody어노테이션
아래 코드에서 @RequestBody 어노테이션의 위치를 살펴보자!
@PostMapping("/board/{id}/update")
public void update (@PathVariable int id, @RequestBody BoardRequest.UpdateDTO requestDTO) {
System.out.println(requestDTO);
}
Java
복사
Postman으로 raw섹션에 JSON타입의 자료를 입력하여 Post요청을 하면 @RequestBody는 해당 원문을 자바 객체로 변환시켜서 저장한다.