There was an unexpected error (type=Internal Server Error, status=500).
An error happened during template parsing (template: "class path resource [templates/post/createPostForm.html]")
org.thymeleaf.exceptions.TemplateInputException: An error happened during template parsing (template: "class path resource [templates/post/createPostForm.html]")
Caused by: org.attoparser.ParseException: Error during execution of processor 'org.thymeleaf.spring5.processor.SpringInputGeneralFieldTagProcessor' (template: "post/createPostForm" - line 23, col 30)
Caused by: org.thymeleaf.exceptions.TemplateProcessingException: Error during execution of processor 'org.thymeleaf.spring5.processor.SpringInputGeneralFieldTagProcessor' (template: "post/createPostForm" - line 23, col 30)
Caused by: java.lang.IllegalStateException: Neither BindingResult nor plain target object for bean name 'post' available as request attribute
타임리프에서 객체 post를 사용할 수 없다는 의미다.
💕 해결 및 관련 코드
@Setter
@Getter
@NoArgsConstructor
public class PostRequestDto {
private Long id;
@NotBlank(message="제목을 작성해주세요.")
@Size(max=30, message="제목은 30자 이하입니다.")
private String title;
private String author;
@NotBlank(message="내용을 작성해주세요.")
@Size(max=10000, message="10,000자 이하로 작성하세요.")
private String content;
private int view;
private LocalDateTime createdDate;
private LocalDateTime modifiedDate;
private List<CommentResponseDto> comments;
}
DTO에 validation 어노테이션을 붙였다.
저기에 설정한 메시지가 프런트에 출력되도록 할 것이다.
@PostMapping("/new")
public String create(@ModelAttribute("post") @Valid PostRequestDto post, BindingResult bindingResult) {
if(bindingResult.hasErrors()){
return "post/createPostForm";
}
Object principal= SecurityContextHolder.getContext().getAuthentication().getPrincipal();
post.setAuthor(((UserDetails)principal).getUsername()); // 작성자=로그인한 유저 id
postService.create(post);
return "redirect:/post";
}
@ModelAttribute("post")를 파라미터에 추가했다. 성공😊
<form action="#" th:action="@{'/post/detail/' + ${post.id}}" th:object="${post}" method="post">
<input type="hidden" name="_method" value="put">
<input id="postId" type="hidden" th:field="*{id}">
<div class="form-group">
<label for="title">제목</label>
<input type="text" class="form-control"
th:classappend="${#fields.hasErrors('title')} ? 'is-invalid'" id="title" th:field="*{title}" required>
<div class="invalid-feedback" th:if="${#fields.hasErrors('title')}" th:errors="*{title}">
제목 에러 메시지
</div>
</div>
<div class="form-group">
<label for="content">내용</label>
<textarea class="form-control" id="content" rows="3" th:field="*{content}"
th:classappend="${#fields.hasErrors('content')} ? 'is-invalid'" required></textarea>
<div class="invalid-feedback" th:if="${#fields.hasErrors('content')}" th:errors="*{content}">
내용 에러 메시지
</div>
</div>
<div style="float:right;" th:with="username=${#authentication.name}">
<a type="button" class="btn btn-primary" th:href="@{/post}">취소</a>
<button class="btn btn-primary" th:if="${#strings.equals(post.author, username)}" onclick="updatePost();">수정</button>
</div>
</form>
th:object는 지역번수 선언
th:object="${post}"는 위에서 @ModelAttribute("post")로 설정한 것
th:if="${#fields.hasErrors('title')}"은 title 필드에 validation 에러가 있으면 th:errors="*{title}" title 필드의 에러 출력
input 또는 textarea의 th:field와 th:errors를 똑같이 맞춰준다.
th:classappend는 CSS 클래스 또는 스타일 조각을 기존 요소를 덮어쓰지 않고 요소에 추가할 때 사용한다. 필수가 아니라는 의미.
required 속성 지우고 실행해보니 백엔드의 validation 메시지가 잘 출력된다 😊
참고 👇
https://www.baeldung.com/spring-thymeleaf-error-messages
https://www.thymeleaf.org/doc/tutorials/2.1/thymeleafspring.html
https://www.thymeleaf.org/doc/tutorials/2.1/usingthymeleaf.html
반응형
'Framework > Spring Boot' 카테고리의 다른 글
전체 게시글 목록에서 각 게시글의 댓글 수 출력 (0) | 2022.07.07 |
---|---|
댓글 최신순 정렬 (0) | 2022.06.08 |
DTO (0) | 2022.05.24 |
[Error] Error creating bean with name 'emailConfig': Injection of autowired dependencies failed; (0) | 2022.03.04 |
JavaMailSender를 이용한 메일 전송 (0) | 2022.03.03 |