how to avoid rejected value [] issue in spring form submission - spring

i have two dates in form submission in Spring 3 + Hibernate.
#Column(name = "FinStartDate")
private Date finStartDate;
#Column(name = "FinEndDate")
private Date finEndDate;
I'm display/hide dates on the basis of some criteria. When the dates are hidden and submit the form, the following errors
org.springframework.validation.BindException: org.springframework.validation.BeanPropertyBindingResult: 2 errors
Field error in object 'register' on field 'obj.finEndDate': rejected value []; codes [typeMismatch]
How to avoid the issue.

#JsonDeserialize(using = LocalDateDeserializer.class)
#JsonSerialize(using = LocalDateSerializer.class)
#DateTimeFormat(pattern = "dd.MM.yyyy")
private Date finEndDate;
Maybe, you should use serializer/deserializer.

I think that you miss a formatter to convert the date String to a Date object.
You can try to annotate your field
#DateTimeFormat(pattern = "yyyy-MM-dd")
or to declare a initbinder in your controller like :
#InitBinder
protected void initBinder(WebDataBinder binder) {
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
binder.registerCustomEditor(Date.class, new CustomDateEditor(
dateFormat, false));
}
Or you can declare a formatter in you mvc configuration file that will format every Date object your application is binding to.

Add #DateTimeFormat annotation for following way. If not working update date format. (MM-dd-yyyy, dd-MM-yyyy)
#Column(name = "FinEndDate")
#DateTimeFormat(pattern = "yyyy-MM-dd")
private Date finEndDate;

Related

dealing with exceptions in #JsonFormat pattern

I am using the #JsonFormat annotation from the fasterxml.jackson library:
#JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd")
private Date endDate;
#JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss")
private Date startDateInUtc;
When the date format isn't correct, I don't get an exception, but instead, get the wrong date object (e.g. month 13 becomes January).
Based on my research, I came across two possible solutions:
Playing with the ObjectMapper. (with the setDateFormat function)
Creating my own Json Deserializer class, that will throw an error when the format is not valid:
public class JsonDateDeserializer extends JsonDeserializer<Date> {
public static final String DATE_FORMAT = "yyyy-MM-dd";
#Override
public Date deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException {
SimpleDateFormat format = new SimpleDateFormat(DATE_FORMAT);
format.setLenient(false);
String dateString = jsonParser.getText();
try {
return format.parse(dateString);
} catch (ParseException e) {
throw new InvalidFormatException(String.format("Date format should be %s", DATE_FORMAT), dateString, Date.class);
}
}
}
With neither solution can I specify a different format for different fields.
Although I can define multiple deserializers, it looks to me like a pretty ugly way to do this.
I thought that the #JsonFormat annotation was designed to deal with different formats of dates in different fields, but as I said, there is no exception when an invalid format is entered.
Could someone suggest an elegant solution to this problem?

(Spring) When using PUT method, #CreationTimestamp fails

I have this API that uses #CreationTimestamp to auto-generate the date when any information is added to the database, and it works. The problem is, when i use the PUT method in a specific information of the database, the generated Date disappears.
This is how things are structured:
...
#Temporal(TemporalType.TIMESTAMP)
#Column(name = "CreationDate", length = 29)
#CreationTimestamp
private Date CreationDate;
...
This is how my PUT method is:
#PutMapping("/SomeURL/{id}")
#ResponseBody
public User editUser(#RequestBody #Valid User T, #PathVariable Integer id) {
return userRepository.save(T);
}
When I use this, the generated Date from the #CreationTimestamp disappears, and that field becomes blank (null).
Why is this happening?
OBS: I dont think is necessary, but this is my POST method:
#PostMapping("/someURL")
public User addUser(#RequestBody #Valid User T) {
return userRepository.save(T);
}
The creation date will be updated when calling save method within your editUser method. The entity possibly does not contain this value, therefore null will be set as updated value. (you can try to debug this to check)
Change the column annotation as followed:
#Column(name = "CreationDate", length = 29, nullable = false, updatable = false)
This should prevent the once created date to be updated.
HTH

How to parse a date of format "2016-08-07T08:50:06.000Z" using Jackson and ObjectMapper

I am trying to parse a Json in the above format using Jackson and Java 8, but unable to do so.
Here is my code -
String date = "{\"requestDate\":\"2016-08-07T08:50:06.000Z\"}";
TestPOJO testPOJO = new ObjectMapper().readValue(date, TestPOJO.class);
System.out.println("testPOJO" + testPOJO.toString());
TestPojo.java
#AllArgsConstructor
#NoArgsConstructor
#Data
#JsonIgnoreProperties(ignoreUnknown = true)
public class TestPOJO {
#JsonProperty("requestDate")
#JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ss.SSS", timezone = "GMT")
private LocalDateTime testDate;
}
However for the same pattern I am able to parse it to Calendar Object.
Is there a way pattern to directly parse it as LocalDateTime object ?
Registering the jackson-datatype-jdk8 module will solve your issue.
ObjectMapper mapper = new ObjectMapper().registerModule(new Jdk8Module());

Spring mvc ZonedDateTime conversion to UTC

I woudl ike to convert all java8 ZonedDateTimes into UTC time zone on the server side of the application. I am successfully binding the Java 8 jsr310 date data types into a spring RestController using the #DateTimeFormat.
#RequestMapping(value = "rest/test-date", method = RequestMethod.GET)
public TestCollection findPrivilegesByRoleList(
#RequestParam(value = "local-date", defaultValue = "2015-05-10") #DateTimeFormat(iso = ISO.DATE) LocalDate requestParamDate,
#RequestParam(value = "local-date-time", defaultValue = "2015-05-16T15:55:56") #DateTimeFormat(iso = ISO.DATE_TIME) LocalDateTime requestParamLocalDateTime,
#RequestParam(value = "zoned-date-time", defaultValue = "2015-05-18T11:55:56-04:00") #DateTimeFormat(iso = ISO.DATE_TIME) ZonedDateTime requestParamZonedDateTime
)
For the ZonedDateTime class, I would like to shift all input ZonedDateTimes to UTC time, so the server side is always working in UTC timezone. Following best practice #3 - Store it in UTC
http://apiux.com/2013/03/20/5-laws-api-dates-and-times/#comments
For JSON deserialization, I have a custom deserializer for ZonedDateTime that shifts any timezone into UTC.
....
//Parse string into a zoned date time with the specified timezone offset - EST, CET, EDT, PST, ect.
ZonedDateTime zonedDateTimewithTimeZone = ZonedDateTime.parse(string, formatter);
//Shift the date time to UTC Time
return zonedDateTimewithTimeZone.withZoneSameInstant(ZoneId.of("UTC"));
What is the best way to do the conversion in the controller binding? I understand this may be forcing multiple responsibilities into the same class, however I want to avoid adding the
ZonedDateTime.withZoneSameInstant
call for every date in every controller.
Thanks

Spring Controller converts time to it's Local TimeZone

I have spring rest service project and I am using JPA hibernate and I am facing a strange issue in my controller. Below is code snippet:
controller:
#RequestMapping(method = RequestMethod.POST, value=PATH_SEPERATOR+ CREATE_OR_UPDATE_EVENT_METHOD, headers = ACCEPT_APPLICATION_JSON, produces = APPLICATION_JSON)
#ResponseStatus(HttpStatus.CREATED)
#ResponseBody
ResponseBean createOrUpdateEvent(#RequestBody Event eventBean)
{
ResponseBean response = new ResponseBean();
try {
String sysId = eventService.createOrUpdateEvent(eventBean);
response.setStatus(OK);
response.setData(sysId);
} catch(Exception ex) {
response = handleException(CREATE_OR_UPDATE_EVENT_METHOD, ex);
return response;
}
return response;
}
Event.java
#Entity
#JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "sysId", scope = Event.class)
#Table(name = "event")
public class Event {
#Column(name = "date_time")
#JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ss")
private Date dateTime;
public Date getDateTime() {
return dateTime;
}
public void setDateTime(Date dateTime) {
this.dateTime = dateTime;
}
}
When I pass date to Event bean in createOrUpdateEvent method as String "2014-04-17T17:15:56" which is in IST timezone, the controller convert it to Date with datetime "2014-04-17T22:45:56" IST considering previous time as UTC time. I don't understand this behaviour of auto conversion. I assume that it's because I am accepting parameter as bean, where bean is JPA Entity. Please help me to fix it.
There are several things you must take into consideration. First and foremost you are lacking a time zone information in the provided JSON serialization format "yyyy-MM-dd'T'HH:mm:ss". There's a format character that adds it - Z. Using it should be something like "yyyy-MM-dd'T'HH:mm:ssZ" depending on your preferences. Another thing you should consider is the fact that java.util.Date is not TimeZone aware and when you are creating a new Date(long) it always assumes that the passed date is in the current time zone.
So in order to fix this issue you have to add (and pass) the time zone as I told you and the Json parser will do the rest.

Resources