27.유효성검사

강재영's avatar
Sep 13, 2024
27.유효성검사
 
 

1.라이브러리 추가

implementation 'org.springframework.boot:spring-boot-starter-aop' implementation 'org.springframework.boot:spring-boot-starter-validation'
 

2.리퀘스트객체 @NotEmpty 추가

package shop.mtcoding.blog.board; import jakarta.validation.constraints.NotEmpty; import lombok.Data; import shop.mtcoding.blog.user.User; public class BoardRequest { @Data public static class UpdateDTO { @NotEmpty private String title; @NotEmpty private String content; //요청dto는 중복되어도 따로만들기 //Insert할떄만 필요 /* public Board toEntity(User sessionUser) { return Board.builder() .title(title) .content(content) .user(sessionUser) .build(); }*/ } @Data public static class SaveDTO { @NotEmpty // 공백도 안되고 , null도 안됨 private String title; @NotEmpty private String content; public Board toEntity(User sessionUser) { return Board.builder() .title(title) .content(content) .user(sessionUser) .build(); } } }
 

2.GlobalValidationHandler 만들기

package shop.mtcoding.blog.core.error; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before; import org.springframework.stereotype.Component; import org.springframework.validation.Errors; import org.springframework.validation.FieldError; import shop.mtcoding.blog.core.error.ex.Exception400; @Component @Aspect //AOP 등록 public class GlobalValidationHandler { //@Before("@annotation(org.springframework.web.bind.annotation.PostMapping) || @annotation(org.springframework.web.bind.annotation.PutMapping)") @Before("@annotation(org.springframework.web.bind.annotation.PostMapping)") public void vaildCheck(JoinPoint jp) { //public String save(@Valid BoardRequest.SaveDTO saveDTO, Errors errors) { //스프링 기본전략 x-www-form-urlencoded 파싱 // Object[] args = jp.getArgs();//매개변수 /* System.out.println("사이즈 : " + args.length); for (Object arg : args) { System.out.println(arg); }*/ for (Object arg : args) { if (arg instanceof Errors) { Errors errors = (Errors) arg; if (errors.hasErrors()) { for (FieldError error : errors.getFieldErrors()) { throw new Exception400(error.getDefaultMessage() + " : " + error.getField()); } } } } } @Around("@annotation(shop.mtcoding.blog.core.Hello)") //@Before("@annotation(org.springframework.web.bind.annotation.GetMapping)") public Object hello1(ProceedingJoinPoint jp) throws Throwable { System.out.println("aop hello1 before 호출됨"); Object proceed = jp.proceed(); //@Hello 어노테이션이 붙은 함수 호출 System.out.println("aop hello1 after 호출됨"); System.out.println(proceed); return proceed; } }
 
@Before("@annotation(org.springframework.web.bind.annotation.PostMapping)")
PostMapping을 AOP하고 메소드의 파싱된 객체를 가져와서 유효성 검사를 실시
 

3.Controller

 
@PostMapping("/api/board/{id}/update") public String update(@PathVariable("id") int id, @Valid BoardRequest.UpdateDTO updateDTO, Errors errors) { User sessionUser = (User) session.getAttribute("sessionUser"); boardService.게시글수정(id, updateDTO, sessionUser); /*boardRepository.updateById(title, content, id);*/ return "redirect:/board/" + id; }
 
@Valid 어노테이션을 객체를 잡고 유효성검사 내용을 ERRORS객체에 담아준다.
 

4.pattern

 
package shop.mtcoding.blog.user; import jakarta.validation.constraints.NotEmpty; import jakarta.validation.constraints.Pattern; import lombok.Data; public class UserRequest { @Data public static class JoinDTO { @NotEmpty private String username; @NotEmpty private String password; @NotEmpty @Pattern(regexp = "^[\\w._%+-]+@[\\w.-]+\\.[a-zA-Z]{2,6}$", message = "이메일 형식으로 작성해주세요") private String email; //DTO -> UserObject public User toEntity() { //insert할때만 return User.builder().username(username).password(password).email(email).build(); } } @Data public static class LoginDTO { @NotEmpty private String username; @NotEmpty private String password; } }
 
@Pattern(regexp = "^[\\w._%+-]+@[\\w.-]+\\.[a-zA-Z]{2,6}$", message = "이메일 형식으로 작성해주세요")
요효성검사를 Pattern으로 만들어서 검사

정리

유효성검사를 if eals 이렇게 하지 않고 따로 AOP로 빼서 POST요청시 유효성검사를 실시하여 중복코드를 지우고 에러 발생시 throw로 던져버려서 한번에 관리하기 쉽게 하였다.
 
Share article

강재영 블로그