Validation (@Valid)
⚠️ 이 프로젝트의 게시글 작성/수정은 현재
@RequestParam으로 개별 파라미터를 받고 있음 (파일 업로드와 함께 처리하기 위해).
아래는 @Valid + DTO 바인딩 방식의 정석적인 사용법 정리.
1. 의존성
implementation 'org.springframework.boot:spring-boot-starter-validation'
2. DTO에 제약 조건 선언
// CommunityCreateDTO.java
@Getter
@NoArgsConstructor
@AllArgsConstructor
public class CommunityCreateDTO {
@NotBlank(message = "제목을 입력해주세요.")
@Size(max = 200, message = "제목은 200자 이하로 입력해주세요.")
private String title;
@NotBlank(message = "내용을 입력해주세요.")
private String content;
}
3. Controller에서 @Valid 적용
@PostMapping("/write")
public String write(@Valid @ModelAttribute CommunityCreateDTO createDTO,
BindingResult bindingResult) { // 반드시 @Valid 바로 다음에 위치
if (bindingResult.hasErrors()) {
return "community/write"; // 검증 실패 → 다시 폼으로
}
Long id = communityService.createCommunity(createDTO, null);
return "redirect:/community/" + id;
}
BindingResult가 없으면 검증 실패 시 바로 예외 발생
BindingResult가 있으면 직접 처리 가능
4. Thymeleaf에서 오류 메시지 표시
<form th:action="@{/community/write}" method="post" th:object="${communityCreateDTO}">
<div class="form-group">
<label>제목</label>
<input type="text" th:field="*{title}">
<!-- 검증 실패 시 오류 메시지 표시 -->
<span th:if="${#fields.hasErrors('title')}"
th:errors="*{title}"
style="color:red;">
</span>
</div>
<div class="form-group">
<label>내용</label>
<textarea th:field="*{content}"></textarea>
<span th:if="${#fields.hasErrors('content')}"
th:errors="*{content}"
style="color:red;">
</span>
</div>
<button type="submit">저장</button>
</form>
5. 주요 애노테이션
| 애노테이션 | 설명 | 예시 |
|---|---|---|
@NotNull |
null 불가 | 숫자, 날짜 등 |
@NotBlank |
null, 빈 문자열, 공백만 불가 | String |
@NotEmpty |
null, 빈 값 불가 (공백은 허용) | String, Collection |
@Size |
길이/크기 범위 | @Size(min=2, max=200) |
@Min |
최솟값 | @Min(0) |
@Max |
최댓값 | @Max(100) |
@Email |
이메일 형식 | @Email |
@Pattern |
정규식 | @Pattern(regexp = "...") |
@Positive |
양수 | @Positive |