원본 본문으로 이동하기

스프링 컨트롤러와 파라미터 : 2. 파라미터 밸리데이션

박용서 - 스프링 컨트롤러와 파라미터 시리즈 1. 컨트롤러에서 파라미터를 받는 방법 - https://gs.saro.me/#!m=elec&jn=878 2. 파라미터 밸리데이션 - https://gs.saro.me/#!m=elec&jn=879 서론 이전 장에서는 컨트롤러에서 파라미터를 받는 방법에 대해서 강의하였습니다. 이번 장에서는 받은 파라미터에 대한 밸리데이션에 대해서 강의 해보도록 하겠습니다. 자바 스펙에는 아래와 같은 기본 밸리데이션 셋이 존재합니다. http://docs.oracle.com/javaee/7/api/javax/validation/constraints/package-summary.html 위 밸리데이션 중 몇가지만 정리하면 아래와 같습니다. - 설명이 간단하니 직접 링크를 보시는 것도 좋습니다. AssertFalse : 거짓인 경우만 통과 AssertTrue : 참인 경우만 통과 Future : 미래날짜인 경우만 통과 Past : 과거날짜인 경우만 통과 Pattern : 해당 패턴 내에서만 통과 Null : null 인 경우만 통과 NotNull : null 이 아닌 경우에만 통과 NotNull.List : 리스트 전체가 null 이 아닌 경우에만 통과 Size : 스트링의 사이즈 조건이 일치할 때 통과. Min : 숫자 형태의 최소 min 이상 [텍스트에서도 숫자로 치환하여 연산] Max : 숫자 형태의 최소 max 이상 [텍스트에서도 숫자로 치환하여 연산] @RequestParam를 통한 밸리데이션 @RestController class TempController { @GetMapping("/temp") String temp(@RequestParam(value="p1") @NotNull String p1) { return "통과"; } } 결과 : /temp - 오류 : p1 이 null 임 결과 : /temp?p1=abcde 통과 @GetMapping("/temp") String temp(@RequestParam(value="p1") @Valid @Pattern(regexp="[a-z]{3}") String p1) { return "통과"; } 결과 : /temp?p1=aa 통과 - 오류 나야하지 않나?? @Valid를 줘야하나? @GetMapping("/temp") String temp(@RequestParam(value="p1") @Valid @NotNull @Pattern(regexp="[a-z]{3}") String p1) { return "통과"; } 결과 : /temp?p1=aa 통과 - 그렇습니다. RequestParam 에서는 @NotNull 는 사용할 수 있으나 @Pattern 을 사용할 수 없습니다. - 심지어 @NotNull 보단 아래 방법이 더 나을 겁니다. String temp(@RequestParam(value="p1", required=true) String p1) 그럼 모델을 가지고 해보도록 하겠습니다. 모델 클래스를 통한 밸리데이션 @RestController class TempController { @GetMapping("/temp") String temp(@Valid Abc abc) { return "통과 : " + p1; } @Data @ToString @Getter @Setter static public class Abc { @NotNull @Pattern(regexp = "[a-z]{3}") String p1 = "default"; } } 결과 : /temp - 오류 : p1 이 null 임 결과 : /temp?p1=Daa - 오류 : p1 이 영문소문자3자("[a-z]{3}") 가 아니다. 결과 : /temp?p1=try 통과 : try 그렇다면 파라미터를 체크하는 것인가? 또한 다중 조건들이 될 것인가? @RestController class TempController { @GetMapping("/temp") String temp(@Valid Abc abc) { return "통과 : " + abc.getP1(); } @Data @ToString @Getter @Setter static public class Abc { @NotNull @Size(min=1, max=10) String p1 = "default"; @Min(1) @Max(100) int p2 = 1; } } 결과 : /temp 통과 : TempController.Abc(p1=default, p2=1) 파라미터를 체크하는 것이 아닌 모델을 체크하는 것 입니다.!!! 즉, 아무런 인자를 넣지 않았지만 모델이 조건에 맞으니 통과합니다. 결과 : /temp?p1=AbcdeAbcdea - 오류 : p1의 길이가 10자를 넘어갑니다. 결과 : /temp?p1=AbcdeAbc&p2=32 통과 : TempController.Abc(p1=AbcdeAbc, p2=32) @Data @ToString @Getter @Setter static public class Abc { @NotNull @Min(1) @Max(100) String p1; @Min(1) @Max(100) int p2 = 1; } 결과 : /temp - 오류 : p1 이 null 입니다. 결과 : /temp?p1=a - 오류 : @Min(1) @Max(100) 조건으로 p1은 숫자 형태여야합니다. 결과 : /temp?p1=33 통과 : TempController.Abc(p1=33, p2=1) - 스트링으로 받아야하지만 숫자로 검증할 때 유용합니다. PathVariable - 앞 장에서도 설명됬지만 PathVariable 은 새로운 형태에 다른 플로우를 타는 것이 아닌 표현방식이 다른것 입니다. - 즉, 사용법은 같습니다. @RestController class TempController { @GetMapping("/temp/{p1}") String temp(@Valid Abc abc) { return "통과 : " + abc.toString(); } @Data @ToString @Getter @Setter static public class Abc { @NotNull @Min(1) @Max(1000) String p1; } } 결과 : /temp/a - 오류 : @Min(1) @Max(1000) 조건으로 오직 숫자 형태로 넘겨야합니다. 결과 : /temp/23231 - 오류 : 범위를 초과합니다. 결과 : /temp/23 통과 : TempController.Abc(p1=23) 기타 : 날짜 - 날짜 같은경우는 입력 포멧을 설정해 주어야 합니다. @RestController class TempController { @GetMapping("/temp") String temp(@Valid Abc abc) { return "통과 : " + abc.toString(); } @Data @ToString @Getter @Setter static public class Abc { @NotNull @Future @DateTimeFormat(pattern = "yyyyMMdd") Date date; } } 결과 [작성일로부터 과거날짜] : /temp?date=20001122 - 오류 결과 [작성일로부터 미래날짜] : /temp?date=20171122 통과 : TempController.Abc(date=Wed Nov 22 00:00:00 KST 2017) 추신 - null이 있는 조것들은 @NotNull 을 주지 않으면 조건에 맞지 않더라도 통과됩니다.!! - 스프링 자바