<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Validation &#8211; Pauls Blog</title>
	<atom:link href="https://sterl.org/tag/validation/feed/" rel="self" type="application/rss+xml" />
	<link>https://sterl.org</link>
	<description></description>
	<lastBuildDate>Fri, 15 Feb 2019 11:48:56 +0000</lastBuildDate>
	<language>de</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.8.3</generator>
	<item>
		<title>JSR 303 Validation for Dates</title>
		<link>https://sterl.org/2015/06/java-jsr-validation-for-dates/</link>
					<comments>https://sterl.org/2015/06/java-jsr-validation-for-dates/#comments</comments>
		
		<dc:creator><![CDATA[Paul Sterl]]></dc:creator>
		<pubDate>Thu, 11 Jun 2015 20:17:55 +0000</pubDate>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[JSR Validation]]></category>
		<category><![CDATA[JSR]]></category>
		<category><![CDATA[JSR 303]]></category>
		<category><![CDATA[Validation]]></category>
		<guid isPermaLink="false">http://sterl.org/?p=21</guid>

					<description><![CDATA[A common case is to validate date inputs in Java e.g. to avoid the nice and friendly typos like 06/01/1500. Nevertheless by default where is not to much support to handle this very common case. So let&#8217;s fix this together: Annotation first The first we need is a JSR annotation which we use to annotate&#8230;]]></description>
										<content:encoded><![CDATA[<p>A common case is to validate date inputs in Java e.g. to avoid the nice and friendly typos like <strong>06/01/1500</strong>.</p>
<p>Nevertheless by default where is not to much support to handle this very common case. So let&#8217;s fix this together:</p>
<h2>Annotation first</h2>
<p>The first we need is a JSR annotation which we use to annotate the code. We provide from the start proper default values, to avoid none sense data.</p>
<pre title="InDateRange Annotation" class="lang:java decode:true">import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import javax.validation.Constraint;
import javax.validation.Payload;

@Documented
// Note: We use here already a validator which we will add in a sec too
@Constraint(validatedBy = InDateRangeValidator.class)
@Target({ElementType.METHOD, ElementType.FIELD, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface InDateRange {
    // used to get later in the resource bundle the i18n text
    String message() default "{validation.date.InDateRange.message}";
    Class&lt;?&gt;[] groups() default {};
    Class&lt;? extends Payload&gt;[] payload() default {};
    // min value, we for now just a string
    String min() default "1900-01-01";
    // max date value we support
    String max() default "2999-12-31";
}</pre>
<h2>Validator next</h2>
<p>As we have the annotation now, we still need to add some code behind for the JSR bean validation to make it really do something. I assume that both classes are in the same package.</p>
<pre title="Validator Class" class="lang:java decode:true ">import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;

public class InDateRangeValidator implements ConstraintValidator&lt;InDateRange, java.util.Date&gt; {
    
    private final SimpleDateFormat dateParser = new SimpleDateFormat("yyyy-MM-dd");
    
    private InDateRange constraintAnnotation;
    
    @Override
    public void initialize(InDateRange constraintAnnotation) {
        this.constraintAnnotation = constraintAnnotation;
    }
    
    @Override
    public boolean isValid(java.util.Date value, ConstraintValidatorContext context) {
        try {
            final Date min = dateParser.parse(constraintAnnotation.min());
            final Date max = dateParser.parse(constraintAnnotation.max());
            return value == null ||
                    (value.after(min) &amp;&amp; value.before(max));
        } catch (ParseException ex) {
            throw new RuntimeException(ex);
        }
    }
}</pre>
<p>The validator is not very smart now, but it will do the job for. Let&#8217;s use it first, will we?</p>
<div class="bs-callout bs-callout-info"><strong>Note:</strong> This tutorial is a bit old, use nowadays the DateTimeFormatter from the Java time.</div>
<h2>Apply our date validation</h2>
<pre title="Use our Date validation Annotation" class="lang:java decode:true">class SomeBean {
    @InDateRange
    private Date date;
}</pre>
<p>Well not to surprising but the interesting part is of course always the test case we should add to verify all is good and working as we like it.</p>
<pre title="Junit Test for Date Validator" class="lang:java decode:true">import java.util.Date;
import java.util.Set;
import org.junit.Test;
import static org.junit.Assert.*;
import org.junit.BeforeClass;
import javax.validation.ConstraintViolation;
import javax.validation.Validation;
import javax.validation.Validator;
import javax.validation.ValidatorFactory;
import org.joda.time.LocalDate;

public class TestInDateRange {

    private static Validator validator;
    
    @BeforeClass
    public static void setUp() {
        ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
        validator = factory.getValidator();
    }
    
    @Test
    public void testDateRange() {
        SomeBean test = new SomeBean();
        test.date = new LocalDate(10001, 01, 01).toDate();
        
        Set&lt;ConstraintViolation&lt;TestClass&gt;&gt; validate = validator.validate(test);
        System.out.println(validate);
        assertEquals(1, validate.size());
        assertEquals("date", validate.iterator().next().getPropertyPath().toString());
    }
}</pre>
<h2>i18n File</h2>
<p>Assuming you use a default maven project we should add in <code>/src/main/resources</code> the file <code>ValidationMessages.properties</code> if it not already exists:</p>
<pre class="lang:default decode:true">validation.date.InDateRange.message=date must be between {min} and {max}.</pre>
<div class="bs-callout bs-callout-info"><strong>Note:</strong> You can use placeholders in the messages string. Here we use <code>min</code> and <code>max</code>, which automatically add the values from our annotation into the user message.</div>
<h2>Going further</h2>
<ul>
<li>Well as you noticed right now we parse the min and max date each time. We could of course just do this once as it is quite static</li>
<li>We use currently <code>java.util.Date</code> well again something we could change</li>
<li>Last but not least we should try to avoid <code>Date</code> in the API / Model objects and try to just use simply UTC <code>Long</code>s</li>
</ul>
]]></content:encoded>
					
					<wfw:commentRss>https://sterl.org/2015/06/java-jsr-validation-for-dates/feed/</wfw:commentRss>
			<slash:comments>2</slash:comments>
		
		
			</item>
	</channel>
</rss>
