0

In my simple webservice written with spring boot, I have simple object like:

@Entity
@Table(name = "my_amazing_object", schema="s")
public class MyAmazingObject implements Serializable {
  @Id
  @GeneratedValue(strategy = GenerationType.IDENTITY)
  @Column(unique=true, nullable=false, pecision=10)
  private int id;

  @Column(name="capture_datetime")
  private Date captureDatetime;

  public void setCaptureDatetime(Date aCaptureDatetime){
    this.captureDatetime = aCaptureDatetime;
  }

  public Date getCaptureDatetime(){
    return this.captureDatetime;
  }
}

and in my Android application I have very similar object but without all those annotations:

public class MyAmazingObject implements Serializable {
  private int id;

  private Date captureDatetime;

  public void setCaptureDatetime(Date aCaptureDatetime){
    this.captureDatetime = aCaptureDatetime;
  }

  public Date getCaptureDatetime(){
    return this.captureDatetime;
  }
}

And my problem is that when I am sending this object to spring application using retrofit2 I am getting error

2021-08-06 14:02:03.610  WARN 20440 --- [nio-8080-exec-1] .w.s.m.s.DefaultHandlerExceptionResolver : Failed to read HTTP message: org.springframework.http.converter.HttpMessageNotReadableException: JSON parse error: Can not deserialize value of type java.util.Date from String "Aug 6, 2021 2:02:03 PM": not a valid representation (error: Failed to parse Date value 'Aug 6, 2021 2:02:03 PM': Can not parse date "Aug 6, 2021 2:02:03 PM": not compatible with any of standard forms ("yyyy-MM-dd'T'HH:mm:ss.SSSZ", "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", "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: Can not deserialize value of type java.util.Date from String "Aug 6, 2021 2:02:03 PM": not a valid representation (error: Failed to parse Date value 'Aug 6, 2021 2:02:03 PM': Can not parse date "Aug 6, 2021 2:02:03 PM": not compatible with any of standard forms ("yyyy-MM-dd'T'HH:mm:ss.SSSZ", "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", "yyyy-MM-dd'T'HH:mm:ss.SSS", "EEE, dd MMM yyyy HH:mm:ss zzz", "yyyy-MM-dd"))
 at [Source: java.io.PushbackInputStream@f588781; line: 2, column: 22] (through reference chain: com.example.spring.server.entities.MyAmazingObject["captureDatetime"])

The problem I have noticed is that in my android app when I am logging my object which I am sending I can see date time like this:

"captureDatetime": "Fri Aug 06 14:02:03 GMT+01:00 2021"

but on the spring application I am receiving something like this (you can see it in error message)

"captureDatetime": "Aug 6, 2021 2:02:03 PM":

I solved the issue with formatting date in android app as string like dd/MM/yyyy HH:mm and sending that to spring and on spring server I have to modify each settter (for Date) like this:

 public void setCaptureDatetime(String aCaptureDatetime){
    this.captureDatetime = new SimpleDateFormat("dd/MM/yyyy HH:mm").parse(aCaptureDatetime);
  }

and it is working fine. But right know I have object which have more then one Date and adding that SimpleDateFormat solution to each one of them is not the best solution in my opinion, I am almost sure there must other way to do this stuff.

I am think about sending Date from android and keeping it the same way on spring server, without parsing it to proper format.

I was trying to use JsonFormat(pattern = "dd/MM/yyyy HH:mm") but it did not help.

Is there any solution?

noname
  • 565
  • 6
  • 23

2 Answers2

1

Don't use java.util.Date. It's outdated and, paradoxically, doesn't have basic date utils (time zone, calendar, format...).

I recommend you to use java.time.Instant or java.time.LocalDate instead.

adamito
  • 19
  • 1
  • that would be great to use, but I have to support API 24 but LocalDate features are available only form API 26. Any other suggestions? – noname Aug 06 '21 at 14:21
  • For `Instant` and other java.time types for Andoird API level 24 look into [coreLibraryDesugaring](https://developer.android.com/studio/write/java8-support-table). – Ole V.V. Aug 09 '21 at 04:08
0

You can use LocalDateTime or even OffsetDateTime for the server, and date with @JsonFormat in the android app. Just make it use ISO 8601 on both ends. As shown here: https://stackoverflow.com/a/36253614/3841161

I'm not certain if JsonFormat works the same for the java.time classes, but I do know there's a dependency you can simply add to your project that enables serializers for those classes. You may only need the annotation on the Android app side, or different format descriptors for the both sides.

coladict
  • 4,799
  • 1
  • 16
  • 27