{"id":7657,"date":"2023-03-01T12:50:05","date_gmt":"2023-03-01T03:50:05","guid":{"rendered":"https:\/\/www.skyer9.pe.kr\/wordpress\/?p=7657"},"modified":"2023-03-04T08:06:04","modified_gmt":"2023-03-03T23:06:04","slug":"spring-boot-jstl-form-validation","status":"publish","type":"post","link":"https:\/\/www.skyer9.pe.kr\/wordpress\/?p=7657","title":{"rendered":"Spring Boot \u2013 JSTL form validation"},"content":{"rendered":"<h1>Spring Boot \u2013 JSTL form validation<\/h1>\n<p>Spring Boot \uae30\ubc18\uc73c\ub85c JSTL form validation \uc744 \ud558\ub294 \ubc29\ubc95\uc744 \uc815\ub9ac\ud569\ub2c8\ub2e4.<\/p>\n<h2>\uc758\uc874\uc131 \ucd94\uac00<\/h2>\n<pre><code class=\"language-groovy\">dependencies {\n    implementation &#039;org.apache.tomcat.embed:tomcat-embed-jasper&#039;\n    implementation &#039;org.springframework.boot:spring-boot-starter-validation&#039;\n    implementation &#039;javax.servlet:jstl&#039;\n}<\/code><\/pre>\n<h2>Form \ud074\ub798\uc2a4<\/h2>\n<p>DTO \uac1d\uccb4\uc640\ub294 \ubcc4\ub3c4\ub85c Form \uac1d\uccb4\uac00 \ud544\uc694\ud569\ub2c8\ub2e4.<\/p>\n<pre><code class=\"language-java\">@Getter\n@Setter\n@NoArgsConstructor\npublic class ItemForm {\n    private Long itemId;\n    private Long companyId;\n    @NotNull(message = &quot;\uace0\uac1d\uc0acID \ub97c \uc785\ub825\ud558\uc138\uc694.&quot;)\n    private Long partnerId;\n    private String companyName;\n    private String partnerName;\n    @NotBlank(message = &quot;\uc0c1\ud488\uba85\uc744 \uc785\ub825\ud558\uc138\uc694.&quot;)\n    private String itemName;\n    private String itemOptionName;\n    private Float weight;\n}<\/code><\/pre>\n<h2>Controller<\/h2>\n<p><code>itemForm<\/code> \uc740 <code>ItemForm<\/code> \uc640 \ub300\uc751\ud574\uc57c \ud569\ub2c8\ub2e4.<br \/>\n\ud3fc \ud074\ub798\uc2a4\uba85\uc5d0\uc11c \uccab\uae00\uc790\ub9cc \uc18c\ubb38\uc790\ub85c \ubcc0\uacbd\ud574\uc11c \uc0ac\uc6a9\ud569\ub2c8\ub2e4.<br \/>\n\uc774\ub984\uc774 \ub2e4\ub978 \uacbd\uc6b0 \uc624\ub958 \uba54\uc2dc\uc9c0\uac00 \ud45c\uc2dc\ub418\uc9c0 \uc54a\uc2b5\ub2c8\ub2e4.<\/p>\n<p><code>BindingResult<\/code> \ub294 \ud3fc \ud074\ub798\uc2a4 \ubc14\ub85c \ub2e4\uc74c\uc5d0 \uc704\uce58\ud574\uc57c \ud569\ub2c8\ub2e4.<\/p>\n<p>\uc624\ub958\uac00 \uc788\ub294 \uacbd\uc6b0 \ud3fc JSP \ub85c \ub2e4\uc2dc \uc774\ub3d9\uc2dc\ucf1c \uc90d\ub2c8\ub2e4.<\/p>\n<pre><code class=\"language-java\">@Controller\n@RequiredArgsConstructor\npublic class ItemController {\n    @GetMapping(&quot;\/item\/create&quot;)\n    public String create(ModelMap model) {\n        model.addAttribute(&quot;itemForm&quot;, new ItemForm());\n        return &quot;\/itemModify&quot;;\n    }\n\n    @PostMapping(&quot;\/item\/create&quot;)\n    public String doCreate(ModelMap model, @Valid ItemForm form, BindingResult bindingResult) {\n        if (bindingResult.hasErrors()) {\n            \/\/ List&lt;ObjectError&gt; list = bindingResult.getAllErrors();\n            \/\/ for (ObjectError error : list) {\n            \/\/     System.out.println(error);\n            \/\/ }\n            model.addAttribute(&quot;itemForm&quot;, form);\n            return &quot;\/itemModify&quot;;\n        }\n\n        service.create(form);\n        return &quot;redirect:\/item\/&quot;;\n    }<\/code><\/pre>\n<h2>JSP<\/h2>\n<p>\uc624\ub958\uac00 \uc788\ub294 \uacbd\uc6b0 \ud45c\uc2dc\ud574 \uc90d\ub2c8\ub2e4.<\/p>\n<pre><code class=\"language-jsp\">&lt;%@ taglib prefix=&quot;form&quot; uri=&quot;http:\/\/www.springframework.org\/tags\/form&quot; %&gt;\n&lt;%--@elvariable id=&quot;itemForm&quot; type=&quot;kr.pe.skyer9.warehouseweb.external.dto.ItemForm&quot;--%&gt;\n\n&lt;form:form id=&quot;frm&quot; name=&quot;frm&quot; modelAttribute=&quot;itemForm&quot;&gt;\n&lt;form:input path=&quot;itemName&quot; \/&gt;\n&lt;form:errors path=&quot;itemName&quot; \/&gt;\n&lt;\/form:form&gt;<\/code><\/pre>\n<h2>NumberFormatException<\/h2>\n<p>NumberFormatException \uc758 \uacbd\uc6b0 \ub514\ud3f4\ud2b8 \uc624\ub958 \uba54\uc2dc\uc9c0\uac00 \ub098\uc635\ub2c8\ub2e4.<\/p>\n<pre><code class=\"language-text\">Failed to convert property value of type java.lang.String to required type java.lang.Float for property sizeWidth; nested exception is java.lang.NumberFormatException: For input string: &quot;aa&quot;<\/code><\/pre>\n<p>\uc624\ub958\ub97c \ud55c\uad6d\uc5b4\ub85c \ubc14\uafb8\uae30 \uc704\ud574 \ub2e4\uc74c \uc124\uc815\uc744 \ud574\uc90d\ub2c8\ub2e4.<\/p>\n<p>application.yaml<\/p>\n<pre><code class=\"language-yaml\">spring:\n  messages:\n    basename: messages<\/code><\/pre>\n<p>resources\/messages.properties<\/p>\n<pre><code class=\"language-properties\"># typeMismatch.itemForm.sizeWidth=\uac00\ub85c \uc0ac\uc774\uc988\ub294 \uc22b\uc790\ub9cc \uc785\ub825\ud574\uc57c \ud569\ub2c8\ub2e4.\ntypeMismatch.java.lang.Float=\uc22b\uc790\ub85c \uc785\ub825\ud574\uc57c \ud569\ub2c8\ub2e4.<\/code><\/pre>\n<p><code>typeMismatch.\ud3fc\uc774\ub984.\ud544\ub4dc\uba85<\/code> \uc774 \uc788\ub294 \uacbd\uc6b0 \uadf8 \uc624\ub958\uba54\uc2dc\uc9c0\uac00 \ud45c\uc2dc\ub429\ub2c8\ub2e4.<br \/>\n\ub300\uc751\ud558\ub294 \ucf54\ub4dc\uac00 \uc5c6\ub294 \uacbd\uc6b0 <code>typeMismatch.java.lang.Float<\/code> \uc640 \uac19\uc774 \ubc94\uc6a9 \uc624\ub958\uba54\uc2dc\uc9c0\uac00 \ud45c\uc2dc\ub429\ub2c8\ub2e4.<\/p>\n<p><a href=\"https:\/\/www.skyer9.pe.kr\/wordpress\/wp-content\/uploads\/2023\/03\/2023-03-01-01.png\"><img decoding=\"async\" src=\"https:\/\/www.skyer9.pe.kr\/wordpress\/wp-content\/uploads\/2023\/03\/2023-03-01-01.png\" alt=\"\" \/><\/a><\/p>\n<h2>Form \ud074\ub798\uc2a4 \ubd84\ub9ac<\/h2>\n<p>\uc785\ub825\uc6a9 \ud074\ub798\uc2a4 \uc790\uccb4\ub97c \ubd84\ub9ac\ud558\ub294 \uac83\uc774 \uacb0\uacfc\uc801\uc73c\ub85c\ub294 \uc81c\uc77c \uac04\ub2e8\ud569\ub2c8\ub2e4.<\/p>\n<pre><code class=\"language-java\">public class UserCreateForm {\n}\n\npublic class UserModifyForm {\n}\n\npublic class UserChangePasswordForm {\n}<\/code><\/pre>\n<h2>Custom Validator<\/h2>\n<p>\ubcf5\ud569 \uc870\uac74\uacfc \uac19\uc740 \ud2b9\uc218\ud55c \uccb4\ud06c\ub97c \uc704\ud574 Custom Validator \ub97c \uc0dd\uc131\ud560 \uc218 \uc788\uc2b5\ub2c8\ub2e4.<\/p>\n<pre><code class=\"language-java\">import org.springframework.validation.Validator;\n\n@Component\npublic class UserCreateValidator implements Validator {\n    @Override\n    public boolean supports(Class&lt;?&gt; clazz) {\n        return UserCreateForm.class.isAssignableFrom(clazz);\n    }\n\n    @Override\n    public void validate(Object target, Errors errors) {\n        UserCreateForm dto = (UserCreateForm) target;\n\n        if (ObjectUtils.isEmpty(dto.getCompanyId())) {\n            errors.rejectValue(&quot;companyId&quot;, &quot;required&quot;, &quot;\uc5c5\uccb4ID \ub97c \uc785\ub825\ud558\uc138\uc694.&quot;);\n        }\n\n        if (!Objects.equals(dto.getUserLoginPassword(), dto.getUserLoginPassword2())) {\n            errors.rejectValue(&quot;userLoginPassword2&quot;, &quot;passwordNotMatch&quot;, &quot;\ube44\ubc00\ubc88\ud638\uac00 \uc77c\uce58\ud558\uc9c0 \uc54a\uc2b5\ub2c8\ub2e4.&quot;);\n        }\n    }\n}<\/code><\/pre>\n<p>userCreateForm \uc740 \uac80\uc99d\ud560 \ud074\ub798\uc2a4 UserCreateForm \uc5d0\uc11c \uccab\uae00\uc790\ub9cc \uc18c\ubb38\uc790\ub85c \ubcc0\uacbd\ud55c \uac83\uc785\ub2c8\ub2e4.<\/p>\n<pre><code class=\"language-java\">@Controller\n@RequiredArgsConstructor\npublic class AdminUserController {\n\n    private final UserService service;\n    private final UserCreateValidator userCreateValidator;\n\n    @InitBinder(&quot;userCreateForm&quot;)\n    public void initBinder(WebDataBinder webDataBinder) {\n        webDataBinder.addValidators(userCreateValidator);\n    }\n\n    @PostMapping(&quot;\/admin\/user\/create&quot;)\n    public String doCreate(@LoginInfo LoginInfoDto loginInfo, ModelMap model, @Valid UserCreateForm dto, BindingResult bindingResult) {\n        if (bindingResult.hasErrors()) {\n            setAttribute(loginInfo, model);\n            model.addAttribute(&quot;userCreateForm&quot;, dto);\n            return &quot;\/admin\/userModify&quot;;\n        }\n        service.create(loginInfo, dto);\n        return &quot;redirect:\/admin\/user\/&quot;;\n    }\n}<\/code><\/pre>\n","protected":false},"excerpt":{"rendered":"<p>Spring Boot \u2013 JSTL form validation Spring Boot \uae30\ubc18\uc73c\ub85c JSTL form validation \uc744 \ud558\ub294 \ubc29\ubc95\uc744 \uc815\ub9ac\ud569\ub2c8\ub2e4. \uc758\uc874\uc131 \ucd94\uac00 dependencies { implementation &#039;org.apache.tomcat.embed:tomcat-embed-jasper&#039; implementation &#039;org.springframework.boot:spring-boot-starter-validation&#039; implementation &#039;javax.servlet:jstl&#039; } Form \ud074\ub798\uc2a4 DTO \uac1d\uccb4\uc640\ub294 \ubcc4\ub3c4\ub85c Form \uac1d\uccb4\uac00 \ud544\uc694\ud569\ub2c8\ub2e4. @Getter @Setter @NoArgsConstructor public class ItemForm { private Long itemId; private Long companyId; @NotNull(message = &quot;\uace0\uac1d\uc0acID \ub97c \uc785\ub825\ud558\uc138\uc694.&quot;) private Long\u2026 <span class=\"read-more\"><a href=\"https:\/\/www.skyer9.pe.kr\/wordpress\/?p=7657\">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-7657","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\/7657","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=7657"}],"version-history":[{"count":5,"href":"https:\/\/www.skyer9.pe.kr\/wordpress\/index.php?rest_route=\/wp\/v2\/posts\/7657\/revisions"}],"predecessor-version":[{"id":7674,"href":"https:\/\/www.skyer9.pe.kr\/wordpress\/index.php?rest_route=\/wp\/v2\/posts\/7657\/revisions\/7674"}],"wp:attachment":[{"href":"https:\/\/www.skyer9.pe.kr\/wordpress\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=7657"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.skyer9.pe.kr\/wordpress\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=7657"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.skyer9.pe.kr\/wordpress\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=7657"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}