{"id":15198,"date":"2013-07-08T01:00:05","date_gmt":"2013-07-07T22:00:05","guid":{"rendered":"http:\/\/www.javacodegeeks.com\/?p=15198"},"modified":"2013-07-07T22:24:34","modified_gmt":"2013-07-07T19:24:34","slug":"spring-mvc-custom-validation-annotations","status":"publish","type":"post","link":"https:\/\/www.javacodegeeks.com\/2013\/07\/spring-mvc-custom-validation-annotations.html","title":{"rendered":"Spring MVC Custom Validation Annotations"},"content":{"rendered":"<p>Last tutorial, I showed how to <a title=\"Spring MVC Form Validation with Annotations Tutorial\" href=\"http:\/\/codetutr.com\/2013\/05\/28\/spring-mvc-form-validation\/\">validate a form using annotations<\/a>. This works great for simple validations, but eventually, you\u2019ll need to validate some custom rules that aren\u2019t available in the out-of-the-box annotations. For example, what if you need to validate that a user is over 21 years old, calculated based off their input birthdate, or, maybe you need to validate that the user\u2019s phone area code is in Nebraska, USA. This tutorial with full source code will show how to create custom validation annotations that you can use along-side the JSR-303 and Hibernate Validator annotations we explored in the last tutorial.<\/p>\n<p>You can grab the code for this tutorial <a title=\"Spring MVC Validation Source Code\" href=\"https:\/\/github.com\/stevehanson\/spring-mvc-validation\" target=\"_blank\">on GitHub<\/a> if you want to follow along.<\/p>\n<p>For this example, let\u2019s say we have a form with a phone number field and a birthdate field, and we want to validate the the phone number is valid (simple check for format) and that the user was born in 1989. There are no out-of-the-box annotations that support these (as far as I know), so we will write custom validation annotations which we can then re-use, just like the built-in JSR-303 ones.<\/p>\n<p>When we are done, we will apply our annotations to our form object, like so:<\/p>\n<pre class=\" brush:java\">public class Subscriber {\r\n\r\n    ...\r\n\r\n\t@Phone\r\n\tprivate String phone;\r\n\r\n\t@Year(1989)\r\n\tprivate Date birthday;\r\n\r\n    \/\/ getters setters ...\r\n\r\n}<\/pre>\n<p>Let\u2019s get started with the @Phone annotation. We will be creating two classes: <code>Phone<\/code>, which is the annotation, and <code>PhoneConstraintValidator<\/code> which contains the validation logic. The first step is to create the <code>Phone<\/code> annotation class:<\/p>\n<pre class=\" brush:java\">@Documented\r\n@Constraint(validatedBy = PhoneConstraintValidator.class)\r\n@Target( { ElementType.METHOD, ElementType.FIELD })\r\n@Retention(RetentionPolicy.RUNTIME)\r\npublic @interface Phone {\r\n\r\n\tString message() default \"{Phone}\";\r\n\r\n\tClass&lt;?&gt;[] groups() default {};\r\n\r\n\tClass&lt;? extends Payload&gt;[] payload() default {};\r\n\r\n}<\/pre>\n<p>The code above is mostly just boiler-plate. The three methods in the annotation are required by the JSR-303 spec. If our annotation accepted any arguments, we would have defined them there as methods. We will see this in our next annotation later in this tutorial. The most important part of the class above is the <code>@Constraint<\/code> annotation on the class which specifies that we will use our <code>PhoneConstraintValidator<\/code> class for the validation logic. The <code>message()<\/code> method defines how the message is resolved. By specifying \u201c{Phone}\u201d, we can override the message in a Spring resource bundle using the <code>Phone<\/code> key (see my other <a title=\"Spring MVC Form Validation with Annotations Tutorial\" href=\"http:\/\/codetutr.com\/2013\/05\/28\/spring-mvc-form-validation\/\">validation tutorial<\/a> for details about messages).<div style=\"display:inline-block; margin: 15px 0;\"> <div id=\"adngin-JavaCodeGeeks_incontent_video-0\" style=\"display:inline-block;\"><\/div> <\/div><\/p>\n<p>Now, we define the constraint validator:<\/p>\n<pre class=\" brush:java\">public class PhoneConstraintValidator implements ConstraintValidator&lt;Phone, String&gt; {\r\n\r\n\t@Override\r\n\tpublic void initialize(Phone phone) { }\r\n\r\n\t@Override\r\n\tpublic boolean isValid(String phoneField, ConstraintValidatorContext cxt) {\r\n\t\tif(phoneField == null) {\r\n\t\t\treturn false;\r\n\t\t}\r\n\t\treturn phoneField.matches(\"[0-9()-\\.]*\");\r\n\t}\r\n\r\n}<\/pre>\n<p>Let\u2019s look at the above code. The templated type of the superclass takes two types: the type of the annotation it supports, and the type of the property it validates (in this example, Phone, String).<\/p>\n<p>The \u201cinitialize\u201d method is empty here, but it can be used to save data from the annotation, as we will see below when we define our other annotation.<\/p>\n<p>Finally, the actual logic happens in the \u201cisValid\u201d method. The field value is passed in as the first argument, and we do our validation here. As you can see, I am just validating that the phone number only contains numbers, parentheses or dashes.<\/p>\n<p>That\u2019s it for this annotation! The annotation can now be used on a field as shown above on our form object.<\/p>\n<p>Now, let\u2019s do our second annotation. This one is a little contrived \u2013 we will validate that the user\u2019s birthdate is in 1989. In the future, we may need to validate dates are in other years, though, so rather than create an annotation that validates the year to be 1989, we will let it take an argument to specify the year to validate against. Example usage:<\/p>\n<pre class=\" brush:java\">@Year(1989)\r\nprivate Date birthDate;<\/pre>\n<p>Now, the annotation:<\/p>\n<pre class=\" brush:java\">@Documented\r\n@Constraint(validatedBy = YearConstraintValidator.class)\r\n@Target( { ElementType.METHOD, ElementType.FIELD })\r\n@Retention(RetentionPolicy.RUNTIME)\r\npublic @interface Year {\r\n\r\n\tint value();\r\n\r\n\tString message() default \"{Year}\";\r\n\r\n\tClass&lt;?&gt;[] groups() default {};\r\n\r\n\tClass&lt;? extends Payload&gt;[] payload() default {};\r\n\r\n}<\/pre>\n<p>Notice the \u201cvalue()\u201d method. This exposes the \u201cvalue\u201d argument of the annotation which we will use to pass the year that the annotation should validate against. The rest of the code is mostly boilerplate<\/p>\n<p>Now, the constraint validator:<\/p>\n<pre class=\" brush:java\">public class YearConstraintValidator implements ConstraintValidator&lt;Year, Date&gt; {\r\n\r\n\tprivate int annotationYear;\r\n\r\n\t@Override\r\n\tpublic void initialize(Year year) {\r\n\t\tthis.annotationYear = year.value();\r\n\t}\r\n\r\n\t@Override\r\n\tpublic boolean isValid(Date target, ConstraintValidatorContext cxt) {\r\n\t\tif(target == null) {\r\n\t\t\treturn true;\r\n\t\t}\r\n\t\tCalendar c = Calendar.getInstance();\r\n\t\tc.setTime(target);\r\n\t\tint fieldYear = c.get(Calendar.YEAR);\r\n\t\treturn fieldYear == annotationYear;\r\n\t}\r\n\r\n}<\/pre>\n<p>The first thing to notice, is that, this time, we are saving the year passed into the annotation as a member variable of the constraint validator class. This allows us to access the value in our \u201cisValid\u201d method.<\/p>\n<p>The isValid method is pretty straightforward code wrestling with the obnoxious Date\/Calendar API\u2019s to validate that the value of the annotated field matches the year that the validation annotation specified (I may post an example using JodaTime sometime if I get around to it). And now, if we start up our web application, our two validations are in place and ready to be used!<\/p>\n<p><a href=\"http:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2013\/07\/custom-validation-example-e1372733063855.png\"><img decoding=\"async\" src=\"http:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2013\/07\/custom-validation-example-e1372733063855-300x214.png\" alt=\"custom-validation-example-e1372733063855\" width=\"300\" height=\"214\" class=\"aligncenter size-medium wp-image-15233\" srcset=\"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2013\/07\/custom-validation-example-e1372733063855-300x214.png 300w, https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2013\/07\/custom-validation-example-e1372733063855.png 762w\" sizes=\"(max-width: 300px) 100vw, 300px\" \/><\/a><\/p>\n<p>That\u2019s all. Did I miss anything? Have questions? Let me know in the comments.<\/p>\n<p><strong>Full Source:<\/strong>\u00a0<a title=\"Full Source\" href=\"https:\/\/github.com\/stevehanson\/spring-mvc-validation\/archive\/master.zip\" target=\"_blank\">ZIP<\/a>,\u00a0<a title=\"GitHub Repo\" href=\"https:\/\/github.com\/stevehanson\/spring-mvc-validation\" target=\"_blank\">GitHub<\/a><br \/>\nTo run the code from this tutorial: Must have\u00a0<a title=\"How to install Gradle\" href=\"http:\/\/codetutr.com\/2013\/03\/23\/how-to-install-gradle\/\">Gradle installed<\/a>. Clone the GitHub repo or download the ZIP and extract. Open command prompt to code location. Run gradle jettyRunWar. Navigate in browser to http:\/\/localhost:8080.<br \/>\n&nbsp;<\/p>\n<div style=\"border: 1px solid #D8D8D8; background: #FAFAFA; width: 100%; padding-left: 5px;\"><b><i>Reference: <\/i><\/b><a href=\"http:\/\/codetutr.com\/2013\/05\/29\/custom-spring-mvc-validation-annotations\/\">Spring MVC Custom Validation Annotations<\/a> from our <a href=\"http:\/\/www.javacodegeeks.com\/jcg\">JCG partner<\/a> Steve Hanson at the <a href=\"http:\/\/codetutr.com\/\">CodeTutr<\/a> blog.<\/div>\n","protected":false},"excerpt":{"rendered":"<p>Last tutorial, I showed how to validate a form using annotations. This works great for simple validations, but eventually, you\u2019ll need to validate some custom rules that aren\u2019t available in the out-of-the-box annotations. For example, what if you need to validate that a user is over 21 years old, calculated based off their input birthdate, &hellip;<\/p>\n","protected":false},"author":409,"featured_media":240,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[8],"tags":[30,150],"class_list":["post-15198","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-enterprise-java","tag-spring","tag-spring-mvc"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.5 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Spring MVC Custom Validation Annotations<\/title>\n<meta name=\"description\" content=\"Last tutorial, I showed how to validate a form using annotations. This works great for simple validations, but eventually, you\u2019ll need to validate some\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.javacodegeeks.com\/2013\/07\/spring-mvc-custom-validation-annotations.html\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Spring MVC Custom Validation Annotations\" \/>\n<meta property=\"og:description\" content=\"Last tutorial, I showed how to validate a form using annotations. This works great for simple validations, but eventually, you\u2019ll need to validate some\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.javacodegeeks.com\/2013\/07\/spring-mvc-custom-validation-annotations.html\" \/>\n<meta property=\"og:site_name\" content=\"Java Code Geeks\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/javacodegeeks\" \/>\n<meta property=\"article:published_time\" content=\"2013-07-07T22:00:05+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/spring-logo.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"150\" \/>\n\t<meta property=\"og:image:height\" content=\"150\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"author\" content=\"Steve Hanson\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@javacodegeeks\" \/>\n<meta name=\"twitter:site\" content=\"@javacodegeeks\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Steve Hanson\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"5 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2013\\\/07\\\/spring-mvc-custom-validation-annotations.html#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2013\\\/07\\\/spring-mvc-custom-validation-annotations.html\"},\"author\":{\"name\":\"Steve Hanson\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#\\\/schema\\\/person\\\/006867093496e3253c65f37b3fbec162\"},\"headline\":\"Spring MVC Custom Validation Annotations\",\"datePublished\":\"2013-07-07T22:00:05+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2013\\\/07\\\/spring-mvc-custom-validation-annotations.html\"},\"wordCount\":766,\"commentCount\":2,\"publisher\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#organization\"},\"image\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2013\\\/07\\\/spring-mvc-custom-validation-annotations.html#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2012\\\/10\\\/spring-logo.jpg\",\"keywords\":[\"Spring\",\"Spring MVC\"],\"articleSection\":[\"Enterprise Java\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/www.javacodegeeks.com\\\/2013\\\/07\\\/spring-mvc-custom-validation-annotations.html#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2013\\\/07\\\/spring-mvc-custom-validation-annotations.html\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2013\\\/07\\\/spring-mvc-custom-validation-annotations.html\",\"name\":\"Spring MVC Custom Validation Annotations\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2013\\\/07\\\/spring-mvc-custom-validation-annotations.html#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2013\\\/07\\\/spring-mvc-custom-validation-annotations.html#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2012\\\/10\\\/spring-logo.jpg\",\"datePublished\":\"2013-07-07T22:00:05+00:00\",\"description\":\"Last tutorial, I showed how to validate a form using annotations. This works great for simple validations, but eventually, you\u2019ll need to validate some\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2013\\\/07\\\/spring-mvc-custom-validation-annotations.html#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/www.javacodegeeks.com\\\/2013\\\/07\\\/spring-mvc-custom-validation-annotations.html\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2013\\\/07\\\/spring-mvc-custom-validation-annotations.html#primaryimage\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2012\\\/10\\\/spring-logo.jpg\",\"contentUrl\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2012\\\/10\\\/spring-logo.jpg\",\"width\":150,\"height\":150,\"caption\":\"spring-interview-questions-answers\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2013\\\/07\\\/spring-mvc-custom-validation-annotations.html#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/www.javacodegeeks.com\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Java\",\"item\":\"https:\\\/\\\/www.javacodegeeks.com\\\/category\\\/java\"},{\"@type\":\"ListItem\",\"position\":3,\"name\":\"Enterprise Java\",\"item\":\"https:\\\/\\\/www.javacodegeeks.com\\\/category\\\/java\\\/enterprise-java\"},{\"@type\":\"ListItem\",\"position\":4,\"name\":\"Spring MVC Custom Validation Annotations\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#website\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/\",\"name\":\"Java Code Geeks\",\"description\":\"Java Developers Resource Center\",\"publisher\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#organization\"},\"alternateName\":\"JCG\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/www.javacodegeeks.com\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#organization\",\"name\":\"Exelixis Media P.C.\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#\\\/schema\\\/logo\\\/image\\\/\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2022\\\/06\\\/exelixis-logo.png\",\"contentUrl\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2022\\\/06\\\/exelixis-logo.png\",\"width\":864,\"height\":246,\"caption\":\"Exelixis Media P.C.\"},\"image\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#\\\/schema\\\/logo\\\/image\\\/\"},\"sameAs\":[\"https:\\\/\\\/www.facebook.com\\\/javacodegeeks\",\"https:\\\/\\\/x.com\\\/javacodegeeks\"]},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#\\\/schema\\\/person\\\/006867093496e3253c65f37b3fbec162\",\"name\":\"Steve Hanson\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/5f329aad08233a668ee56ee53f005a94376612b242454cfefaf060b5d6474de0?s=96&d=mm&r=g\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/5f329aad08233a668ee56ee53f005a94376612b242454cfefaf060b5d6474de0?s=96&d=mm&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/5f329aad08233a668ee56ee53f005a94376612b242454cfefaf060b5d6474de0?s=96&d=mm&r=g\",\"caption\":\"Steve Hanson\"},\"description\":\"Steve is a software developer interested in web development and new technologies. He currently works as a Java consultant at Credera in Dallas, TX.\",\"sameAs\":[\"http:\\\/\\\/codetutr.com\\\/\"],\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/author\\\/steve-hanson\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Spring MVC Custom Validation Annotations","description":"Last tutorial, I showed how to validate a form using annotations. This works great for simple validations, but eventually, you\u2019ll need to validate some","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.javacodegeeks.com\/2013\/07\/spring-mvc-custom-validation-annotations.html","og_locale":"en_US","og_type":"article","og_title":"Spring MVC Custom Validation Annotations","og_description":"Last tutorial, I showed how to validate a form using annotations. This works great for simple validations, but eventually, you\u2019ll need to validate some","og_url":"https:\/\/www.javacodegeeks.com\/2013\/07\/spring-mvc-custom-validation-annotations.html","og_site_name":"Java Code Geeks","article_publisher":"https:\/\/www.facebook.com\/javacodegeeks","article_published_time":"2013-07-07T22:00:05+00:00","og_image":[{"width":150,"height":150,"url":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/spring-logo.jpg","type":"image\/jpeg"}],"author":"Steve Hanson","twitter_card":"summary_large_image","twitter_creator":"@javacodegeeks","twitter_site":"@javacodegeeks","twitter_misc":{"Written by":"Steve Hanson","Est. reading time":"5 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.javacodegeeks.com\/2013\/07\/spring-mvc-custom-validation-annotations.html#article","isPartOf":{"@id":"https:\/\/www.javacodegeeks.com\/2013\/07\/spring-mvc-custom-validation-annotations.html"},"author":{"name":"Steve Hanson","@id":"https:\/\/www.javacodegeeks.com\/#\/schema\/person\/006867093496e3253c65f37b3fbec162"},"headline":"Spring MVC Custom Validation Annotations","datePublished":"2013-07-07T22:00:05+00:00","mainEntityOfPage":{"@id":"https:\/\/www.javacodegeeks.com\/2013\/07\/spring-mvc-custom-validation-annotations.html"},"wordCount":766,"commentCount":2,"publisher":{"@id":"https:\/\/www.javacodegeeks.com\/#organization"},"image":{"@id":"https:\/\/www.javacodegeeks.com\/2013\/07\/spring-mvc-custom-validation-annotations.html#primaryimage"},"thumbnailUrl":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/spring-logo.jpg","keywords":["Spring","Spring MVC"],"articleSection":["Enterprise Java"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.javacodegeeks.com\/2013\/07\/spring-mvc-custom-validation-annotations.html#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.javacodegeeks.com\/2013\/07\/spring-mvc-custom-validation-annotations.html","url":"https:\/\/www.javacodegeeks.com\/2013\/07\/spring-mvc-custom-validation-annotations.html","name":"Spring MVC Custom Validation Annotations","isPartOf":{"@id":"https:\/\/www.javacodegeeks.com\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.javacodegeeks.com\/2013\/07\/spring-mvc-custom-validation-annotations.html#primaryimage"},"image":{"@id":"https:\/\/www.javacodegeeks.com\/2013\/07\/spring-mvc-custom-validation-annotations.html#primaryimage"},"thumbnailUrl":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/spring-logo.jpg","datePublished":"2013-07-07T22:00:05+00:00","description":"Last tutorial, I showed how to validate a form using annotations. This works great for simple validations, but eventually, you\u2019ll need to validate some","breadcrumb":{"@id":"https:\/\/www.javacodegeeks.com\/2013\/07\/spring-mvc-custom-validation-annotations.html#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.javacodegeeks.com\/2013\/07\/spring-mvc-custom-validation-annotations.html"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.javacodegeeks.com\/2013\/07\/spring-mvc-custom-validation-annotations.html#primaryimage","url":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/spring-logo.jpg","contentUrl":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/spring-logo.jpg","width":150,"height":150,"caption":"spring-interview-questions-answers"},{"@type":"BreadcrumbList","@id":"https:\/\/www.javacodegeeks.com\/2013\/07\/spring-mvc-custom-validation-annotations.html#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.javacodegeeks.com\/"},{"@type":"ListItem","position":2,"name":"Java","item":"https:\/\/www.javacodegeeks.com\/category\/java"},{"@type":"ListItem","position":3,"name":"Enterprise Java","item":"https:\/\/www.javacodegeeks.com\/category\/java\/enterprise-java"},{"@type":"ListItem","position":4,"name":"Spring MVC Custom Validation Annotations"}]},{"@type":"WebSite","@id":"https:\/\/www.javacodegeeks.com\/#website","url":"https:\/\/www.javacodegeeks.com\/","name":"Java Code Geeks","description":"Java Developers Resource Center","publisher":{"@id":"https:\/\/www.javacodegeeks.com\/#organization"},"alternateName":"JCG","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.javacodegeeks.com\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/www.javacodegeeks.com\/#organization","name":"Exelixis Media P.C.","url":"https:\/\/www.javacodegeeks.com\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.javacodegeeks.com\/#\/schema\/logo\/image\/","url":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2022\/06\/exelixis-logo.png","contentUrl":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2022\/06\/exelixis-logo.png","width":864,"height":246,"caption":"Exelixis Media P.C."},"image":{"@id":"https:\/\/www.javacodegeeks.com\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/www.facebook.com\/javacodegeeks","https:\/\/x.com\/javacodegeeks"]},{"@type":"Person","@id":"https:\/\/www.javacodegeeks.com\/#\/schema\/person\/006867093496e3253c65f37b3fbec162","name":"Steve Hanson","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/secure.gravatar.com\/avatar\/5f329aad08233a668ee56ee53f005a94376612b242454cfefaf060b5d6474de0?s=96&d=mm&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/5f329aad08233a668ee56ee53f005a94376612b242454cfefaf060b5d6474de0?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/5f329aad08233a668ee56ee53f005a94376612b242454cfefaf060b5d6474de0?s=96&d=mm&r=g","caption":"Steve Hanson"},"description":"Steve is a software developer interested in web development and new technologies. He currently works as a Java consultant at Credera in Dallas, TX.","sameAs":["http:\/\/codetutr.com\/"],"url":"https:\/\/www.javacodegeeks.com\/author\/steve-hanson"}]}},"_links":{"self":[{"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/posts\/15198","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/users\/409"}],"replies":[{"embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/comments?post=15198"}],"version-history":[{"count":0,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/posts\/15198\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/media\/240"}],"wp:attachment":[{"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/media?parent=15198"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/categories?post=15198"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/tags?post=15198"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}