JSR 303 - javax.validation - Validate a date - java

I have a Java EE application and I want to validate a Date.
With a String I do this:
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
...
#NotNull
#Size(min = 1, max = 255)
private String myString;
But now I have two dates which I want to validate. The user can in the frontend system write a String in a text field which will be transferred via JSON (I have to use text field, I can not use a datepicker).
So my backend does have this in my domain class:
#DateTimeFormat(pattern = "dd.MM.yy")
#Temporal(value=TemporalType.TIMESTAMP)
private Date myStartDate;
#DateTimeFormat(pattern = "dd.MM.yy")
#Temporal(value=TemporalType.TIMESTAMP)
private Date myEndDate;
I want to validate against the format "dd.MM.yyyy". How can this be done?
And, I do not think so, but is there an automatic validation to check if the start date is before the end date? I only found #Future and #Past.
So the only solution is to use a #Pattern, a regular expression?!
Thank you in advance for your help, Best Regards.

#DateTimeFormat is used during web data binding, when mapping request parameters onto an object (assuming you have enabled it with <mvc:annotation-driven/> or manually.) It's not generally going to be used when deserializing JSON into an object. How are you reading in your JSON? What are you using to deserialize it? You can't validate a java Date object after the fact for the formatting, you have to check up front before deserialization.
There are no multi-field constraints built in. You'll want to write your own type level constraint if you want to compare two properties on an object.

Related

Swagger-Core Different Descriptions For Same Object Type

I have a project which is using spring-doc for it's generation of swagger so I am using OpenApi 3. The issue I am facing I believe is really coming from swagger-core which should have the functionality I need but I can't quite figure out how to get it to work the way I need.
I have a generic date class which is defined in hand written swagger like the below and reused in multiple places.
DateRange:
type: object
properties:
start:
type: string
description: Date fields are formatted according to the ISO 8601 specification.
format: date
example: '2022-01-01'
end:
type: string
description: Date fields are formatted according to the ISO 8601 specification.
format: date
example: '2022-01-01'
In my Java code it is something like the below. I tried adding the allOf since that is what I would normally use if I am writing the Swagger by hand, but I am unsure if I am actually using it correctly as I am not getting the behavior I want!
#Schema(description = "Some description.", allOf = {DateRange.class})
private DateRange someDateRange;
#Schema(description = "Some other description.", allOf = {DateRange.class})
private DateRange anotherDateRange;
This is how it's rendering which is not at all what I was expecting...
Does any one have any idea how I can fix this?

Taking LocalTime input in jsp

I am working on a spring boot and hibernate project
One of my entity class has a localDate and localTime both for different purposes
public class User{
private LocalTime dailyStartTime;
private LocalDate UniversityStartDate;
//There are other fields here as well
}
My jsp form looks like this
<frm:form modelAttribute="user">
<frm: input type="time" path="dailyStartTime">
<frm: input type="date" path="UniversityStartDate">
</frm:form
Using #InitBinder, I am able parse the date and the date gets updated in the user object.
but I am not able to parse the time getting error as typeMismatch (Failed to convert property value of String to LocalTime)
There just was a similar question here JpaRepository SQL syntax error when trying to save to MySQL Date.
For the form binding you probably need to add #DateTimeFormat(pattern = "yyyy-MM-dd") and #DateTimeFormat(pattern = "HH-mm"). However it's good practice to separate the data object from the actual entities, otherwise you may get problems persisting with the new attributes.

Date format time on Spring Doc swagger API

I'm trying to generate the documentation from my springboot application using spring doc , this is some of the attributes of the class which is causing me issues:
public class user {
#JsonFormat(pattern = "yyyy-MM-dd")
private Date dateOfBirth;
}
With the Spring doc annotation, in the swagger i got this:
dateOfBirth* string($date-time)
"dateOfBirth": "2020-04-29T14:15:32.475Z"
while i would like to have this:
dateOfBirth* string($date)
"dateOfBirth": "2020-04-29"
How to do that? I think to be close to solution but i can't firugre out what i'm missing
I think the answer you are looking for is here: swagger date field vs date-time field
Date is an object DateTime for swagger, as it is really a DateTime object. Use the appropriate type, like LocalDate, they know how to handle that.
By the way, how would you expect Swagger to properly convert a Date Pattern into the appropriate type ? It's like too much magic. Swagger relies on thing that are common practices.
The JSONFormat won't change how swagger interpret your data.

Serialized data for requesting a Date value are different for JSON and XML

I have a Jersey Rest service that leverages the Jackson annotations to perform the serialization/deserialization for my service
but when jersey/jackson serializes my object with the below field i get two different values for the result for XML vs JSON requests
#JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd")
private Date startDate;
Results
JSON: "startDate": "2016-02-01"
XML: <startDate>2016-02-01T00:00:00-05:00</startDate>
the json is showing correctly, but the XML results give all sorts of stuff I dont want at the end.
I've tried using other suggestions like
JsonSerializer<T> and JsonDeserializer<T>
but it gives me the same incorrect results
Am I missing an annotation to specifically handle XML?

json date format in spring-boot

I am using spring-boot and I have an entity class defined something like this
import org.joda.time.LocalDateTime;
#Entity
public class Project {
#Type(type = "org.jadira.usertype.dateandtime.joda.PersistentLocalDateTime")
private LocalDateTime start_date;
...
...
}
When this class is converted to JSON, the field gets converted to the following string representation
{"start_date":[2014,11,15,0,0,0,0],...., ...}
I want to have the json response as yyyy-MM-dd.
I tried the #DateTimeFormat(iso = ISO.DATE) annotation and that did not help either.
Is there an easy way to do this conversion to proper json format ?
There are three things that you need to do to format the date as yyyy-MM-dd:
Add a dependency on com.fasterxml.jackson.datatype:jackson-datatype-joda. Judging by the output you're getting at the moment, I think you may already have this dependency.
Configure Jackson not to format dates as timestamps by adding spring.jackson.serialization.write-dates-as-timestamps: false to your application.properties file.
Annotate the LocalDataTime field or getter method with #JsonFormat(pattern="yyyy-MM-dd")
Note: You'll need to use Spring Boot 1.2 for step 2 to work.
Without additional dependency - the only thing I had to do is:
To take care send date from client as string object, in format yyyy/MM/dd
In Spring Boot application, to add annotation on the date field with
the same format
public class Foo
{
#JsonFormat(pattern = "yyyy/MM/dd")
private Date dueDate;
}
Using Spring Boot 2.3.5 version
Update
Another option, instead of step 2, to modify application.properties file, add there the format for any Date object:
spring.jackson.date-format=yyyy/MM/dd
You can use #JsonFormat annotation in and the desired pattern like this without using any dependency :
#JsonFormat(pattern="yyyy-MM-dd")
private Date created_At;
Took me some time struggling with Spring Boot Application + Date Format for my input so I'll try to resume what I saw.
If your date is argument to a function, you can use #DateTimeFormat(pattern = "yyyy-MM-dd") to define a pattern (ie. org.springframework.format.annotation.DateTimeFormat).
If your date is inside an object argument to the function, you can use #JsonFormat(pattern = "yyyy-MM-dd") to define a pattern (ie. com.fasterxml.jackson.annotation.JsonFormat)
If neither of these works, you can try changing your date Type, for me I had tu use org.joda.time.LocalDate in order to make it work with option 2 :
#JsonFormat(pattern = "dd/MM/yyyy")
private org.joda.time.LocalDate date;

Categories

Resources