-
[ Spring Boot + JPA + Thymeleaf ] validation 추가Spring Boot 2021. 3. 2. 21:39
Bean Validation
도메인 로직에서 값을 검증할 수 있게 도와주는 인터페이스이다.
주요 어노테이션들은 아래와 같다.
<직접 검증을 하고 싶을 때 사용>
@AssertTrue
@AssertFalse
<문자열을 다룰 때 사용>
@NotNull // null 불가능
@NotEmpty // null, 빈 문자열(스페이스 포함X) 불가
@NotBlank // null, 빈 문자열, 스페이스만 포함한 문자열 불가
@Size(min=?, max=?) // 최소 길이, 최대 길이 제한
@Null // null만 가능
<숫자를 다룰 때 사용>
@Positive // 양수만 허용
@PositiveOrZero // 양수와 0만 허용
@Negative // 음수만 허용
@NegativeOrZero // 음수와 0만 허용
@Min(?) // 최소값 제한
@Max(?) // 최대값 제한
<정규식 관련>
@Email // 이메일 형식만가능 (기본 제공)
@Pattern(regexp="?") // 직접 정규식을 쓸 수 있음
사용방법은,
검증하고자 하는 Entity에 @Valid를 붙이며, 이에 대한 결과를 받기 위해 BindingResult를 추가하여 사용할 수 있다.
Depedency
dependencies { compile('org.springframework.boot:spring-boot-starter-web') compile('org.springframework.boot:spring-boot-starter-validation') compile('org.projectlombok:lombok') runtime('com.h2database:h2') testCompile('org.springframework.boot:spring-boot-starter-test') }
Controller
- BoardController.java
import com.example.myhome.model.Board; import com.example.myhome.repository.BoardRepository; import com.example.myhome.validator.BoardValidator; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; @Autowired private BoardRepository boardRepository; @Autowired private BoardValidator boardValidator; // 리스트 출력 @GetMapping("/list") public String form(Model model, @RequestParam(required = false) Long id){ return "board/form"; } @PostMapping("/form/save") public String saveForm(@Valid Board board, BindingResult bindingResult){ boardValidator.validate(board, bindingResult); if(bindingResult.hasErrors()){ return "board/form"; } boardRepository.save(board); return "redirect:/board/list"; }
saveForm 메서드를 보면 @Valid와 BindingResult를 추가한것을 볼수있다.
bindingResult값을 받아와 hasErrors()를 사용하여 유효성을 통과하였는지 확인하는것이다.
boardValidator.validate(board, bindingResult); 코드에 대해서는 하단에서 다시 설명할것이다.
Model
- Board.java
package com.example.myhome.model; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.validation.constraints.NotNull; import javax.validation.constraints.Size; @Entity @Data public class Board { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; @NotNull @Size(min=2,max=30) private String title; private String content; }
어노테이션을 사용하여 게시물 제목 글자수를 2~30글자까지만 제한하도록 명시하였다.
View
- form.html
<input type="hidden" th:field="*{id}"> <div class="mb-3"> <label for="exampleFormControlInput1" class="foboardrm-label">제목</label> <input type="text" class="form-control" id="exampleFormControlInput1" th:field="*{title}"> <input type="text" class="form-control" id="exampleFormControlInput1" th:classappend="${#fields.hasErrors('title')} ? 'is-invalid' " th:field="*{title}"> <div class="invalid-feedback" th:if="${#fields.hasErrors('title')}" th:errors="*{title}"> 제목 에러메시지 </div> </div> <div class="mb-3"> <label for="exampleFormControlTextarea1" class="form-label">내용</label> <textarea class="form-control" id="exampleFormControlTextarea1" rows="3" th:field="*{content}"></textarea> <textarea class="form-control" id="exampleFormControlTextarea1" rows="3" th:classappend="${#fields.hasErrors('content')} ? 'is-invalid' " th:field="*{content}"></textarea> <div class="invalid-feedback" th:if="${#fields.hasErrors('content')}" th:errors="*{content}"> 내용 에러메시지 </div> </div> <div class="text-right"> <a type="button" class="btn btn-primary" th:href="@{/board/list}">이전</a>
만일 해당 조건을 충족하지 못했을 경우 에러메시지를 표현해주기 위하여 form페이지에 Thymeleaf문법으로 에러메시지 출력 부분을 추가해주었다.
하지만, 위의 제공되는 에노테이션 말고 다른 방식으로 검증방식을 추가해야 할 경우 직접 클래스를 만들어 사용하는 방법도 있다.
Custom Validation
validator패키지 생성 후 BoardValidator.java 파일을 생성해준다.
- BoardValidator.java
package com.example.myhome.validator; import com.example.myhome.model.Board; import org.springframework.stereotype.Component; import org.springframework.validation.Errors; import org.springframework.validation.Validator; import org.thymeleaf.util.StringUtils; @Component public class BoardValidator implements Validator { @Override public boolean supports(Class<?> clazz) { return Board.class.equals(clazz); } @Override public void validate(Object obj, Errors errors) { Board b = (Board) obj; if(StringUtils.isEmpty(b.getContent())){ errors.rejectValue("content","key","내용을 입력하세요"); } } }
validator를 상속하는 클래스를 작성해주고 validate 메서드에 추가하고 싶은 제한조건에 대해 작성 후
BoardController에서 BoardValidator를 @Autowired 후 validate메서드를 사용해준다.
@PostMapping("/form/save") public String saveForm(@Valid Board board, BindingResult bindingResult){ boardValidator.validate(board, bindingResult); if(bindingResult.hasErrors()){ return "board/form"; } boardRepository.save(board); return "redirect:/board/list"; }
'Spring Boot' 카테고리의 다른 글
[ Spring Boot + JPA + Thymeleaf ] 검색 기능 구현 (0) 2021.03.04 [ Spring Boot + JPA + Thymeleaf ] 페이징 기능 구현 (0) 2021.03.04 [ Spring Boot + JPA + Thymeleaf ] 로그인/회원가입 (0) 2021.02.23 [ Spring Boot + JPA + Thymeleaf ] 게시판 만들기 - 3 (0) 2021.02.10 [ Spring Boot + JPA + Thymeleaf ] 게시판 만들기 - 2 (0) 2021.02.10