How to serialize Instant field of class with swagger-maven-plugin? - java

I have class with the field:
#ApiModelProperty(value = "Дата получения баланса", example = "2018-01-16T09:22:33.316Z")
#JsonProperty("date")
private Instant date;
When I generate yaml from this source (with swagger-maven-plugin) I get:
date:
type: "integer"
format: "int64"
example: "2018-01-16T09:22:33.316Z"
description: "Дата получения баланса"
So when I generate back my class from yaml (with swagger-codegen-maven-plugin) I get it with field:
#JsonProperty("date")
private Long date = null;
Why Instant converts to Long?

This is a bug of swaggger-core, and it was fixed on version 2.1.2 (See here).
If you're using a previous version you can customize this behaviour by replacing the PrimitiveType for the Instant data type with the following snippet:
PrimitiveType.customClasses().put(java.time.Instant.class.getName(),
PrimitiveType.DATE_TIME);

Related

Codec not found for requested operation: [TEXT <-> java.time.LocalDate]

This is the code which I am using to fill the column in the db.
DateTimeFormatter dateFormat = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSSSS");
JSONObject publishedObj = jsonObject.optJSONObject("created");
if(publishedObj != null){
String dateStr = publishedObj.getString("value");
book.setPublishedDate(LocalDate.parse(dateStr,dateFormat));
}
Below is the instance variable of the column where the data needs to go:
#Column("published_date")
#CassandraType(type = CassandraType.Name.DATE)
private LocalDate publishedDate;
Error Message which i am getting:
com.datastax.oss.driver.api.core.type.codec.CodecNotFoundException: Codec not found for requested operation: [TEXT <-> java.time.LocalDate]
Can please someone help.
Thankyou!!
I can reproduce that error with your code above. To remedy it, I have ALTERed the book_by_id table with two new columns:
ALTER TABLE book_by_id ADD pubdate2 TEXT;
ALTER TABLE book_by_id ADD pubdate3 DATE;
My BookEntity class for those columns looks like this:
#Column("pubdate2")
#CassandraType(type = CassandraType.Name.TEXT)
private String publishedDate2;
#Column("pubdate3")
#CassandraType(type = CassandraType.Name.DATE)
private LocalDate publishedDate3;
The code to parse and set the date looks like this:
DateTimeFormatter dateFormat = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSSSS");
String dateStr = "2022-03-03T09:52:33.235555";
musicBook.setPublishedDate2(LocalDate.parse(dateStr,dateFormat).toString());
musicBook.setPublishedDate3(LocalDate.parse(dateStr,dateFormat));
template.insert(musicBook);
tl;dr;
Redefine published_date as a DATE type, and it will work. Besides, dates/times should be stored in date/time types in databases.
Note that Cassandra won't allow you to modify a column's data type. Also, the process of dropping and adding a column with the same name in quick succession has proven to be problematic with Cassandra in the past. I'd advise adding a newly named column of a DATE type, and reloading its data. Or recreate the table (with the correct data types) and reload the data.

typeMismatch.target spring boot batch rejected value [2020-09-18T00:00:00+02:00]

I am trying to integrate data from CSV file with spring boot using a batch,
I have a problem with the date field because it is constantly rejected regardless of the type used,
here is my code:
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String service;
private Timestamp time;
#Override
public IndProd process(final IndProd indProd) throws Exception {
String service = indProd.getService();
Timestamp time = indProd.getTime();
Long nbAppels = indProd.getNbAppels();
Integer tempsDeReponseMoyenMillisecondes = indProd.getTempsDeReponseMoyenMillisecondes();
Long volume = indProd.getVolume();
BigDecimal tempsDeReponseMoyenSecondes = indProd.getTempsDeReponseMoyenSecondes();
IndProd transformedIndProd = new IndProd(service,time,nbAppels,tempsDeReponseMoyenMillisecondes,volume,tempsDeReponseMoyenSecondes);
return transformedIndProd;
}
here is the error returned:
Caused by: org.springframework.validation.BindException:
org.springframework.validation.BeanPropertyBindingResult: 1 errors
Field error in object 'target' on field 'time': rejected value
[2020-09-18T00:00:00+02:00]; codes
[typeMismatch.target.time,typeMismatch.time,typeMismatch.java.sql.Timestamp,typeMismatch];
arguments
[org.springframework.context.support.DefaultMessageSourceResolvable:
codes [target.time,time]; arguments []; default message [time]];
default message [Failed to convert property value of type
'java.lang.String' to required type 'java.sql.Timestamp' for property
'time'; nested exception is java.lang.IllegalStateException: Cannot
convert value of type 'java.lang.String' to required type
'java.sql.Timestamp' for property 'time': no matching editors or
conversion strategy found] at
org.springframework.batch.item.file.mapping.BeanWrapperFieldSetMapper.mapFieldSet(BeanWrapperFieldSetMapper.java:201)
~[spring-batch-infrastructure-4.2.4.RELEASE.jar:4.2.4.RELEASE] at
org.springframework.batch.item.file.mapping.DefaultLineMapper.mapLine(DefaultLineMapper.java:43)
~[spring-batch-infrastructure-4.2.4.RELEASE.jar:4.2.4.RELEASE] at
org.springframework.batch.item.file.FlatFileItemReader.doRead(FlatFileItemReader.java:185)
~[spring-batch-infrastructure-4.2.4.RELEASE.jar:4.2.4.RELEASE] ... 56
common frames omitted
Thanks for your help
From the error, it clear that indProd.getTime() returns a String value which you are trying to assign to a Timestamp variable. Assuming indProd.getTime() returns a date-time string in the format, yyyy-MM-dd'T'HH:mm:ssXXX e.g. 2020-09-18T00:00:00+02:00 (as mentioned in the title of your question), you should replace
Timestamp time = indProd.getTime();
with
Timestamp time = new Timestamp(new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssXXX").parse(indProd.getTime()).getTime());
Note: java.sql.Timestamp extends java.util.Date and the date-time API of java.util and their formatting API, SimpleDateFormat are outdated and error-prone. I suggest you should stop using them completely and switch to the modern date-time API.
Using the modern date-time API:
OffsetDateTime odt = OffsetDateTime.parse(indProd.getTime());
//...
IndProd transformedIndProd = new IndProd(service,odt,nbAppels,tempsDeReponseMoyenMillisecondes,volume,tempsDeReponseMoyenSecondes);
and declare the instance members as
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String service;
private OffsetDateTime odt;// Change the type to OffsetDateTime
Learn more about the modern date-time API at Trail: Date Time. If you are working for an Android project and your Android API level is still not compliant with Java-8, check Java 8+ APIs available through desugaring and How to use ThreeTenABP in Android Project.
As the error said you are trying to assign a String value to an Instant variable.
That mean indProd.getTime() is trying to be String.
One way to fix this is to retype to String back to instant, it is maybe not the best solution but is should work.
Timestamp time = Timestamp.from(ZonedDateTime.parse(indProd.getTime()).toInstant());
and in IndProd variable change time to String

Failed to convert value of 'java.lang.string' to 'java.localtime' from jsp in springboot

I am very new to SpringBoot. I have some issues converting String value which I get from jsp form to LocalTime.
For example I have jsp form where I write my input:
<div class="col-lg-7">
<form:input path="shiftStart" type="time" name="shiftStart" id="shift-start-time" min="08:00:00" max="17:45:00" step="900"></form:input>
</div>
and I have the following controller where I try to convert this String value to LocalTime variable:
#PostMapping("/add-shift")
public String createShiftForm(#ModelAttribute("shiftForm") #Valid TimeTable timeTable, BindingResult result, Model model, #RequestParam("shiftStart") String shiftStart ){
if (result.hasErrors()) {
return "/add-shift";
}
LocalTime startShift = LocalTime.parse(shiftStart);
model.addAttribute("shiftStart",startShift);
return "redirect:/admin";
}
and I am getting the following error:
Failed to convert property value of type java.lang.String to required type java.time.LocalTime for property shiftEnd; nested exception is org.springframework.core.convert.ConversionFailedException: Failed to convert from type [java.lang.String] to type [#javax.persistence.Column java.time.LocalTime] for value 09:15; nested exception is java.lang.IllegalArgumentException: Parse attempt failed for value [09:15]
Can anybody please help?
I found a solution: just need to pass parametr without #RequestParametr in Controller and convert string to localtime in local variable like this:
#RequestParam #DateTimeFormat(iso = DateTimeFormat.ISO.TIME) LocalTime shiftStart
Here it was discussed:How to use LocalDateTime RequestParam in Spring? I get "Failed to convert String to LocalDateTime"
You need to parse the String value to LocalTime to do so you need to figure out in which format you're receiving it and you just add this code :
LocalTime startShift = LocalTime.parse(time, DateTimeFormatter.ofPattern("HH:mm"));
As Elarbi said, I also recommand using a standard formatter:
DateTimeFormatter formatter = DateTimeFormatter.ISO_LOCAL_TIME;
LocalTime lt = LocalTime.parse("10:15:45", formatter);
Or directly:
LocalTime lt = LocalTime.parse("10:15:45", DateTimeFormatter.ISO_LOCAL_TIME);
For a list of patterns consider this from official Oracle doc.

I want date to be displayed in Milliseconds(epoch) format but getting date with timestamp

#Data
public class SampleDate {
private Date revisiondate;
}
#RequestMapping("/date")
public ResponseEntity<List<SampleDate>> getDateSample()
{
List<SampleDate> listDate = new ArrayList<>();
SampleDate sampDate = new SampleDate();
sampDate.setRevisiondate(new Date());
listDate.add(sampDate);
return new ResponseEntity<>(listDate,HttpStatus.OK);
}
Output : [{"revisiondate":"2018-12-06T06:06:18.795+0000"}]
Expected Output : [{"revisiondate":1544077577462}]
I'm using Springboot 2.0.3.RELEASE version. In Springboot 1.3.2.RELEASE version im able to achieve this. Have anyone faced this when you upgrade Springboot.
Judging by this guide, assuming SpringBoot still uses Jackson, it looks like you can specify that the shape of the data should be a number:
#JsonFormat(shape = JsonFormat.Shape.NUMBER)
private Date revisiondate;
(Admittedly that guide describes it as seconds since the Unix epoch, but it gives an example that's milliseconds.)
You can use below annotation on top of date field.
#JsonFormat(shape = JsonFormat.Shape.NUMBER)
private Date revisiondate;
As suggested here

How to serialize and deserialize Java 8 dateTime in lift JSON?

I have a case class which I want to serialize first. Then after that, I want to deserialize it for storing purpose in MongoDB but java 8 LocalDateTime was creating problem. I took help from this link:
how to deserialize DateTime in Lift
but with no luck. I am unable to write it for java 8 date time.
Can any one please help me with this date Time issue? Here is my code:
import net.liftweb.json.Serialization.{read, write}
implicit val formats = Serialization.formats(NoTypeHints)
case class Child(var str: String, var Num: Int, var abc: Option[String], MyList: List[Int], val dateTime: LocalDateTime = LocalDateTime.now())
val ser = write(Child("Mary", 5, None, List(1, 2)))
println("Child class converted to string" + ser)
var obj = read[Child](ser)
println("object of Child is " + obj)
And here is the error message printed on the console:
(run-main-0) java.lang.ArrayIndexOutOfBoundsException: 49938
java.lang.ArrayIndexOutOfBoundsException: 49938
at com.thoughtworks.paranamer.BytecodeReadingParanamer$ClassReader.<init>(BytecodeReadingParanamer.java:451)
at com.thoughtworks.paranamer.BytecodeReadingParanamer$ClassReader.<init>(BytecodeReadingParanamer.java:431)
at com.thoughtworks.paranamer.BytecodeReadingParanamer$ClassReader.<init>(BytecodeReadingParanamer.java:492)
at com.thoughtworks.paranamer.BytecodeReadingParanamer$ClassReader.<init>(BytecodeReadingParanamer.java:337)
at com.thoughtworks.paranamer.BytecodeReadingParanamer.lookupParameterNames(BytecodeReadingParanamer.java:100)
at com.thoughtworks.paranamer.CachingParanamer.lookupParameterNames(CachingParanamer.java:75)
at com.thoughtworks.paranamer.CachingParanamer.lookupParameterNames(CachingParanamer.java:68)
at net.liftweb.json.Meta$ParanamerReader$.lookupParameterNames(Meta.scala:89)
at net.liftweb.json.Meta$Reflection$.argsInfo$1(Meta.scala:237)
at net.liftweb.json.Meta$Reflection$.constructorArgs(Meta.scala:253)
at net.liftweb.json.Meta$Reflection$.net$liftweb$json$Meta$Reflection$$findMostComprehensive$1(Meta.scala:266)
at net.liftweb.json.Meta$Reflection$$anonfun$primaryConstructorArgs$1.apply(Meta.scala:269)
at net.liftweb.json.Meta$Reflection$$anonfun$primaryConstructorArgs$1.apply(Meta.scala:269)
at net.liftweb.json.Meta$Memo.memoize(Meta.scala:199)
at net.liftweb.json.Meta$Reflection$.primaryConstructorArgs(Meta.scala:269)
at net.liftweb.json.Extraction$.decompose(Extraction.scala:88)
at net.liftweb.json.Extraction$$anonfun$1.applyOrElse(Extraction.scala:91)
at net.liftweb.json.Extraction$$anonfun$1.applyOrElse(Extraction.scala:89)
at scala.collection.immutable.List.collect(List.scala:305)
at net.liftweb.json.Extraction$.decompose(Extraction.scala:89)
at net.liftweb.json.Serialization$.write(Serialization.scala:38)
at TestActor$.delayedEndpoint$TestActor$1(TestActor.scala:437)
at TestActor$delayedInit$body.apply(TestActor.scala:54)
at scala.Function0$class.apply$mcV$sp(Function0.scala:40)
at scala.runtime.AbstractFunction0.apply$mcV$sp(AbstractFunction0.scala:12)
at scala.App$$anonfun$main$1.apply(App.scala:76)
at scala.App$$anonfun$main$1.apply(App.scala:76)
at scala.collection.immutable.List.foreach(List.scala:383)
at scala.collection.generic.TraversableForwarder$class.foreach(TraversableForwarder.scala:35)
at scala.App$class.main(App.scala:76)
at TestActor$.main(TestActor.scala:54)
at TestActor.main(TestActor.scala)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
If I remove the dateTime parameter from case class, it works fine. It seems like the problem is in dateTime.
I ran your code on my Intellij Idea, got the same error. Tried to debug the cause but the invocation stack is so deep that I finally gave up.
But I guess maybe it is because Lift doesn't provide default Format for LocaleDateTime, just like the post you mentioned said, "it is the DateParser format that Lift uses by default."
Here is a compromise for your reference,Lift-JSON provides default Date format for us
// net.liftweb.json.Serialization Line 72
def formats(hints: TypeHints) = new Formats {
val dateFormat = DefaultFormats.lossless.dateFormat
override val typeHints = hints
}
So instead of going all the way to write customized serializer, we may as well change our data type to fit the default Date format. Plus, net.liftweb.mongodb.DateSerializer(Line 79) provides support for Date serialization.
Then, we can provide method to easily get LocaleDateTime. Following is how I try to figure it out.
package jacoffee.scalabasic
import java.time.{ ZoneId, LocalDateTime }
import java.util.Date
// package object defined is for Scala compiler to look for implicit conversion for case class parameter date
package object stackoverflow {
implicit def toDate(ldt: LocalDateTime): Date =
Date.from(ldt.atZone(ZoneId.systemDefault()).toInstant())
implicit def toLDT(date: Date): LocalDateTime =
LocalDateTime.ofInstant(date.toInstant(), ZoneId.systemDefault())
}
package jacoffee.scalabasic.stackoverflow
import java.time.LocalDateTime
import java.util.Date
import net.liftweb.json.{ NoTypeHints, Serialization }
import net.liftweb.json.Serialization.{ read, write }
case class Child(var str: String, var Num: Int, var abc: Option[String],
myList: List[Int], val date : Date = LocalDateTime.now()) {
def getLDT: LocalDateTime = date
}
object DateTimeSerialization extends App {
implicit val formats = Serialization.formats(NoTypeHints)
val ser = write(Child("Mary", 5, None, List(1, 2)))
// Child class converted to string {"str":"Mary","Num":5,"myList":[1,2],"date":"2015-07-21T03:07:05.699Z"}
println(" Child class converted to string " + ser)
var obj=read[Child](ser)
// Object of Child is Child(Mary,5,None,List(1, 2),Tue Jul 21 11:48:22 CST 2015)
println(" Object of Child is "+ obj)
// LocalDateTime of Child is 2015-07-21T11:48:22.075
println(" LocalDateTime of Child is "+ obj.getLDT)
}
Anyway, hope it helps.

Categories

Resources