Thymeleaf rejects null date - html

I have this html code:
<input class="form-control col-sm-8" type="date" th:field="*{completiondate}">
and this model :
import java.math.BigDecimal;
import java.sql.Date;
import java.sql.Timestamp;
public class EventReport {
private Long id;
private Date creationdate;
private String status;
private Date completiondate;
...
}
completion date is not a required value and can be null sometimes. When user submits the post form I take the following
Field error in object 'treeTrimsEventReport' on field
'completiondate': rejected value [];
Obviously I don't have errors when I select a value for date and the app works fine.
How can I give null on completion date without errors?

I think it is a binding error.
You need to tell spring how to convert form data which comes as text (String) to the type in your model (here a Date).
You may do it with this annotation on the field in EventReport :
import org.springframework.format.annotation.DateTimeFormat
...
#DateTimeFormat(pattern = "yyyy-MM-dd")
private Date completiondate;
(change the pattern to match the one you wish to show to the user)
Spring gives you other option to tell it how to bind data.
Have a look at the reference manual, in this chapter for all options :
https://docs.spring.io/spring/docs/current/spring-framework-reference/web.html#mvc-ann-initbinder

Related

LocalDateTime of type format problem in thymeleaf

I'm studying JavaWeb now,but not enough experience to solve the problem.
I use MySql 8.0+, "mysql-connector-java" version by maven impot is 8.0.12,JDBC connect MySql Driver use "com.mysql.cj.jdbc.Driver";DataBase table date time field type is " datetime",the field can be read successful by invoked set in JavaBean attribute "orderDate",then let attribute "orderDate" through 'HttpSession session' to set in session.
When JavaBean attribute type is " java.sql.Timestamp ", from session read variable values,the thymeleaf format work is fine;
There is the source code:
<td th:text="${#dates.format(orderBean.getOrderDate(),'yyyy-MM-dd HH:mm:ss')}"></td>
But when JavaBean attribute type is " java.time.LocalDateTime ",the "orderBean.java" part source code:
public class OrderBean {
....
private LocalDateTime orderDate;
.....
public LocalDateTime getOrderDate() {
return orderDate;
}
public void setOrderDate(LocalDateTime orderDate) {
this.orderDate = orderDate;
}
}
There is a method to set orderBean to HttpSeesion part source code:
public String checkout(HttpSession session){
........
OrderBean orderBean = new OrderBean();
LocalDateTime localDateTime = LocalDateTime.now();
orderBean.setOrderDate(localDateTime);
session.setAttribute("orderBean",orderBean);
........
return "cart/cart";
}
There is the cart.html source code:
<td th:text="${#temporals.format(orderBean.getOrderDate(),'yyyy-MM-dd HH:mm:ss')}"></td>
from session read variable values,the thymeleaf format not in effect,throw the erro:
org.thymeleaf.exceptions.TemplateProcessingException: Exception evaluating OGNL expression: "#temporals.format(orderBean.getOrderDate(),'yyyy-MM-dd HH:mm:ss')" (template: "order/order" - line 48, col 19)
at org.thymeleaf.standard.expression.OGNLVariableExpressionEvaluator.evaluate(OGNLVariableExpressionEvaluator.java:191)
at org.thymeleaf.standard.expression.OGNLVariableExpressionEvaluator.evaluate(OGNLVariableExpressionEvaluator.java:95)
at org.thymeleaf.standard.expression.VariableExpression.executeVariableExpression(VariableExpression.java:166)
at org.thymeleaf.standard.expression.SimpleExpression.executeSimple(SimpleExpression.java:66)
at org.thymeleaf.standard.expression.Expression.execute(Expression.java:109)
at org.thymeleaf.standard.expression.Expression.execute(Expression.java:138)
at org.thymeleaf.standard.processor.AbstractStandardExpressionAttributeTagProcessor.doProcess(AbstractStandardExpressionAttributeTagProcessor.java:144)
at org.thymeleaf.processor.element.AbstractAttributeTagProcessor.doProcess(AbstractAttributeTagProcessor.java:74)
at org.thymeleaf.processor.element.AbstractElementTagProcessor.process(AbstractElementTagProcessor.java:95)
at org.thymeleaf.util.ProcessorConfigurationUtils$ElementTagProcessorWrapper.process(ProcessorConfigurationUtils.java:633)
at org.thymeleaf.engine.ProcessorTemplateHandler.handleOpenElement(ProcessorTemplateHandler.java:1314)
at org.thymeleaf.engine.OpenElementTag.beHandled(OpenElementTag.java:205)
at org.thymeleaf.engine.Model.process(Model.java:282)
at org.thymeleaf.engine.Model.process(Model.java:290)
at org.thymeleaf.engine.IteratedGatheringModelProcessable.processIterationModel(IteratedGatheringModelProcessable.java:367)
at org.thymeleaf.engine.IteratedGatheringModelProcessable.process(IteratedGatheringModelProcessable.java:221)
at org.thymeleaf.engine.ProcessorTemplateHandler.handleCloseElement(ProcessorTemplateHandler.java:1640)
at org.thymeleaf.engine.CloseElementTag.beHandled(CloseElementTag.java:139)
at org.thymeleaf.engine.TemplateModel.process(TemplateModel.java:136)
I try to solve it ,but i search in google,they write code like the same that.But the different is that they use SpringMVC, through "model.setAttribute()" method ,
model.addAttribute("localDate", LocalDate.now());
then through thymeleaf expression:
<p th:text="${#temporals.format(localDateTime, 'dd-MM-yyyy HH:mm')}"></p>
In addition,i also import dependency in maven artifactId "thymeleaf-extras-java8time ";
I just use javax-Servlet-api ,without spring,springMVC stc...,I'm devastated that I don't know how to solve it.
I hope someone can help me....

Reading data using Spring data jpa automatically converting timestamp to current timezone

I have a table User with columns
user_id, first_name,last_name, created_time(timestamp)
I have a class User Entity
#Getter
#Setter
#Table(name="user")
#Entity
public class User {
#Id
private Long userId;
#Column(name="first_name")
private String firstName;
#Column(name="last_name")
private String lastName;
#Column(name="created_time")
private Timestamp createdTime;
}
I have an interface User Repository
public interface UserRepository extends CRUDRepository<User,Long> {
User findByUserId(Long id);
}
The created_time stored in database table is 2020-09-08 15:38:13 and when i read the object using spring data jpa it returned as "2020-09-08 21:08:13"
How should i ensure that this automatic time zone conversion not to happen?
The root cause of the problem is that Jackson automatically converts the timestamp values to UTC and then serializes the same.
In order to correct this behavior, you can add following property to your application.properties and specify the same timezone value as is being used by your DB server.
spring.jackson.time-zone=Asia/Kolkata
There is an article that explains this problem and also proposes solutions.
You can also have a look at this answer.

Format DateTime object in Model as NotMapped Property

I have a model called Report having bellow two properties. I am going to retrieve the data and send it to jQuery datatable. I need to format the date field before sending it to view, I did it as bellow:
public class Report
{
public int Id {get; set;}
public DateTime ActivityDate { get; set; }
//Here is the date formation property
public string FormattedDate => ActivityDate.ToString();
}
Here is the action method which is being called by jQuery datatable:
[JQDataTable]
public ActionResult Search()
{
IQueryable<Report> data = db.Reports;
return View("Index",data);
}
The problem is, I can not get the formatted date, instead I am getting an error of:
The specified type member 'FormattedDate' is not supported in LINQ to Entities. Only initializers, entity members, and entity navigation properties are supported.
I tried and search alot but was unable to find a solution for this. In next step I want to convert this date to PersianCalendar object and return its string.
I have faced similar problems using ToString inside Linq query. For your case I think it would be easier to handle the conversion of datetime in time of view and leave the datetime variable as is. Rather accept specific format for the search action, parse the received date and do the query.
After suffering for a very long time, I now tend to accept datetime from view as string with my explicitly specified format ("yyyy-mm-dd" just my personal choice :P ) and use DateTime.TryParseExact() handling the null input as well.
Hope it helps. Happy coding.

SpringBoot, Hibernate and REST - date format in JSON

I have a problem with date format in JSON response generated in REST project (SpringBoot+Hibernate).
When I call function I got JSON like this:
"rezerwacjaDataOd": 1535580000000,
"rezerwacjaDataDo": 1535839200000,
"rezerwacjaGodzOd": "14:00:00",
"rezerwacjaGodzDo": "12:00:00"
my entity:
private Date rezerwacjaDataOd;
private Date rezerwacjaDataDo;
private Time rezerwacjaGodzOd;
private Time rezerwacjaGodzDo;
It's Date from java.sql and Time from java.sql too
My controller:
#RestController
#CrossOrigin
#RequestMapping("api/rezerwacja")
#Api
public class RezerwacjaController {
...
#GetMapping(value = "/getRezerwacjaById")
public #ResponseBody
Rezerwacja getRezerwacjaById(Integer id) {
return rezDao.findOne(id);
}
...
Why Time is in "12:00:00" format, but Date in 1535580000000 format?
How to make Date to be in "yyyy-MM-dd" format?
You should do two things
add spring.jackson.serialization.write-dates-as-timestamps:false in your application.properties this will disable converting dates to timestamps and instead use a ISO-8601 compliant format
You can then customize the format by annotating the getter method of you dateOfBirth property with #JsonFormat(pattern="yyyy-MM-dd")
The differences in the way hibernate persists the date/time objects in the database have to do with the way these objects are used.
Per the documentation Time is a thin wrapper around Date that allows the underlying JPA provider to save the date object using the convention your noticed.
On the other hand, the Date object you pass in is converted directly to a timestamp and gets saved this way.
In both cases you can retrieve the value in question and serialize over to the desired format (with ISO-8601 being the best).
Another solution, other than the one mentioned above, is to create a custom serializer to do this.
A simple implementation would be:
public class Iso8601Serializer extends StdSerializer<Date> {
private static final String ISO_8601_FORMAT = "yyyy-MM-dd'T'HH:mm:ss.SSSZ";
public Iso8601Serializer() {
this(null);
}
public Iso8601Serializer(Class clazz) {
super(clazz);
}
#Override
public void serialize(Date date, JsonGenerator jsonGenerator, SerializerProvider serializerProvider)
throws IOException {
if (date == null) {
jsonGenerator.writeNull();
} else {
jsonGenerator.writeString(DateFormatUtils.format(date, ISO_8601_FORMAT));
}
}
}
Also (and this is a personal thing), I would advise in using plain Date objects to store dates and futhermore, have the respective fields annotated as #Temporal.

Spring mvc error while binding date param

I'm having a weird problem with a Spring MVC.
I have a Controller method that accepts 2 date parameters as request parameters startDate and endDate.
If I use a simple url with the 2 params like so :
http://localhost/myapp/videos?startDate=2013-05-10&endDate=2013-06-01.json
I get this error message :
[#|2013-05-27T17:39:01.711+0200|INFO|glassfish3.1.2|javax.enterprise.system.std.com.sun.enterprise.server.logging|_ThreadID=24;_ThreadName=Thread-2;|38386 [http-thread-pool-8080(5)] DEBUG org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver - Resolving exception from handler [public java.util.List<Video> com.ufasoli.Videos.programs(com.ufasoli.filtering.SearchParams)]: org.springframework.validation.BindException: org.springframework.validation.BeanPropertyBindingResult: 1 errors
Field error in object 'searchParams' on field 'endDate': rejected value [2013-06-01.json]; codes [typeMismatch.searchParams.endDate,typeMismatch.endDate,typeMismatch.java.util.Date,typeMismatch]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [searchParams.endDate,endDate]; arguments []; default message [endDate]]; default message [Failed to convert property value of type 'java.lang.String' to required type 'java.util.Date' for property 'endDate'; nested exception is org.springframework.core.convert.ConversionFailedException: Failed to convert from type java.lang.String to type #org.springframework.format.annotation.DateTimeFormat java.util.Date for value '2013-06-01.json'; nested exception is java.lang.IllegalArgumentException: Invalid format: "2013-06-01.json" is malformed at ".json"]
|#]
But as soon as I remove the .json like so :
http://localhost/myapp/videos?startDate=2013-05-10&endDate=2013-06-01
it all works fine...
This looks like a bug to me as the databinder should not take the url extension into account when binding the data to the controller or is this normal behavior?
Below is the controller method causing the problem :
#RequestMapping(value = "/videos/",
method = RequestMethod.GET,
produces = MediaType.APPLICATION_JSON_VALUE)
public List<Videos> videos( SearchParams searchParams) {
return videosRepository.videos(searchParams);
}
Here is my SearchParams class :
public class SearchParams extends BaseSearchParams implements Serializable{
private static final long serialVersionUID = 1L;
#DateTimeFormat(iso = ISO.DATE, pattern = "yyyy-MM-dd")
private Date startDate;
#DateTimeFormat(iso = ISO.DATE, pattern = "yyyy-MM-dd")
private Date endDate;
//Setters/Getters
}
I'm using Spring MVC 3.2.1.RELEASE
Any insight?
Thanks in advance
I think that the 'url extension' (if any) should be part of the path and belongs therefore before the query: http://localhost/myapp/videos.json?startDate=2013-05-10&endDate=2013-06-01.