Instantiating POJO (LocalDateTime) from YAML Properties File (Java & Spring Boot) - java

I am trying to load custom properties from a YAML properties file upon initialization using Spring Boot. I have found countless tutorials on how to do that, and they work. The problem is that I can't seem to find a way how to instantiate POJOS, such as for example LocalDateTime. My code is as shown below.
#Configuration
#ConfigurationProperties(prefix="default-film-showings")
public class FilmShowings {
private List<FilmShowing> filmShowings;
//Constructors, Getters, setters etc.
public static class FilmShowing {
private Integer id;
private Film film;
private Theatre theatre;
private LocalDateTime dateTime;
//Constructors, Getters, setters etc.
}
}
My YAML file is currently as follows
default-film-showings:
filmShowings:
- id: 1
dateTime: 2018-07-13 21:00:00
My problem is that I get the following error upon initialisation
Failed to convert property value of type 'java.lang.String' to required type 'java.time.LocalDateTime' for property 'filmShowings[0].dateTime';
I also tried this variant
default-film-showings:
filmShowings:
- id: 1
dateTime:
date:
year: 2018
month: 7
day: 13
time:
hour: 21
minute: 0
second: 0
nano: 0
but I got the following error
Error creating bean with name 'filmShowings': Could not bind properties to FilmShowings
Any help? I looked at the following thread JSON Java 8 LocalDateTime format in Spring Boot but it didn't solve my problem.
On a similar note, is there any way to link the Film POJO attribute to another default property?
Say I have the following in my properties file
default-films:
films:
- id: 1
filmName: Spider-Man
can I add something like this too?
default-film-showings:
filmShowings:
- id: 1
film: default-films.films[0]
dateTime: whatever I need to do here to make it work
It is reading default-films.films[0] as string and thus not matching 'the YAML' object.
Any help?

Assuming Spring honors the #DateTimeFormat annotation in a #ConfigurationProperties class (I haven't verified that), you've declared the format to be DateTimeFormat.ISO.DATE_TIME which is 2011-12-03T10:15:30+01:00[Europe/Paris]. Your property file has 2018-07-13 21:00:00 which isn't any of the standard formats. How do you expect it to work?
Your datatype is LocalDateTime which doesn't have a concept of time zone, thus contradicting the ISO_DATE_TIME format. However, the time zone is optional is for ISO_DATE_TIME, so this may not be an issue.
Clearly, you're throwing spaghetti at the wall and hoping something would stick. Write a unit test and try to convert the string to whatever datetime object you want. Once you've done that, come back if you've a problem.

You should just adapt the setter in the configuration class.
if your yaml is:
default-film-showings:
filmShowings:
- id: 1
dateTime: 2018-07-13 21:00:00
then do this in your configuration class:
#Configuration
#ConfigurationProperties(prefix="default-film-showings")
public class FilmShowings {
private List<FilmShowing> filmShowings;
//Constructors, Getters, setters etc.
public static class FilmShowing {
private Integer id;
private Film film;
private Theatre theatre;
private LocalDateTime dateTime;
//Constructors, Getters, setters etc.
public void setDateTime(String dateTime) {
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd
HH:mm:ss");
LocalDateTime formatDateTime = LocalDateTime.parse(dateTime, formatter);
this.dateTime= formatDateTime;
}
}
}

Related

Using application property in Spring Boot annotation?

I have the following date field in my DTO class:
#JsonFormat(pattern="dd.MM.yyyy")
private LocalDateTime date;
I define the date format in my application.yml as shown below:
spring:
jackson:
date-format: "dd.MM.yyyy"
I am trying to use this format in my DTO field directly like below:
#JsonFormat(pattern="${spring.jackson.date-format}")
private LocalDateTime date;
Is it possible? Or do ı have to add a #Value field like below? I tried but cannot use this dateFormat in my date field.
#Value("${spring.jackson.date-format}")
private String dateFormat;
JsonFormat is not a spring annotation, therefore you can't use spring expression language.
spring.jackson.date-format defines default date format for some types of date classes, you don't have to use this variable inside JsonFormat, just define the value. For details see e.g. https://www.baeldung.com/spring-boot-formatting-json-dates
If you would like to be more flexible in spring you can define converters for any type, see the same article.
You have good tips here: https://www.baeldung.com/spring-boot-formatting-json-dates
Either configure the default format, like
spring.jackson.date-format=dd.MM.yyyy
or configure the serializer:
#Configuration
public class MyJsonConfig {
#Value("${spring.jackson.date-format}")
private String dateFormat;
#Bean
public Jackson2ObjectMapperBuilderCustomizer jsonCustomizer() {
return builder -> {
builder.simpleDateFormat(dateTimeFormat);
builder.serializers(new LocalDateSerializer(DateTimeFormatter.ofPattern(dateFormat)));
builder.serializers(new LocalDateTimeSerializer(DateTimeFormatter.ofPattern(dateFormat)));
};
}
}

Disable converting epoch to date on Springboot

I have the following springboot request:
#Data
#ToString
public class OffsetDate {
public OffsetDateTime time;
}
And my request goes:
{
"time" : 20000101
}
Right now, that is being converted to date during serialization: 1970-01-01T05:33:20.101Z - which I don't want to happen.
I need to be able to specify the format and fail if it's invalid without custom annotations (request code is actually autogenerated from swagger yaml, hence I cannot modify the request).
Is there a way to do that?

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.

How do I format a Date as a Timestamp in Springboot 2?

Spring boot 2 has made UTC format the default for dates when serializing objects as json. This broke several of our old integrations that relied on the date being a timestamp. How do I selectively restore this functionality to the responses that need it?
On any dates you need formatted as a timestamp again, in either the constructor or on the field annotate them with #JsonFormat(shape = JsonFormat.Shape.NUMBER) like so:
#JsonFormat(shape = JsonFormat.Shape.Number)
private Date myDate;
or
MyClass(#JsonFormat(shape = JsonFormat.Shape.Number)
Date myDate) {
...
}

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