0

While trying to serialize the following Object, which has a LocalDate field, with Gson, it works without any problem without using the @Expose annotation.

@Data
@Entity(name = "user")
@NoArgsConstructor
public class User {

    @NotEmpty
    @NotNull
    @Id
    @Column(unique = true)
    @Expose
    private String userName;

    @NotEmpty
    @NotNull
    private String password;

    @Past @After1900
    @Expose
    private LocalDate birthday;

    @Email
    @Expose
    private String email;

    @EqualsAndHashCode.Exclude
    @OneToMany(mappedBy = "user", fetch= FetchType.LAZY, cascade = CascadeType.ALL)
    @Expose
    private List<Address> addressList;

}

With the following code,

Gson gson = new Gson();
System.out.println(gson.toJson(user));

I get the following Json,

{
   "userName":"demo_user",
   "password":"123456",
   "birthday":{
      "year":2000,
      "month":1,
      "day":1
   },
   "email":"demo@demo.de",
   "addressList":[
      {
         "id":4,
         "street":"An der Weberei",
         "number":"5",
         "postalCode":"96049"
      }
   ]
}

But with the following code by adding excludeFieldsWithoutExposeAnnotation(),

Gson gson = new GsonBuilder()
                .excludeFieldsWithoutExposeAnnotation()
                .create();
System.out.println(gson.toJson(user));

I get the following Json without any value in the birthday field,

{
   "userName":"demo_user",
   "birthday":{
      
   },
   "email":"demo@demo.de",
   "addressList":[
      {
         "street":"An der Weberei",
         "number":"5",
         "postalCode":"96049"
      }
   ]
}

Am I missing something here which is causing this problem?

Joy Saha
  • 11
  • 2
  • 1
    Have a look at the first JSON: `year`, `month`, `day` -- is that really what you wanted and doesn't it look **weird** to you? I guess it should look weird, as you most likely want to have something like a **strictly defined** `"YYYY-MM-DD"` in your JSON. Gson does not have Java 8 Time API support by default and it takes `LocalDate` as a regular POJO similar to your `User`. Obviously, the internal fields of the `LocalDate` class are not annotated with `@Expose`, therefore they are not serialized -- exactly what you told Gson in the builder... https://stackoverflow.com/a/53246168/12232870 – terrorrussia-keeps-killing Jan 23 '22 at 00:10
  • @fluffy, to be fair, it is not really that obvious to users when Gson is accessing the internal fields of JDK classes. Your explanation seem to be correct, but from the standpoint of a user (who might not have much experience with Gson yet), that JSON data might look like it have been written by a default adapter of Gson. – Marcono1234 Jan 23 '22 at 02:41
  • It's not about experience, it's more of deducing why it happens right from what the annotation is designed for, especially for complex _objects_ that may be designated in strings for humans in real life. Dates exist in real life for everyone. – terrorrussia-keeps-killing Jan 23 '22 at 11:59
  • 1
    Compare it to serializing `java.util.Pattern` whose only public way to construct is using the factory method `compile` and the regexp string, and no one even knows its fancy internals until they get serialized. No one, except of the maintainers, should even if (some of) the components look meaningful. However, in my JRE implementation, it serializes as `{"pattern":..., "flags":...}` (meaningful but still not a single string) having a lot of private fields `transient` behind the scenes, and yes, adding `excludeFieldsWithoutExposeAnnotation` will make it `{}` too. – terrorrussia-keeps-killing Jan 23 '22 at 12:00

0 Answers0