Validator 사용하기
데이터 검증은 form의 데이터를 파라미터로 받아 데이터를 조작하고 모델에 담아 뷰에 보여주는 과정에서 파라미터가 데이터로써 사용 가능한지 파악하는 단계

이런 Form에서 입력 값이 올바른지 validator를 통해 검증하는 것
ContentDto.java
package com.study.springboot;
import lombok.Data;
@Data
public class ContentDto {
private int id;
private String writer;
private String content;
}
- id,writer, contents 변수를 갖고 있음
- 롬복을 이용했으므로 getter, setter 등은 자동으로 작성됨 => 파라미터를 이 command객체를 통해 받을 수 있게 해줌
MyController.java
package com.study.springboot;
import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
public class MyController {
@RequestMapping("/")
public @ResponseBody String root() throws Exception{
return "Validator (1)";
}
@RequestMapping("/insertForm")
public String insert1() {
return "createPage";
}
@RequestMapping("/create")
public String insert2(@ModelAttribute("dto") ContentDto contentDto,
BindingResult result)
{
String page = "createDonePage";
System.out.println(contentDto);
ContentValidator validator = new ContentValidator();
validator.validate(contentDto, result);
if (result.hasErrors()) {
page = "createPage";
}
return page;
}
}
- 파라미터로 Command 객체를 받음
- @ModelAttribute는 command객체의 변수명을 이용해서 jsp페이지에서 이용할 수 있는 command객체의 이름이 길거나 다른 이름으로 만들고 싶을 때 사용하는 어노테이션 => ${dto,writer}이런식으로 이용
- contentsDto에 들어온 파라미터를 검증하기 위해 ContentValidator 타입의 변수 이용
- validate 검사 결과를 result 변수에 넣음
ContentValidator.java
package com.study.springboot;
import org.springframework.validation.Errors;
import org.springframework.validation.Validator;
public class ContentValidator implements Validator {
@Override
public boolean supports(Class<?> arg0) {
return ContentDto.class.isAssignableFrom(arg0); // 검증할 객체의 클래스 타입 정보
}
@Override
public void validate(Object obj, Errors errors) {
ContentDto dto = (ContentDto)obj;
String sWriter = dto.getWriter();
if(sWriter == null || sWriter.trim().isEmpty()) {
System.out.println("Writer is null or empty");
errors.rejectValue("writer", "trouble");
}
String sContent = dto.getContent();
if(sContent == null || sContent.trim().isEmpty()) {
System.out.println("Content is null or empty");
errors.rejectValue("content", "trouble");
}
}
}
- validator인터페이스를 implement
- validate함수에 검증하고 싶은 로직 구현
- 검증을 하고 에러가 나면 spring-boot-contain에서 관리하는 errors라는 빈 객체에다가 error를 넣어주면 다른 클래스에서도 사용 가능
- null이나 값이 비어 있으면 spring boot가 관리하는 errors 개체에 키값과 value값을 넣어주면 됨
ValidationUtils 사용하기
파라미터의 값을 구해 null인지 아니면 비어 있는지 체크하는 코드는 모든 개발자가 만들어야하는 코드임
=> 스프링 프레임워크에서 유틸리티 제공
ContentValidate.java
package com.study.springboot;
import org.springframework.validation.Errors;
import org.springframework.validation.ValidationUtils;
import org.springframework.validation.Validator;
public class ContentValidator implements Validator {
@Override
public boolean supports(Class<?> arg0) {
return ContentDto.class.isAssignableFrom(arg0); // 검증할 객체의 클래스 타입 정보
}
@Override
public void validate(Object obj, Errors errors) {
ContentDto dto = (ContentDto)obj;
ValidationUtils.rejectIfEmptyOrWhitespace(errors, "writer", "writer is empty.");
String sWriter = dto.getWriter();
if (sWriter.length() < 3) {
errors.rejectValue("writer", "writer is too short.");
}
ValidationUtils.rejectIfEmptyOrWhitespace(errors, "content", "content is empty.");
}
}
- validation-utils 패키지의 rejectIfEmptyOrWhitespace라는 메소드로 클래스를 별도로 new하지 않고 사용
- 이름이 없거나 화이트 스페이스면 errors 변수에 세번째 변수의 내용을 담겠다는 것
이렇게 기본으로 제공되는 메서드를 이용하거나 직접 만든 검증 로직을 통해 에러에 내용을 담아줄 수 있음
initBinder 사용하기
미리 제공되는 initBinder에 검증클래스를 이용해서 약한 결합을 만들고 validated annotation을 이용해서 코드를 간략화시켜보자

validater를 매번 새로운 객체를 할당함 => 스프링은 강한결합 비선호
MyController.java
package com.study.springboot;
import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
public class MyController {
@RequestMapping("/")
public @ResponseBody String root() throws Exception{
return "Validator (3)";
}
@RequestMapping("/insertForm")
public String insert1() {
return "createPage";
}
@RequestMapping("/create")
public String insert2(@ModelAttribute("dto") @Validated ContentDto contentDto,
BindingResult result)
{
String page = "createDonePage";
System.out.println(contentDto);
// ContentValidator validator = new ContentValidator();
// validator.validate(contentDto, result);
if (result.hasErrors()) {
if (result.getFieldError("writer") != null) {
System.out.println("1:" + result.getFieldError("writer").getCode());
}
if (result.getFieldError("content") != null) {
System.out.println("2:" + result.getFieldError("content").getCode());
}
page = "createPage";
}
return page;
}
@InitBinder
protected void initBinder(WebDataBinder binder) {
binder.setValidator(new ContentValidator());
}
}
- setValidator로 우리가 만든 ConetentValidator를 넣어주면 서비스가 만들어질 때 init가 될 때 최초의 한번만 new가 돼서 바인딩됨
- 단순히 에러가 있는지 확인하는 것뿐만 아니라 에러에 대해 키값을 이용해 에러를 찾아오고 출력함
Valid 어노테이션 사용하기
사용자가 검증 클래스를 만들지 않아도 어노테이션을 이용하여 파라미터를 쉽게 검증할 수 있음
ContentDto.java
package com.study.springboot;
import jakarta.validation.constraints.NotEmpty;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Size;
import lombok.Data;
@Data
public class ContentDto {
private int id;
@NotNull(message="writer is null.")
@NotEmpty(message="writer is empty.")
@Size(min=3, max=10, message="writer min 3, max 10.")
private String writer;
@NotNull(message="content is null.")
@NotEmpty(message="content is empty.")
private String content;
}
- 메세지로 에러 처리를 할 수 있음
MyController.java
@Controller
public class MyController {
@RequestMapping("/")
public @ResponseBody String root() throws Exception{
return "Validator (4)";
}
@RequestMapping("/insertForm")
public String insert1() {
return "createPage";
}
@RequestMapping("/create")
public String insert2(@ModelAttribute("dto") @Valid ContentDto contentDto,
BindingResult result)
{
String page = "createDonePage";
System.out.println(contentDto);
if (result.hasErrors()) {
// if (result.getFieldError("writer") != null) {
// System.out.println("1:" + result.getFieldError("writer").getCode());
// }
// if (result.getFieldError("content") != null) {
// System.out.println("2:" + result.getFieldError("content").getCode());
// }
if (result.getFieldError("writer") != null) {
System.out.println("1:"+result.getFieldError("writer").getDefaultMessage());
}
if (result.getFieldError("content") != null) {
System.out.println("2:"+result.getFieldError("content").getDefaultMessage());
}
page = "createPage";
}
return page;
}
// @InitBinder
// protected void initBinder(WebDataBinder binder) {
// binder.setValidator(new ContentValidator());
// }
}'개발 > Backend' 카테고리의 다른 글
| [SpringBoot] 예제로 배우는 스프링부트 입문 | JPA 기초 (0) | 2024.07.21 |
|---|---|
| [Spring Boot] 예제로 배우는 스프링부트 입문 | JdbcTemplate (0) | 2024.07.15 |
| [Spring Boot] 예제로 배우는 스프링부트 입문 | Web 기초 (0) | 2024.07.06 |
| [Spring Boot] 예제로 배우는 스프링부트 입문 | Dependency Injection (0) | 2024.07.03 |
| [JS 기초] CODEIT POWER BOOST 1주차 (0) | 2024.05.22 |