수정 및 삭제 기능 추가
수정 일시 추가하기
게시판의 질문과 답변을 수정하거나 삭제 기능을 추가하기 전에 언제 수정되었는지 확인할 수 있도록 속성을 추가하자.
/question/Question.java
package com.mysite.sbb.question;
import java.time.LocalDateTime;
import java.util.List;
import com.mysite.sbb.answer.Answer;
import com.mysite.sbb.user.SiteUser;
import jakarta.persistence.CascadeType;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.OneToMany;
import lombok.Getter;
import lombok.Setter;
@Getter
@Setter
@Entity
public class Question {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
@Column(length = 200)
private String subject;
@Column(columnDefinition = "TEXT")
private String content;
private LocalDateTime createDate;
//관계주입
@OneToMany(mappedBy = "question", cascade = CascadeType.REMOVE)
private List<Answer> answerList;
//관계주입
@ManyToOne
private SiteUser author;
private LocalDateTime modifyDate;
}
/answer/Answer.java
package com.mysite.sbb.answer;
import java.time.LocalDateTime;
import com.mysite.sbb.question.Question;
import com.mysite.sbb.user.SiteUser;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.ManyToOne;
import lombok.Getter;
import lombok.Setter;
@Getter
@Setter
@Entity
public class Answer {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
@Column(columnDefinition = "TEXT")
private String content;
private LocalDateTime createDate;
//관계주입
@ManyToOne
private Question question;
//관계주입
@ManyToOne
private SiteUser author;
private LocalDateTime modifyDate;
}
Question과 Answer모두 동일하게 수정일시를 추가한 후, 다시 H2콘솔에 접속해보면 열이 추가된 것을 확인할 수 있다.

질문 수정 기능 생성하기
질문 수정 버튼 만들기
/templates/question_detail.html
...
<!--수정 버튼-->
<div class="my-3">
<a th:href="@{|/question/modify/${question.id}|}" class="btn btn-sm btn-outline-secondary"
sec:authorize="isAuthenticated()"
th:if="${question.author != null and #authentication.getPrincipal().getUsername() == question.author.username}"
th:text="수정"></a>
</div>
<!--수정 버튼 끝-->
...

질문 컨트롤러 수정하기(1)
위의 <a>태그를 통해 GET방식으로 @{|/question/modify/${question.id}|} url이 추가되었으므로 이 링크가 정상 작동하도록 수정해야 한다.
/question/QuestionController.java
@PreAuthorize("isAuthenticated()")
@GetMapping("/modify/{id}")
public String questionModify(QuestionForm questionForm, @PathVariable("id") Integer id, Principal principal){
Question question = this.questionService.getQuestion(id);
if (!question.getAuthor().getUsername().equals(principal.getName())) {
throw new ResponseStatusException(HttpStatus.BAD_REQUEST, "수정 권한이 없습니다.");
}
questionForm.setSubject(question.getSubject());
questionForm.setContent(question.getContent());
return "question_form";
}
유효성 검사를 위해 QuestionForm을 선언해두었다.
먼저 해당하는 question객체를 가져오고
그에 해당하는 제목과 내용으로 QuestionForm을 세팅해준다. 이 내용들을 가지고 qeustion_form화면으로 이동한다.
질문 등록 템플릿 수정하기
질문을 등록하는 화면이나 수정하는 화면은 내용 기입하는 곳이 동일하므로 같은 템플릿을 사용한다.
/templates/question_form.html
<html layout:decorate="~{layout}">
<div layout:fragment="content" class="container">
<h5 class="my-3 border-bottom pb-2">질문등록</h5>
<form th:object="${questionForm}" method="post">
<input type="hidden" th:name="${_csrf.parameterName}"
th:value="${_csrf.token}">
<div th:replace="~{form_errors :: formErrorsFragment}"></div>
<div class="mb-3">
<label for="subject" class="form-label">제목</label>
<input type="text" th:field="*{subject}" class="form-control">
</div>
<div class="mb-3">
<label for="content" class="form-label">내용</label>
<textarea th:field="*{content}" class="form-control" rows="10"></textarea>
</div>
<input type="submit" value="저장하기" class="btn btn-primary my-2">
</form>
</div>
</html>
먼저 기존에 있던 form태그의 action속성을 삭제한다. 그러면 CSRF값이 자동생성되지 않아 input태그의 hidden타입으로 직접 추가해주어야 한다. 그러지 않으면 접근 거부가 나타난다.
여기서 action속성없이 submit하게되면 자동으로 여기 화면으로 접근하게된 경로를 갖고 있으므로
/question/cretae URL로 GET방식으로 접근했다면 submit할 시 자동으로 POST방식으로 /question/cretae가 action속성으로 잡힌다. 수정시에는 /question/modify/2와 같은 URL로 접근했기 때문에 POST방식으로 자동으로 /question/modify/2로 설정된다.
질문 서비스 수정하기
/qeustion/QuestionService.java
public void modify(Question question, String subject, String content) {
question.setSubject(subject);
question.setContent(content);
question.setModifyDate(LocalDateTime.now());
this.questionRepostiory.save(question);
}
수정된 질문이 처리되도록 서비스를 수정했다.
질문 컨트롤러 수정하기(2)
내용 변경 후 저장 버튼을 클릭하게 되면 action이 /question/modify/{id}로 자동 생성되고 POST방식으로 전달할 것이다.
이를 처리하기 위해 컨트롤러를 수정하자.
/question/QuestionController.java
@PreAuthorize("isAuthenticated()")
@PostMapping("/modify/{id}")
public String questionModify(@Valid QuestionForm questionForm, BindingResult bindingResult,
Principal principal, @PathVariable("id") Integer id) {
if (bindingResult.hasErrors()) {
return "question_form";
}
Question question = this.questionService.getQuestion(id);
if (!question.getAuthor().getUsername().equals(principal.getName())) {
throw new ResponseStatusException(HttpStatus.BAD_REQUEST, "수정 권한이 없습니다.");
}
this.questionService.modify(question, questionForm.getSubject(), questionForm.getContent());
return String.format("redirect:/question/detail/%s", id);
}
유효성 검사를 통해 만약 오류가 있다면 다시 question_form 으로 돌아가고
작성자와 동일한지도 검사한다.
이상이 없다면 위의 Service에서 만들었던 modify메서드를 호출하여 question객체와 수정된 제목과 내용을 넘겨 수정하게 한다.
이후에는 상세화면으로 돌아가게끔 했다.
수정 기능 확인하기



'IT > Spring Boot' 카테고리의 다른 글
[Spring Boot] 31. 게시판 답변 수정 기능 추가하기 (0) | 2024.05.20 |
---|---|
[Spring Boot] 30. 게시판 질문 삭제 기능 추가하기 (0) | 2024.05.20 |
[Spring Boot] 28. 게시판 작성자 기능 구현 (0) | 2024.05.10 |
[Spring Boot] 26. 로그인과 로그아웃 기능 구현하기(스프링 시큐리티) (0) | 2024.05.08 |
[Spring Boot] 25. 회원 가입 기능 구현하기 (0) | 2024.05.08 |