Spring객체 저장방식과 폼유효성검사
BindingResult와 @Valid를 이용해 폼 유효성검사를 하는 방법과 설명
1) message.properties 사용 전 세팅법
#message
#message.properties파일을 사용하겠다는 의미 (인코딩방식은 UTF-8)
spring.messages.basename=messages
spring.messages.encoding=UTF-8
application.properties에서 다음과같이 message.properties를 사용하겠다고 선언
error.dto.pass = 비밀번호가틀려요
내가 message.properties에 설정해놓은 에러명과 문자
2) 사용과 설명
DTO
package kr.gdu.dto.board;
import jakarta.validation.constraints.NotEmpty;
import lombok.Data;
@Data
public class DeleteBoardDto {
private int num;
@NotEmpty(message="비밀번호를 입력해")
private String pass;
private String boardid;
}
valid에서 제공하는 @NotEmpty를 사용해 빈값으로 폼을 제출하면 해당 message를 띄울거임
controller
@PostMapping("delete")
public String delete(
@Valid @ModelAttribute DeleteBoardDto dto,BindingResult bresult,Model model) {
if(bresult.hasErrors()) {
model.addAttribute("num",dto.getNum());
model.addAttribute("boardid",dto.getBoardid());
return "board/delete";
}
Board dbBoard = service.getBoard(dto.getNum());
if(!dbBoard.getPass().equals(dto.getPass())) {
bresult.reject("error.dto.pass");
model.addAttribute("num",dto.getNum());
model.addAttribute("boardid",dto.getBoardid());
return "board/delete";
}
service.boardDelete(dto);
return "redirect:list?boardid="+dbBoard.getBoardid();
}
bresult.hasErrors() : @Valid 검증 결과(에러 포함)를 저장합니다.
bresult.reject("error.dto.pass") : message.properties의 error.dto.pass메시지를 띄움
@Valid 검증 후 BindingResult를 확인하는 추가적인 검증을 실시함
빈값으로 제출하게되면 @NotEmpty의 오류가 view에 뜨게될거고
비밀번호가 틀리다면 message.properties에 error.dto.pass로 설정해둔 메시지를띄울것임
view
<%@ taglib prefix="spring" uri="http://www.springframework.org/tags"%>
<form:form modelAttribute="deleteBoardDto" action="delete">
<!-- 객체의 이름 : deleteBoardDto(@Valid DeleteBoardDto dto) -->
<spring:hasBindErrors name="deleteBoardDto">
<div class="error-message">
<c:forEach items="${errors.globalErrors}" var="error">
<spring:message code="${error.code}" /><br>
</c:forEach>
</div>
</spring:hasBindErrors>
<input type="hidden" name="num" value="${param.num}">
<input type="hidden" name="boardid" value="${param.boardid}">
<div class="mb-3">
<label for="pass" class="form-label">게시글 비밀번호</label>
<input type="password" name="pass" class="form-control" id="pass" onkeyup="delError()" placeholder="비밀번호를 입력하세요">
<div class="error-message"><form:errors path="pass" id="err"/></div>
</div>
<button type="submit" class="btn btn-primary">게시글 삭제</button>
</form:form>
다음과 같이 일반적인 폼태그내에서
비밀번호를 입력해 delete란 이름으로 폼을 보내는 페이지이다.
springFramwork태그를 선언 하면
spring:hasBindError,message를 사용할수있음
일단 spring:hasBindErrors 태그 내에는 에러메시지를 처리하는 부분이라고
생각을 하면 됨.
name="deleteBoardDto": 컨트롤러에서 @Valid @ModelAttribute DeleteBoardDto dto로
바인딩된 객체의 이름 , 스프링에서는 클래스명의 시작문자를 소문자로바꿔서 객체로 저장
name="DeleteBoardDto"와 같이 내가 저장한 객체명과 똑같이 작성 시 인식X
<c:forEach items="${errors.globalErrors}" var="error">
<spring:message code="${error.code}" /><br>
</c:forEach>
해당부분은 컨트롤러부분에서 Bindingresult.reject("메시지이름") 가 발생하면
해당 message.properties를 찾아가 설정한에러명의 문자를 가져옴
<div class="error-message"><form:errors path="pass" id="err"/></div>
bindingresult.hasError()을 이용해 valid검증 결과가 에러가 나면
dto객체의 pass에서 설정해둔 @NotEmpty메시지를 띄우게됨
추가 디테일)
기본적으로 에러메시지를 계속 띄우고있기때문에
script문을 이용해 각 에러메시지에 class또는 id를 달아준 후
키입력이 들어오면 에러메시지를 사라지게 하는 방식을추천
<script type="text/javascript">
function delError(){
const err = document.querySelector(".error-message");
const passError = document.querySelector("#err");
err.style.display = 'none';
passError.style.display='none';
}
</script>