{"id":7614,"date":"2023-02-18T14:20:27","date_gmt":"2023-02-18T05:20:27","guid":{"rendered":"https:\/\/www.skyer9.pe.kr\/wordpress\/?p=7614"},"modified":"2023-02-18T14:25:53","modified_gmt":"2023-02-18T05:25:53","slug":"spring-boot-valid","status":"publish","type":"post","link":"https:\/\/www.skyer9.pe.kr\/wordpress\/?p=7614","title":{"rendered":"Spring Boot &#8211; @Valid"},"content":{"rendered":"<h1>Spring Boot &#8211; @Valid<\/h1>\n<p>@Valid \uc0ac\uc6a9\ubc29\ubc95 \ubc0f MethodArgumentNotValidException \ucc98\ub9ac \ubc29\ubc95\uc744 \uc815\ub9ac\ud574\ubd05\ub2c8\ub2e4.<\/p>\n<h2>\uc758\uc874\uc131 \ucd94\uac00<\/h2>\n<pre><code class=\"language-gradle\">dependencies {\n    implementation &#039;org.springframework.boot:spring-boot-starter-validation&#039;\n}<\/code><\/pre>\n<h2>DTO<\/h2>\n<pre><code class=\"language-java\">@Getter\n@Setter\n@NoArgsConstructor\npublic class LoginRequestDto {\n    @NotEmpty(message = &quot;\ub85c\uadf8\uc778 \uc544\uc774\ub514\ub97c \uc785\ub825\ud558\uc138\uc694&quot;)\n    private String userLoginId;\n    @NotEmpty(message = &quot;\ub85c\uadf8\uc778 \ube44\ubc00\ubc88\ud638\ub97c \uc785\ub825\ud558\uc138\uc694&quot;)\n    private String userLoginPassword;\n}<\/code><\/pre>\n<h2>Controller<\/h2>\n<pre><code class=\"language-java\">@RestController\n@RequiredArgsConstructor\n@RequestMapping(&quot;\/v1\/login&quot;)\npublic class LoginController {\n    @PostMapping(&quot;\/&quot;)\n    public ResponseEntity&lt;?&gt; login(@Valid @RequestBody LoginRequestDto dto) {\n        return service.login(dto);\n    }\n}<\/code><\/pre>\n<h2>RestControllerAdvice<\/h2>\n<pre><code class=\"language-java\">@RestControllerAdvice(&quot;kr.pe.skyer9.warehouse.account.web&quot;)\npublic class AccountRestExceptionHandler {\n    @ExceptionHandler(MethodArgumentNotValidException.class)\n    public ResponseEntity&lt;?&gt; handleMethodArgumentNotValidException(MethodArgumentNotValidException e) {\n        return ResponseEntity.status(460) \/\/ 460 = custom error code\n                .body(\n                        new ApiResponseMessage(\n                                ResponseCode.ERROR_FIELD_REQUIRED,\n                                e.getBindingResult().getAllErrors().get(0).getDefaultMessage())\n                );\n    }\n}<\/code><\/pre>\n<h2>Feign error handling<\/h2>\n<p>\uc218\uc2e0\ubd80\uac00 Feign \uc778 \uacbd\uc6b0 \uc544\ub798\ucc98\ub7fc @ControllerAdvice \ub97c \uc774\uc6a9\ud574 \ucc98\ub9ac\ud560 \uc218 \uc788\uc2b5\ub2c8\ub2e4.<\/p>\n<pre><code class=\"language-java\">public class FeignErrorDecoder implements ErrorDecoder {\n    @Override\n    public Exception decode(String methodKey, Response response) {\n        switch (response.status()) {\n            case 460: \/\/ 460 = custom error code\n                ApiResponseMessage message;\n                try (InputStream bodyIs = response.body().asInputStream()) {\n                    ObjectMapper mapper = new ObjectMapper();\n                    message = mapper.readValue(bodyIs, ApiResponseMessage.class);\n                } catch (IOException e) {\n                    return new Exception(e.getMessage());\n                }\n                return new ApiServerException(message.getMessage());\n            default:\n                return new Exception(response.reason());\n        }\n        return null;\n    }\n}<\/code><\/pre>\n<pre><code class=\"language-java\">public class ApiServerException extends RuntimeException {\n    public ApiServerException(String message) {\n        super(message);\n    }\n}<\/code><\/pre>\n<pre><code class=\"language-java\">@ControllerAdvice\npublic class ApiServerExceptionHandler {\n    @ExceptionHandler({ApiServerException.class})\n    public ResponseEntity&lt;?&gt; handleApiServerException(HttpServletResponse response, ApiServerException ex) throws IOException {\n        ScriptUtil.alertAndBackPage(response, ex.getMessage());\n        return null;\n    }\n}<\/code><\/pre>\n","protected":false},"excerpt":{"rendered":"<p>Spring Boot &#8211; @Valid @Valid \uc0ac\uc6a9\ubc29\ubc95 \ubc0f MethodArgumentNotValidException \ucc98\ub9ac \ubc29\ubc95\uc744 \uc815\ub9ac\ud574\ubd05\ub2c8\ub2e4. \uc758\uc874\uc131 \ucd94\uac00 dependencies { implementation &#039;org.springframework.boot:spring-boot-starter-validation&#039; } DTO @Getter @Setter @NoArgsConstructor public class LoginRequestDto { @NotEmpty(message = &quot;\ub85c\uadf8\uc778 \uc544\uc774\ub514\ub97c \uc785\ub825\ud558\uc138\uc694&quot;) private String userLoginId; @NotEmpty(message = &quot;\ub85c\uadf8\uc778 \ube44\ubc00\ubc88\ud638\ub97c \uc785\ub825\ud558\uc138\uc694&quot;) private String userLoginPassword; } Controller @RestController @RequiredArgsConstructor @RequestMapping(&quot;\/v1\/login&quot;) public class LoginController { @PostMapping(&quot;\/&quot;) public ResponseEntity&lt;?&gt; login(@Valid\u2026 <span class=\"read-more\"><a href=\"https:\/\/www.skyer9.pe.kr\/wordpress\/?p=7614\">Read More &raquo;<\/a><\/span><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[29],"tags":[],"class_list":["post-7614","post","type-post","status-publish","format-standard","hentry","category-spring-boot-2-5"],"_links":{"self":[{"href":"https:\/\/www.skyer9.pe.kr\/wordpress\/index.php?rest_route=\/wp\/v2\/posts\/7614","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.skyer9.pe.kr\/wordpress\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.skyer9.pe.kr\/wordpress\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.skyer9.pe.kr\/wordpress\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.skyer9.pe.kr\/wordpress\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=7614"}],"version-history":[{"count":2,"href":"https:\/\/www.skyer9.pe.kr\/wordpress\/index.php?rest_route=\/wp\/v2\/posts\/7614\/revisions"}],"predecessor-version":[{"id":7616,"href":"https:\/\/www.skyer9.pe.kr\/wordpress\/index.php?rest_route=\/wp\/v2\/posts\/7614\/revisions\/7616"}],"wp:attachment":[{"href":"https:\/\/www.skyer9.pe.kr\/wordpress\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=7614"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.skyer9.pe.kr\/wordpress\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=7614"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.skyer9.pe.kr\/wordpress\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=7614"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}