이전 글에서 글 상세보기까지 만들었는데
✏️ 글 수정 update에 대해서 만들어보자 ✏️
JPA에서는 table을 조회해 이미 있는 data라면 변경사항을 병합해준다👍
코딩시작 👩🏻💻
기존 class에 아래 코드를 추가
1. controller
[ BoardController ]
@GetMapping("/post/edit/{id}")
public String edit(@PathVariable("id") Long id, Model model){
BoardDto boardDto = boardService.postDtl(id);
model.addAttribute("board", boardDto);
return "board/edit";
}
@PutMapping("/post/edit/{id}")
public String update(@Valid BoardDto boardDto, BindingResult bindingResult, Model model) {
// 유효성 검사 실패 시 -- edit 화면 바로리턴
if (bindingResult.hasErrors()) {
return "board/edit";
}
try {
boardService.savePost(boardDto);
} catch (IllegalStateException e) {
model.addAttribute("errorMessage", e.getMessage());
return "board/edit";
}
return "redirect:/";
}
✅ @GetMapping("/post/edit/{id}")
글 수정 시 @GetMapping으로 수정 요청을 받는데
@PathVariable(”id”) 으로 요청이 들어온 id값을 사용할 수 있다.
id값을 받는 이유는
- 어떤 id글을 수정할 것인지 식별, 수정 처리를 위해
- 해당 id의 원글을 수정 view에 보여주기 위해
수정하는데 백지를 주면 수정이라고 하기 좀 곤란행,,, 🥴
@GetMapping 은 2번의 이유로 boardService.postDtl(id) 호출,
model객체에 담아 view인 board/edit.html을 리턴한다 (타임리프 .html subfix 지원)
그러면 edit.html에서 ${post.title} ${post.author} 등 value를 사용 가능
그리고 view는 1번의 이유로 ${post.id}를 다시 서버로 전송한다
✅ @PutMapping("/post/edit/{id}")
@PutMapping으로 매핑 시 비즈니스 로직을 호출한다
html에서 PutMapping이 지원되지 않지만 아래에 사용법이 나온다
JPA에서 Data처리 방식은 id를 조회하여
- 없으면 생성하고
- 있으면 변경사항을 병합하기 때문에
insert, update를 모두 save()를사용하고
게시글 Create에서 사용했던 로직인 boardService.savePost(boardDto)를 호출한다
bindingResult 유효성 체크는 글쓰기와 동일.
2. edit.html
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org"
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
layout:decorate="~{layout/layout}">
<!-- 사용자 CSS 추가 -->
<th:block layout:fragment="css">
<style>
.fieldError {
color: #b73a3a;
}
</style>
</th:block>
<!-- 사용자 스크립트 추가 -->
<th:block layout:fragment="script">
<script th:inline="javascript">
$(document).ready(function(){
var errorMessage = [ [${errorMessage}] ];
if(errorMessage != null){
alert(errorMessage);
}
});
</script>
</th:block>
<div layout:fragment="content">
<div class="container">
<form th:object="${board}" th:action="@{'/post/edit/' + ${id}}" method="post" >
<input type="hidden" name="_method" value="put"/>
<input type="hidden" name="id" th:value="${id}"/>
<div class="form-group row">
<label for="inputTitle" class="col-sm-2 col-form-label"><strong>제목</strong></label>
<div class="col-sm-10">
<input type="text" name="title" class="form-control" id="inputTitle" th:value="${board.title}">
<p th:if="${#fields.hasErrors('title')}" th:errors="*{title}" class="fieldError">Incorrect data</p>
</div>
</div>
<div class="form-group row">
<label for="inputAuthor" class="col-sm-2 col-form-label"><strong>작성자</strong></label>
<div class="col-sm-10">
<input type="text" name="author" class="form-control" id="inputAuthor" th:value="${board.author}" readonly>
</div>
</div>
<div class="form-group row">
<label for="inputContent" class="col-sm-2 col-form-label"><strong>내용</strong></label>
<div class="col-sm-10">
<textarea type="text" name="content" class="form-control" id="inputContent"th:text="${board.content}"></textarea>
</div>
</div>
<div class="row">
<div class="col-auto mr-auto"></div>
<div class="col-auto">
<input class="btn btn-success" type="submit" role="button" value="수정">
<a class="btn btn-danger" th:href="@{'/post/' + ${id}}" role="button">취소</a>
</div>
</div>
</form>
</div>
</div>
</html>
✅ Html에서
- <form>은 Get, Post의 method만 사용가능하고
- 클라이언트가 입력한 값을 전송
- 하지만 Type=”hidden” 사용 시 value를 서버로 전송
이 점을 이용해 html에서도 Put, Delete Mapping이 사용가능
- form 자체는 Post로 전송하면서
- <input type="hidden" name="_method" value="put"/> 를 같이 전송하면 Put으로 전송
- → @PutMapping 매핑 가능
- ✅ application.propertie 에서 히든필터 활성화 필요 (아래 3 참고)
✅ <input type="hidden" name="id" th:value="${board.id}"/>
hidden 으로 id값을 넘겨주는 이유는
글쓰기와 글수정은 JPA에서 같은 save()메소드를 사용하는데
글쓰기 create는 원본글이 없으니 id값이 존재하지않고 자동생성을 한다
→ @GeneratedValue(strategy = GenerationType.IDENTITY) (DB위임)
하지만 수정은 원본글에 새 내용을 병합하기 때문에 기존 id값을 알아야한다
위 controller에서 @GetMapping을 기억해보자
@GetMapping("/post/edit/{id}")
public String edit(@PathVariable("id") Long id, Model model){
BoardDto boardDto = boardService.postDtl(id);
model.addAttribute("board", boardDto);
return "board/edit";
}
이미 “post”모델 객체에 담아서 view로 보냈기 때문에
view는 ${board.id}값을 알고있고 다시 서버로 전송한다
3. application.properties
스프링 2.2부터는 Put, Delete 사용을 위해 별도 설정
✅ hidden 필터 활성화
spring.mvc.hiddenmethod.filter.enabled=true
4. detail.html
✅ 글 상세보기에서 수정으로 넘어갈 수 있도록 button 추가
<div class="row mt-3">
<div class="col-auto">
<a class="btn btn-info" th:href="@{'/post/edit/' + ${board.id}}" role="button">수정</a>
</div>
<div class="col-left mr-auto"></div>
<div class="col-auto">
<a class="btn btn-success" th:href="@{'/'}" role="button">목록</a>
</div>
</div>
약 18행 쯤 <class = “row mt-3”> 태그 바로 밑에 수정 코드 추가
오예 이거 끝인거 같은데?
끝!!!!!



수정 전 (상세보기) 에서 수정을 누르면
작성자는 readOnly 수정이 안되는게 맞고 수정버튼을 누르면
수정사항이 반영된 상세보기 view로 redirect된다 성공이다 !
👩🏻💻다음 글에서는 제일 쉬운
Delete 레츠고~~~~
👋그럼이만
'Project > 🥑JPA + SpringSecurity 게시판' 카테고리의 다른 글
| [JPA + SpringSecurity 게시판] #10 Pageable 페이징 처리 (0) | 2022.05.31 |
|---|---|
| [JPA + SpringSecurity 게시판] #9 글 삭제하기 (0) | 2022.05.18 |
| [JPA + SpringSecurity 게시판] #7 글 상세보기 (0) | 2022.05.02 |
| [JPA + SpringSecurity 게시판] #6 글 리스트 만들기 (0) | 2022.04.24 |
| [JPA + SpringSecurity 게시판] #5 @Valid 유효성 체크하기 (0) | 2022.04.19 |