My pojo class is as given below
public class Employee {
private int empId;
#NotEmpty
private String empName;
#DateTimeFormat(pattern = "dd/MM/yyyy")
private Date empDoj;
public int getEmpId() {
return empId;
}
public void setEmpId(int empId) {
this.empId = empId;
}
public String getEmpName() {
return empName;
}
public void setEmpName(String empName) {
this.empName = empName;
}
public Date getEmpDoj() {
return empDoj;
}
public void setEmpDoj(Date empDoj) {
this.empDoj = empDoj;
}
I am accepting the request in controller as shown below
#RequestMapping(value = "/employee",method = RequestMethod.POST)
public Employee employee(#RequestBody #Valid Employee employee
) {
return employee ;
}
when I am sending the below JSON request from postman it is giving me an error
{
"empName":"Anubhav",
"empDoj":"10/10/2019"
}
JSON parse error: Cannot deserialize value of type java.util.Date from String "10/10/2019": not a valid representation (error: Failed to parse Date value '10/10/2019': Cannot parse date "10/10/2019": not compatible with any of standard forms ("yyyy-MM-dd'T'HH:mm:ss.SSSX", "yyyy-MM-dd'T'HH:mm:ss.SSS", "EEE, dd MMM yyyy HH:mm:ss zzz", "yyyy-MM-dd")); nested exception is com.fasterxml.jackson.databind.exc.InvalidFormatException: Cannot deserialize value of type java.util.Date from String "10/10/2019": not a valid representation (error: Failed to parse Date value '10/10/2019': Cannot parse date "10/10/2019": not compatible with any of standard forms ("yyyy-MM-dd'T'HH:mm:ss.SSSX", "yyyy-MM-dd'T'HH:mm:ss.SSS", "EEE, dd MMM yyyy HH:mm:ss zzz", "yyyy-MM-dd"))
at [Source: (PushbackInputStream); l
when I am doing the same for the method handler
#RequestMapping(value = "/dateformat",method = RequestMethod.POST)
public Date dateex(#DateTimeFormat(pattern = "dd-MM-yyyy") #RequestParam(value = "date")Date date) {
}
It is working fine. Converting string specified in given pattern to Date object then why not with Java class member. In the docs also it says it can be used either at method parameter or field formatted as given date type of field
Since you are sending in JSON you need to add the #JsonFormat(pattern="dd/MM/yyyy") annotation to empDoj. If all your dates will be this format you can set spring.jackson.date-format=dd/MM/yyyy in your application.properties file.
Some details about my vote to close.
You are attempting to use a SpringBoot parameter annotation to specify JSON formatting.
I believe you need to use the JsonFormat annotation
(as noted in the buræquete answer to this question)
Related
I have legacy data coming in to my API as part of UserRequest model like
#PostMapping
public MyResponse saveUser(#Valid #RequestBody UserRequest userRequest) {
...
}
UserRequest class uses OffsetDateTime for dateRegistered field:
public class UserRequest {
...
OffsetDateTime birthDate;
...
}
The problem I am having is that the data is coming into the API using below format for dateRegistered field:
{
"last-name":"Mikel",
"birth-date":"20200716"
}
So, the string representation "20200716" from JSON request needs to be somehow converted to OffsetDateTime like "2020-07-16T00:00:00Z" (the time portion and offset is set to 0s).
By default, the "20200716":
{
"last-name":"Mikel",
"birth-date":"20200716"
}
, gets converted to OffsetDateTime value of
{
"last-name": "Mikel",
"birth-date": "1970-08-22T19:18:36Z"
}
, which is obviously way off.
How do I convert a string representation of date in Json field like "20200716" to its OffsetDateTime representation like "2020-07-16T00:00:00Z" or "2020-07-16T00:00:00.000+00:00"?
I was trying to annotate my OffsetDateTime field with #JsonFormat("yyyyMMdd") but that is throwing exception like: JSON parse error: Cannot deserialize value of type java.time.OffsetDateTime from String "20200716".
you don't need a JSON annotation. You need to adjust the setter as follow.
public class MedicalCandidateRequest {
private OffsetDateTime dateRegistered;
public OffsetDateTime getDateRegistered() {
return dateRegistered;
}
public void setDateRegistered(String dateString) {
final String pattern = "yyyy-MM-dd'T'HH:mm:ss.SSSxx";
DateTimeFormatter dtFormatter = DateTimeFormatter.ofPattern(pattern);
this.dateRegistered = OffsetDateTime.parse(dateString, dtFormatter );
}
}
Change the parameter of the setter method to a String and do the conversion yourself.
public void setDateRegistered(String value) {
this.dateRegistered = doConversionHere(value);
}
Thanks for suggestions but I have decided to go with my own implementation.
I provided a custom deserializer like:
public class CustomDateDeserializer extends JsonDeserializer<OffsetDateTime> {
private static final String PATTERN = "yyyyMMdd";
private final DateTimeFormatter formatter;
public CustomDateDeserializer() {
this.formatter = DateTimeFormatter.ofPattern(PATTERN);
}
#Override
public OffsetDateTime deserialize(JsonParser parser, DeserializationContext context) throws IOException, JacksonException {
LocalDate localDate = LocalDate.parse(parser.getText), formatter);
OffsetDateTime offsetDateTime = OffsetDateTime.of(localDate, LocalTime.MIDNIGHT, ZoneOffset.UTC);
return offsetDateTime;
}
}
, which I then use to annotate my model field like:
#JsonDeserialize(using = CustomDateDeserializer.class)
private OffsetDateTime birthDate;
I have JSON string which was generated by GSON library and it looks like :
{
"id": 10,
"articleNumber": 5009,
"processDate": {
"year": 2021,
"month": 1,
"day": 1
},
"price": 1.22
}
I want to use Jackson for deserialize the above JSON. But it fails at processDate field due to the format how processDate field is present in the JSON.
How to parse the above JSON string by using some custom deserializer?
It seems you unwillingly got Jackson's built-in
LocalDateDeserializer parsing your date.
This deserializer supports several JSON date formats
(string, integer array, epoch day count)
"2021-1-1"
[2021, 1, 1]
18627
but unfortunately not your object-like format
{ "year": 2021, "month" :1, "day": 1 }
Therefore you need to write your own deserializer for LocalDate.
This is not so hard.
public class LocalDateDeserializer extends JsonDeserializer<LocalDate> {
#Override
public LocalDate deserialize(JsonParser parser, DeserializationContext ctxt)
throws IOException, JsonProcessingException {
JsonNode node = parser.getCodec().readTree(parser);
try {
int year = node.get("year").intValue();
int month = node.get("month").intValue();
int day = node.get("day").intValue();
return LocalDate.of(year, month, day);
} catch (Exception e) {
throw JsonMappingException.from(parser, node.toString(), e);
}
}
}
Then, in your Java class you need to tell Jackson,
that you want its processDate property be deserialized
by your own LocalDateDeserializer.
public class Root {
private int id;
private int articleNumber;
#JsonDeserialize(using = LocalDateDeserializer.class)
private LocalDate processDate;
private double price;
// getters and setters (omitted here for brevity)
}
I dont know java that well, just make a custom type like this. below
just create a custom Struct like:
inline class processDate {
int year,
int month,
int day,
public Date getDate(){
DateFormat formatter = new SimpleDateFormat("dd-MMM-yy");
Date date = formatter.parse(this.day + "-" + this.month + "-" + this.year);
return date;
}
}
I am converting the json received from database to object User.class using Objectmapper,class structure as follows
#XmlRootElement
public class User {
public User() {
super();
}
#XmlElement
private String username=null;
#XmlElement
private Feedbacks feedbacks=null;
//getter setter....
}
User has an instance of Feedbacks class which in turn has Arraylist< Feedback>
#XmlRootElement
public class Feedbacks {
public Feedbacks() {
}
#XmlElement
private ArrayList<Feedback> FeedbackList=new ArrayList<>();
public ArrayList<Feedback> getFeedbackList() {
return FeedbackList;
}
public void setFeedbackList(ArrayList<Feedback> FeedbackList) {
this.FeedbackList = FeedbackList;
}
}
and
public class Feedback {
private String feedback=null;
//private String timeStamp=null;
/*#JsonDeserialize(using = DateDeserializer.class); */
#JsonFormat(pattern = "MM/dd/yyyy HH:mm")
private Date feedbackDate;
public Feedback (){}
}
Sample json that i retrieve from db is:
{
"userName":"Test",
"feedbacks":{
"feedbackTOList":[
{
"feedback":"Please select appropriate value..1",
"timeStamp":"03/01/2000 14:52"
},
{
"feedback":"Please select appropriate value..2",
"timeStamp":"03/01/2018 13:50"
},
{
"feedback":"Please select appropriate value..3",
"timeStamp":"02/01/2018 10:52"
}
]
}
}
Json to object conversion and sorting the list of feedback based on date:
SimpleDateFormat formatter = new SimpleDateFormat("MM/dd/yyyy HH:mm");
mapper = new ObjectMapper();
mapper.setDateFormat(formatter);
userObject= mapper.readValue(jsonPayload, User.class);
Collections.sort(user.getFeedbacks().getFeedbackList(), new
Comparator<Feedback>() {
public int compare(Feedback f1, Feedback f2) {
if (f1.getTimeStamp() == null || f2.getTimeStamp() == null)
return 0;
return (f2.getTimeStamp().compareTo(f1.getTimeStamp()));
}
});
The issue is when angular UI consumes the object from rest service,instead of Date (Wed Aug 01 16:20:00 EDT 2018]) the timestamp value is being sent as timeStamp=1533154800000.
My question is how do i send the string in given format or atleast date object but not timestamp?
So far i tried #JsonFormat(pattern = "MM/dd/yyyy HH:mm"),custom date deserializer but no luck(by referring many other posts on stackoverflow,sites),can some one please let me know what mistake am i making?
I'm having an entity class according to the database, which includes a Date type field called start_date. There's a search bar within a jsp page where the user will be able to search for the data using the name or the date. But the search value which we're passing, into the method should be a String value.
But where as the start_date is a type of Date, and I'm unable to use that to search for a data since the search parameter is a string. What could I do to convert Date type into String? These are the sample entity fields I've got.
P.S: This is a Maven Hibernate Spring MVC project with MySQL
#Basic
#Column(name = "name")
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
#Basic
#Column(name = "start_date")
public Date getStartDate() {
return startDate;
}
public void setStartDate(Date startDate) {
this.startDate = startDate;
}
Any help would be appreciated.
Add an <input type="date"/> and bind it in a controller method with #RequestParam Date searchDate. The line format is yyyy-mm-dd so make sure your binder supports, because I'm not sure if it does so out of the box.
pubilc Static getFromattedDate(date,dateFormatter){
SimpleDateFormat formatter = new SimpleDateFormat(dateFormat);
return formatter.format(date);
}
Creating this method in your CalendarUtil.java you can call in from your controller.then you can format your inputs and return as string as you want.
I need to convert a certain JSON string to a Java object. I am using Jackson for JSON handling.
Here is my Java class:
public class RequestClass {
String email_id;
String password;
public String getEmailId() {
return email_id;
}
public String getPassword() {
return password;
}
#Override
public String toString(){
return email_id+" "+password;
}
}
Here is the web service code:
#POST
#Consumes(MediaType.APPLICATION_JSON)
#Produces(MediaType.APPLICATION_JSON)
#Path("/dbconnect3")
public String connectToDbTest3(RequestClass rc) {
System.out.println("connectToDbTest3");
String email_id = rc.getEmailId();
String password = rc.getPassword();
System.out.println(email_id + " " + password);
}
This throws exception UnrecognizedPropertyException with message "Unrecognized field "email_id" (Class jaxrs.RequestClass), not marked as ignorable".
In case i am not using the annotation #JsonIgnoreProperties(ignoreUnknown = true) in my Java class, the output I am getting on line 09 is:
null myPassword
So I don't want to ignore Unrecognized field instead I want to get the value of email_id.
Please tell why It shows email_id as Unrecognized field while password is fetched successfully.
Just add #JsonProperty("email_id") before the getEmailId() like given below:
#JsonProperty("email_id")
public String getEmailId() {
return email_id;
}