I have to read date string from json and set it to java object.
I have used the following annotations on my variable.
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
#JsonInclude(JsonInclude.Include.NON_NULL)
public class RequestObject {
#JsonProperty("doj")
#JsonDeserialize(using = CustomDateDeserializer.class, as=Date.class)
private Date doj;
public Date getDoj() {
return doj;
}
public void setDoj(Date doj) {
this.doj = doj;
}
}
Below is my Custom DateDeserializer.
import java.io.IOException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
#SuppressWarnings("serial")
public class CustomDateDeserializer extends JsonDeserializer<Date>{
#Override
public Date deserialize(JsonParser jsonParser, DeserializationContext context) throws IOException, JsonProcessingException {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
String date = jsonParser.getText();
try{
return sdf.parse(date);
}catch(ParseException e){
throw new RuntimeException(e);
}
}
}
I am testing this using postman, below is my postman request.
{
"doj":"2017-12-27"
}
But I am getting the following error.
Caused by: java.lang.IllegalArgumentException: Invalid format: "2017-12-27" is too short
at org.joda.time.format.DateTimeFormatter.parseDateTime(DateTimeFormatter.java:945) ~[joda-time-2.9.1.jar:2.9.1]
at com.exxonmobil.ace.hybris.jaxb.DateAdapter.unmarshal(DateAdapter.java:45) ~[DateAdapter.class:?]
at com.exxonmobil.ace.hybris.jaxb.DateAdapter.unmarshal(DateAdapter.java:1) ~[DateAdapter.class:?]
at org.eclipse.persistence.internal.jaxb.XMLJavaTypeConverter.convertDataValueToObjectValue(XMLJavaTypeConverter.java:149) ~[org.eclipse.persistence.moxy-2.6.1.jar:?]
Could someone please let me know where I am going wrong.
Regards,
Farhan
Related
Implementaion: Im trying to show the customize exception DATE_FORMAT_EXCEPTION with a message of Date format is wrong if error. But even i input a wrong format the customize exception wont show but there is error 400 Bad Request and i use Exception which catch all the error.
import java.io.IOException;
import java.time.LocalDate;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.Date;
import com.cartgatewayservice.RestModelException.DATE_FORMAT_EXCEPTION;
import com.fasterxml.jackson.core.JacksonException;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
public class DateDeserializer extends JsonDeserializer<Date> {
#Override
public Date deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JacksonException {
DateTimeFormatter localDateFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
String dateValue = p.getValueAsString();
try {
LocalDate localDate = LocalDate.parse(dateValue, localDateFormatter);
return convertToDateViaInstant(localDate);
} catch (Exception e) {
throw new DATE_FORMAT_EXCEPTION("Date format is wrong");
}
}
public Date convertToDateViaInstant(LocalDate dateToConvert) {
return Date.from(dateToConvert.atStartOfDay()
.atZone(ZoneId.systemDefault())
.toInstant());
}
}
import java.util.Date;
import com.cartgatewayservice.BodyConvertParameters.DateDeserializer;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.OptBoolean;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import org.springframework.format.annotation.DateTimeFormat;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.ToString;
#Data
#NoArgsConstructor
#AllArgsConstructor
#ToString
#Builder
public class ProductEntity {
#DateTimeFormat(iso = DateTimeFormat.ISO.DATE)
#JsonFormat(pattern = "yyyy-MM-dd", shape = JsonFormat.Shape.STRING, lenient = OptBoolean.FALSE)
#JsonDeserialize(using = DateDeserializer.class)
private Date productexpirationdate;
}
public class DATE_FORMAT_EXCEPTION extends RuntimeException {
private static final long serialVersionUID = 1L;
public DATE_FORMAT_EXCEPTION(String message) {
super(message);
}
}
#ControllerAdvice
public class RestAdviceException extends ResponseEntityExceptionHandler {
#ExceptionHandler(DATE_FORMAT_EXCEPTION.class)
public ResponseEntity<Object> handleFormatDateEntity(DATE_FORMAT_EXCEPTION ex, WebRequest request) {
return new ResponseEntity<Object>(new ERROR_DETAILS_EXCEPTION(ex.getMessage(), HttpStatus.BAD_REQUEST, LocalDateTime.now()),HttpStatus.NOT_FOUND);
..........
}
}
DTO:
#Getter
#Setter
#ToString
public class TestDto {
#NotNull
private String id;
#NotNull
#DateTimeFormat(pattern = "YYYY-MM-DD'T'hh:mm:ss.SSSZ")
private Instant timestamp;
}
When I give this input
{"timestamp":"4/23/2018 11:32 PM","id":"132"}
It gives BAD_REQUEST (which it should), but I want to handle this malformed date and throw an exception with my custom exception.
How can I add this?
Since OP requested feature is not supported yet: https://github.com/FasterXML/jackson-annotations/issues/130
Trying to do the same thing with a bit longer approach by using custom deserializer for a field timestamp
Custom exception class:
import com.fasterxml.jackson.core.JsonProcessingException;
public class MyException extends JsonProcessingException {
public MyException(String message) {
super(message);
}
}
Custom Deserializer class:
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.deser.std.StdDeserializer;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.time.Instant;
import java.util.Date;
public class InstantDeserializer extends StdDeserializer<Instant> {
public InstantDeserializer() {
this(null);
}
public InstantDeserializer(Class<?> vc) {
super(vc);
}
private SimpleDateFormat sdf = new SimpleDateFormat("YYYY-MM-DD'T'hh:mm:ss.SSS'Z'");
#Override
public Instant deserialize(JsonParser jp, DeserializationContext ctxt)
throws IOException, JsonProcessingException {
JsonNode node = jp.getCodec().readTree(jp);
Date date = null;
try {
date = sdf.parse(node.asText());
} catch (Exception e) {
throw new MyException("Instant field deserialization failed");
}
return date.toInstant();
}
}
Updated TestDto class:
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
import org.springframework.format.annotation.DateTimeFormat;
import javax.validation.constraints.NotNull;
import java.time.Instant;
#Getter
#Setter
#ToString
public class TestDto {
#NotNull
private String id;
#NotNull
#JsonDeserialize(using = InstantDeserializer.class)
#DateTimeFormat(pattern = "YYYY-MM-DD'T'hh:mm:ss.SSS'Z'")
private Instant timestamp;
}
Invalid Input request:
{"timestamp":"4/23/2018 11:32 PM","id":"132"}
Response:
{
"timestamp": 1552845180271,
"status": 400,
"error": "Bad Request",
"message": "JSON parse error: Instant field deserialization failed; nested exception is com.fasterxml.jackson.databind.JsonMappingException: Instant field deserialization failed (through reference chain: TestDto[\"timestamp\"])"
}
Valid Input Request:
{"timestamp":"2018-04-23T11:32:22.213Z","id":"132"}
Response:
{
"id": "132",
"timestamp": {
"epochSecond": 1514700142,
"nano": 213000000
}
}
If you do not like the way timestamp field is getting deserialized and would like to change that, this SO post will be helpful.
This question already has answers here:
Parse json date string in android
(7 answers)
Closed 6 years ago.
In Json list i'm getting such a date: "lastModifiedDate":1459202400000". Serialize and Deserialize class they seem to be ok.
Entity class:
import org.codehaus.jackson.map.annotate.JsonDeserialize;
import org.codehaus.jackson.map.annotate.JsonSerialize;
import org.hibernate.validator.constraints.Email;
#Data
#ToString
#Entity
public class UserEntity implements Serializable {
#JsonSerialize(using=JsonDateSerializer.class)
#JsonDeserialize(using=JsonDateDeserializer.class)
#Column(name = "LastModifiedDate", columnDefinition="DATETIME", nullable = true, insertable = true, updatable = true)
private java.util.Date lastModifiedDate;
}
Deserializer class:
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import org.codehaus.jackson.JsonParseException;
import org.codehaus.jackson.JsonParser;
import org.codehaus.jackson.JsonProcessingException;
import org.springframework.stereotype.Component;
import org.codehaus.jackson.JsonGenerator;
import org.codehaus.jackson.map.*;
#Component
public class JsonDateDeserializer extends JsonDeserializer<Date> {
private static final SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
#Override
public Date deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JsonProcessingException {
try {
return dateFormat.parse(jsonParser.getText());
} catch (Exception e) {
throw new JsonParseException("Could not parse date", jsonParser.getCurrentLocation(), e);
}
}
What's wrong?
}
You are not parsing the date correctly. Right now you receive a date in milliseconds, so you have first to create a date before formatting, i.e.:
dateFormat.format(new Date(Long.parseLong(jsonParser.getText())));
Or if you just want to create the Date object from it, just skip the format part.
i am writing a rest services where i am getting response as in format "1448994600000" for date but i need it to give response in date,month,year format.
if i send data by giving 12-2-2015 format it give me error
The request sent by the client was syntactically incorrect
In response i get "12333333333" format,i need it to response with 12-2-2015
i have used below code to deserialize it,but its not working what is going wrong in my code,Please guide me.
import java.io.Serializable;
import java.sql.Date;
import java.sql.Timestamp;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;
import org.codehaus.jackson.annotate.JsonAutoDetect;
import org.codehaus.jackson.annotate.JsonIgnoreProperties;
import org.codehaus.jackson.map.annotate.JsonSerialize;
#JsonAutoDetect
#Entity
#Table(name = "DataValueTable")
#JsonIgnoreProperties({"hibernateLazyInitializer", "handler"})
public class DataValueTable implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue
#Column(name = "ID")
private long id;
#JsonSerialize(using=JsonDateSerializer.class)
#Column(name = "Time")
private Date time;
public Date getTime() {
return time;
}
public void setTime(Date time) {
this.time = time;
}
JsonDateSerializer.java
package com.beingjavaguys.model;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import org.codehaus.jackson.JsonGenerator;
import org.codehaus.jackson.JsonProcessingException;
import org.codehaus.jackson.map.JsonSerializer;
import org.codehaus.jackson.map.SerializerProvider;
import org.springframework.stereotype.Component;
/**
* Used to serialize Java.util.Date, which is not a common JSON
* type, so we have to create a custom serialize method;.
*
* #author Loiane Groner
* http://loianegroner.com (English)
* http://loiane.com (Portuguese)
*/
#Component
public class JsonDateSerializer extends JsonSerializer<Date>{
private static final SimpleDateFormat dateFormat = new SimpleDateFormat("dd-MM-yyyy");
#Override
public void serialize(Date date, JsonGenerator gen, SerializerProvider provider)
throws IOException, JsonProcessingException {
String formattedDate = dateFormat.format(date);
gen.writeString(formattedDate);
}
}
method in my controller
/* Getting List of objects in Json format in Spring Restful Services */
#RequestMapping(value = "/list", method = RequestMethod.GET)
public #ResponseBody List getDatalist() {
List DataList = null;
try {
DataList = dataServices.getDataEntityList();
} catch (Exception e) {
e.printStackTrace();
}
return DataList;
}
update data
#RequestMapping(value = "/updateData", method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON_VALUE)
public #ResponseBody
Status updateData(#RequestBody DataValueTable dataObject) {
try {
//response.addHeader("Access-Control-Allow-Origin","*");
dataServices.insertData(dataObject);
return new Status(1, "Data updated Successfully !");
} catch (Exception e) {
// e.printStackTrace();
return new Status(0, e.toString());
}
}
You can use implementation which has been introduced to java8
Import specific libraries
import java.time.LocalDate
import java.time.ZoneId
import java.time.format.DateTimeFormatter
LocalDate localDate= LocalDate.now();
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd-MM-yyyy");
String stamp = localDate.format(formatter);
If you need conversion from Date, you would do it as following
Date input = new Date();
LocalDate localDate = input.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
And the output could be sth like 13-01-2016
I am new to JAX-RS and I want to serve my list of items as JSON. My entity model is something like this:
public class Entity {
private String name;
private Date date;
private Float number;
}
This is how I am invoking the service:
#Path("/entities")
public class EntitiesController {
#GET
#Produces({"application/json"})
public List<Entity> getEntities() {
return EntityDAO.entitiesList();
}
}
However, the date is not formatted but is displayed as a long.
This answer shows how to format a date using a JsonSerializer. If I extend JsonSerializer, then where do I put that subclass in my project?
I figured a solution myself:
Under a new serializers package I created the CustomJsonDateSerializer class, which will be delegated the responsibility of formatting the date attribute thanks to the #JsonSerialize(...) annotation.
So I modified my Entity class adding that annotation ontop of the field:
#JsonSerialize(using = CustomJsonDateSerializer.class)
private Date date;
And this is the content of CustomJsonDateSerializer:
package serializers;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import com.fasterxml.jackson.core.JsonGenerationException;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
public class CustomJsonDateSerializer extends JsonSerializer<Date> {
#Override
public void serialize(Date value, JsonGenerator jgen, SerializerProvider provider)
throws IOException, JsonGenerationException {
SimpleDateFormat formatter = new SimpleDateFormat("dd-MM-yyy");
String format = formatter.format(value);
jgen.writeString(format);
}
}