How to post date as an object parameter in Spring Requestmapping - java

In my browser debug, I can see that there is a date parameter inside my v object (Wed Mar 25 2015 03:00:00 GMT+0300 (Turkey Standard Time)),full text string format.
function saveVehicle(v) {
return $http.post('/shipment/vehicle/save', v).then(function(response) {
return response.data;
})
The problem is in my requestmapping debug, that date parameter comes with null. The server side coding is like this:
#RequestMapping(value="/vehicle/save", method = RequestMethod.POST)
public Vehicle saveVehicle(#RequestBody Vehicle v){
return vehicleRepository.save(v);
}
And my Vehicle model is like this:
#Entity
#Table(name = "VEHICLE", schema = "VV")
public class Vehicle {
#Column(name = "LOADING_DT")
#JsonSerialize(using = TfJsonDateSerializer.class)
#JsonDeserialize(using = TfJsonDateDeSerializer.class)
private Date loadingDate;

You need to map your object 'v' send from browser into the Java Object 'Vehicle'.
Usually using a json mapper or custom mapping from Map to your Vehicle pojo.

also try to POST a well formed object, that ressambles by parameter names your pojo.
v = {
"loading_date": new Date()
}
$http.post(..., v);
Additionally, I see that you're using custom (de)serializers, so please either post their code or be sure that they perform correctly, according to how the JS is serializing the date value
best
nas

It might be that the property into the request body doesn't have the same name of the java Vehicle#loadingDate attribute.
Assuming your request body has an attribute called loading_date, you have to map that name to the java attribute as follows:
import com.fasterxml.jackson.annotation.JsonProperty;
#JsonProperty("loading_date")
private Date loadingDate;
Also, it might be a good idea to define a string conversion for dates:
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonFormat;
#JsonProperty("loading_date")
#JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd", timezone = "UTC")
private Date loadingDate;
and add getters and setters in case you forgot:
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonFormat;
#JsonProperty("loading_date")
#JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd", timezone = "UTC")
private Date loadingDate;
public Date getLoadingDate() {
return loadingDate;
}
public void setLoadingDate(Date loadingDate) {
this.loadingDate = loadingDate;
}

Related

How to convert field in opencsv correct?

I have csv file with this columns id,equity_name,field,date,quartal,year. I have java class where there is a field
#Column(
columnDefinition = "smallint"
)
#Convert(
converter = YearAttributeConverter.class
)
#CsvCustomBindByName(column = "year", converter = YearCsvConverter.class)
private Year year;
And i use custom converter for this field.
#NoArgsConstructor
public class YearCsvConverter extends AbstractBeanField {
#Override
protected Object convert(String value) throws CsvDataTypeMismatchException, CsvConstraintViolationException {
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
return LocalDate.parse(value, formatter);
}
}
When i tried to parse file i have an
Exception in thread "pool-1-thread-6" java.lang.RuntimeException: com.opencsv.exceptions.CsvDataTypeMismatchException: Conversion of 1990-12-31 to java.time.LocalDate failed.
How to make this work and convert the field?
Your converter returns a LocalDate, but your field is of type Year, that is your DataTypeMismatch in the CsvDataTypeMismatchException.
Make your converter return an object of the correct data type e.g.:
return Year.fromLocalDate(LocalDate.parse(value, formatter));
On a side note: if you csvBindByName or CsvCustomBindByName, you don't need to specify the column name, and the following should work as long as your field name matches your header name.
#CsvCustomBindByName(converter = YearCsvConverter.class)
private Year year;

Serialized Timestamps converting to seconds

I'm trying to serialize a Timestamp Object to a JSON. But the object in the JSON is displayed as seconds.
This is a snippet of my POJO:
#JsonSerialize(include = JsonSerialize.Inclusion.NON_NULL)
public class TimeAndDateDetail{
#JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd hh.mm.ss")
private Timestamp timeAndDate;
public Timestame getTimeAndDate() {return timeAndDate; }
public void setTimeAndDate(Timestamp timeAndDate){
this.timeAndDate = timeAndDate;
}
}
This is my output:
{
"timeAndDate": 1583038800000
}
Why is this happening? And how can I get it to keep its original format?
You can annotate the field with #JsonFormat to specify the format, that the timestamp will be serialized. Here is an example:
#JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm")
Looks like you are using jackson, and this is the default behaviour of it.
best way is to disable the related object mapper feature:
objectMapper
.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false)

Why univocity's CsvParser throwing error when use LocalDate as the datatype for POJO and How to reslove it?

I am using Univocity's CSVParser to read csv file. My POJO look something like this.
import java.time.LocalDate;
import com.univocity.parsers.annotations.NullString;
import com.univocity.parsers.annotations.Parsed;
import lombok.Builder;
import lombok.Getter;
#Getter
#Setter
public class TempClass {
#Parsed(field = "A")
private int a;
#Parsed(field = "B")
private String b;
#Parsed(field = "C")
private LocalDate c;
}
My csv file look something like this:-
A,B,C
1,"Hi","2019-01-12"
2,"Hey","2019-01-13"
3,"Hello","2019-01-14"
Now when I try to read this file using CsvParser, it throws error saying Unable to set value '2019-01-12' of type 'java.lang.String' to field attribute 'c'.
Here I am guessing it is throwing error because it can not implicitly convert String to LocalDate. If that is the case then How can it able to convert String to int?
Is there way to solve the error Unable to set value '2019-01-12' of type 'java.lang.String' to field attribute 'c'?(without changeing data type of TempClass.c)
Univocity-parsers is still built on Java 6. LocalDate is not directly supported out of the box, but can to provide a conversion yourself. Something like:
public class LocalDateFormatter implements Conversion<String, LocalDate> {
private DateTimeFormatter formatter;
public LocalDateFormatter(String... args) {
String pattern = "dd MM yyyy";
if(args.length > 0){
pattern = args[0];
}
this.formatter = DateTimeFormatter.ofPattern(pattern);
}
#Override
public LocalDate execute(String input) {
return LocalDate.parse(input, formatter);
}
#Override
public String revert(LocalDate input) {
return formatter.format(input);
}
}
Then annotate your fields with #Convert and provide your conversion class:"
#Parsed(field = "C")
#Convert(conversionClass = LocalDateFormatter.class, args = "yyyy-MM-dd")
private LocalDate c;
The next version (3.0.0) is coming soon with support for this and a lot more.
Hope this helps.

Failed to parse "Date" from JSON

I have the following JSON string in REST response:
"09:41:50 CET"
For the corresponding POJO mapper class has a Date type for this field. So I've tried Jackson and GSON to map JSON to Java Object, but both failed with the following messages:
GSON: java.text.ParseException: Failed to parse date ["09:41:50 CET"]: Invalid number: 09:4
Jackson: InvalidFormatException: Cannot deserialize value of type `java.util.Date` from
String "09:41:50 CET": not a valid representation
Sadly I cannot modify in the POJO class the type to string or anything else, because I get those POJO classes from mvn dependency.
Try with this:
public static void main(String[] args) throws ParseException {
String jsonStr = "{ \"date\" : \"09:41:50 CET\" }";
Gson gson = new GsonBuilder().setDateFormat("HH:mm:ss").create();
JsonElement element = gson.fromJson (jsonStr, JsonElement.class);
OnlyDate date =gson.fromJson(element, new TypeToken<OnlyDate>(){}.getType());
System.out.println(date.getDate());
}
My example DTO is:
public class OnlyDate implements Serializable{
/**
*
*/
private static final long serialVersionUID = 1L;
#SerializedName("date")
private Date date ;
public Date getDate() {
return date;
}
public void setDate(Date date) {
this.date = date;
}
}
You have to specify the dateFormat of your gson Element
Not sure what kind of rest you have however if you are using spring rest you can do it by implementing custom Converter check the example at https://www.baeldung.com/spring-mvc-custom-data-binder.
Since Jackson v2.0, you can use #JsonFormat annotation directly on Object members;
#JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "HH:mm:ss", timezone="CET")
private Date date;

Spring, parsing string to LocalDateTime

I've got model and field like this:
#Element(name = "TIMESTAMP")
#DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME)
private LocalDateTime date;
In response I received:
<TIMESTAMP>2016-05-04T13:13:42.000</TIMESTAMP>
but during parsing xml to model I have error:
"message": "org.simpleframework.xml.core.PersistenceException: Constructor not matched for class java.time.LocalDateTime",
I also tried with:
#Element(name = "TIMESTAMP")
#DateTimeFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss.SSS")
private LocalDateTime date;
and this still doesn't work. Any Idea ? I am using springframework.xml lib.
The problem is by default simplexml lib doesn't know how to serialize/deserialize new Java8 date types.
In order to succeed you need to use custom converter.
Example entity (see the special #Convert annotation)
public class Entity {
#Element(name = "TIMESTAMP")
#Convert(LocalDateTimeConverter.class)
private LocalDateTime date;
// omitted
}
Special converter
public class LocalDateTimeConverter implements Converter<LocalDateTime> {
public LocalDateTime read(InputNode node) throws Exception {
String name = node.getValue();
return LocalDateTime.parse(name, DateTimeFormatter.ISO_LOCAL_DATE_TIME);
}
public void write(OutputNode node, LocalDateTime input) {
String value = input.format(DateTimeFormatter.ISO_LOCAL_DATE_TIME);
node.setValue(value);
}
}
Usage
Strategy strategy = new AnnotationStrategy();
Persister persister = new Persister(strategy);
Entity serializedEntity = persister.read(Entity.class, xmlInputStream);
Full source is available on GitHub

Categories