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.
Related
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?
In Swagger model / Example value, I see this sample value for a $date-time field.
"lastModifiedDate": "2020-07-09T12:50:48.461Z"
But I have defined this field like this
#JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss.SSSXXX", timezone="America/New_York")
private Date lastModifiedDate;
So the actual values returned by my API look like this:
"lastModifiedDate": "2020-07-09T07:44:35.366-04:00"
So I am not sure why swagger is not detecting this.
Probably because this JsonFormat is a Jackson annotation.
com.fasterxml.jackson.annotation.JsonFormat
So... do I need to add some additional Swagger annotation here?
I don't have a Swagger descriptor file (or don't have control over it),
I have just annotations in the Java code.
Can this be done via annotations?
I think that the annotation required for documenting your moddel is #ApiModelProperty, take a look on it http://docs.swagger.io/swagger-core/current/apidocs/io/swagger/annotations/ApiModel.html
hope it will be helpfull.
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;
I am using JDK 1.6 , Jackson 2.0.5 , Spring 3.0.3 and using jackson annotations to serialize and deserialize json response.
public class MyDate extends java.sql.Date{
private static SimpleDateFormat simpleDateFormat = new SimpleDateFormat("MM/dd/yyyy");
private String dateString;
#JsonCreator
public MyDate(#JsonProperty("dateString") String date){
super(simpleDateFormat.parse(date).getTime());
dateString = date;
}
public String getDateString(){
return dateString;
}
private final setDateString(String date){
// .....
}
}
I am getting json response message like 1417977000000 , but it should be like 12/08/2014.
Do I need to write anything else also ?
I tried to follow Jackson wiki page article.
EDIT:
On basis of discussion with #Sotirios Delimanolis I tried JsonValue annotation on getter method and it worked.
#JsonValue
public String getDateString(){
return dateString;
}
Your type is a java.sql.Date which is a java.util.Date which is considered special for Jackson. By default, it writes dates (instances of type java.util.Date) as their timestamps. You can disable this with
objectMapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
or the corresponding configuration for your version of Jackson.
This, however, will give you something like
"2014-12-08T08:00:00.000+0000"
It will not use your SimpleDateFormat. You can register a DateFormat with the ObjectMapper like so
objectMapper.setDateFormat(new SimpleDateFormat("MM/dd/yyyy"));
The best solution would be to use composition over inheritance. Do not extend java.util.Date directly or indirectly.
If you don't want to use a general solution, you can always set format per property
public class DateStuff {
#JsonFormat(shape=JsonFormat.Shape.STRING, pattern="yyyy-MM-dd,HH:00", timezone="CET")
public Date creationTime;
}
For more information please read here: http://wiki.fasterxml.com/JacksonFAQDateHandling
Edit:
As a side note
(aka "Please do NOT use java.sql.Date, ever!")
Although Jackson supports java.sql.Date, there are known issues with
respect to timezone handling, partly due to design of this class. It
is recommended that this type is avoided, if possible, and regular
java.util.Date (or java.util.Calendar) used instead. If this is not
possible, it may be necessary for applications to convert these dates
using java.util.Calendar and explicit timezone definition.
I just added a jQuery date picker to my simple page made in jsp. Using Spring mvc 4.0.0. I would like to have java.util.Date field in my model class and let spring to convert the date String coming from the front end to date. My issue is that, if i have
#DateTimeFormat(pattern = "dd/MM/yy")
private Date startDate;
In my model class I receive null value in my spring controller. (The startDate setter is not called neither) If i change the startDate to be a simple String, than the value is populated correctly and in the controller i am able to retrieve the startDate string. Could you please advice what am I missing?
Was trying to follow the http://gerrydevstory.com/2013/05/21/binding-date-form-input-on-spring-mvc/ seems that no other tricks has been used to convert the String to Date.
Try this:
#DateTimeFormat(pattern=dd/MM/YY)
private Date startDate;
Maybe it's not working with Date, have you tried using DateTime instead?
I think you shoule put #DateTimeFormat under the #RequestMapping, like below:
#RequestMapping
public String someMethod(#RequestParam(value="date", required=false)#DateTimeFormat(pattern="dd/MM/YY") Date date)