# gson Propleme bei Stringproperty



## 4a61766120617274697374 (31. Jul 2016)

Hallo zusammen

Sobald ich ein Object das ein Stringproperty als Eigenschaft besitzt in ein JSON wandeln möchte, wirft mir der Compiler eine Exception. Wenn ich hingegen mit dem Datentyp String arbeite funktioniert alles. Hatte schon jemand mal so ein Problem?

Ändert man im untenstehenden Code das Property String zu StringProperty, so funktioniert es nicht mehr.

Anbei ein example code:


```
public class JsonReaderAndWriter
{

  public static void main(String[] args) {

    Gson gson = new Gson();
    List<Person> persons = new ArrayList<>();
    persons.add(new Person(1, "firstname 1", "lastname 1"));
    persons.add(new Person(2, "firstname 2", "lastname 2"));

    String json = gson.toJson(persons);
    System.out.println("exported json:\n" + json + "\n\n");

    Type type = new TypeToken<List<Person>>() {}.getType();
    List<Person> readedData = gson.fromJson(json, type);
    System.out.println("imported json: ");
    System.out.println(readedData);
  }

}

class Person
{
  private long id;
  private String firstName;
  private String lastName;
//  private StringProperty firstName;
//  private StringProperty lastName;


  Person(long id, String firstName, String lastName) {
    this.id = id;
    this.firstName = firstName;
    this.lastName = lastName;
//    this.firstName = new SimpleStringProperty(firstName);
//    this.lastName = new SimpleStringProperty(lastName);
  }

  @Override
  public String toString() {
    return "(id = " + id + ", firstName = " + firstName + ", lastName = " + lastName + ")";
  }
}
```


----------



## JCODA (31. Jul 2016)

1. Du erwähnst, dass da irgendwo ne Exception fliegt. Ich verlange ja meistens echt nicht viel, aber du hättest uns sagen können welche.
2. Warum postest du Quellcode ohne Imports? Ich mein ... warum ... na gut, kein Problem...
Ich hab mir Gson gerade runtergeladen und erhalte mit der StringProperty folgende Exception:


> Exception in thread "main" java.lang.RuntimeException: Failed to invoke public javafx.beans.property.StringProperty() with no args



Die Fehlermeldung sagt eigentlich schon alles: Man benötigt einen parameterlosen Konstruktor, damit Gson "Out of the Box"- funktioniert.
Es gibt noch eine Art ... Gson damit vertraut zu machen, lese: https://sites.google.com/site/gson/gson-user-guide bei "*Writing an Instance Creator*"...

Andererseits ... *SimpleStringProperty* HAT einen parameterlosen Konstruktor! Leider ist aber* StringProperty* _abstract_, siehe: https://docs.oracle.com/javase/8/javafx/api/javafx/beans/property/StringProperty.html
D.h. hier lässt sich kein Objekt per parameterlosen Konstruktor erstellen.

Tja, deswegen ... könnte man noch die StringProperty zu einer SimpleStringProperty machen, etwa so klappt es bei mir:


```
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.List;

import javafx.beans.property.SimpleStringProperty;

import com.google.gson.*;
import com.google.gson.reflect.*;

public class JsonReaderAndWriter {

    public static void main(String[] args) {

        Gson gson = new Gson();
        List<Person> persons = new ArrayList<>();
        persons.add(new Person(1, "firstname 1", "lastname 1"));
        persons.add(new Person(2, "firstname 2", "lastname 2"));

        String json = gson.toJson(persons);
        System.out.println("exported json:\n" + json + "\n\n");

        Type type = new TypeToken<List<Person>>() {
        }.getType();
        List<Person> readedData = gson.fromJson(json, type);
        System.out.println("imported json: ");
        System.out.println(readedData);
    }

}

class Person {
    private long id;
    private SimpleStringProperty firstName;
    private SimpleStringProperty lastName;

    Person(long id, String firstName, String lastName) {
        this.id = id;
        this.firstName = new SimpleStringProperty(firstName);
        this.lastName = new SimpleStringProperty(lastName);
    }

    @Override
    public String toString() {
        return "(id = " + id + ", firstName = " + firstName + ", lastName = "
                + lastName + ")";
    }
}
```

Dies sind allerdings Dinge, die ich gerade erst vor 5 Minuten nachgelesen habe, falls jemand eine bessere Lösung hat, nur zu.


----------



## Flown (31. Jul 2016)

Nachdem wir aber ja gegen Interfaces implementieren, brauchen wir hier einen TypeAdapter, dann funktionierts auch mit `StringProperty`:

```
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.List;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonDeserializer;
import com.google.gson.JsonElement;
import com.google.gson.JsonParseException;
import com.google.gson.JsonPrimitive;
import com.google.gson.JsonSerializationContext;
import com.google.gson.JsonSerializer;
import com.google.gson.reflect.TypeToken;

import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;

public class Test {
  
  public static void main(String... args) {
    GsonBuilder gsonBuilder = new GsonBuilder();
    gsonBuilder.registerTypeAdapter(StringProperty.class, new StringPropertyAdapter());
    Gson gson = gsonBuilder.create();
    List<Person> persons = new ArrayList<>();
    persons.add(new Person(1, "firstname 1", "lastname 1"));
    persons.add(new Person(2, "firstname 2", "lastname 2"));
    
    String json = gson.toJson(persons);
    System.out.println("exported json:\n" + json + "\n\n");
    
    Type type = new TypeToken<List<Person>>() {
    }.getType();
    List<Person> readedData = gson.fromJson(json, type);
    System.out.println("imported json: ");
    System.out.println(readedData);
    
  }
}

final class StringPropertyAdapter implements JsonSerializer<StringProperty>, JsonDeserializer<StringProperty> {
  
  @Override
  public StringProperty deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
      throws JsonParseException {
    return new SimpleStringProperty(json.getAsJsonPrimitive().getAsString());
  }
  
  @Override
  public JsonElement serialize(StringProperty src, Type typeOfSrc, JsonSerializationContext context) {
    return new JsonPrimitive(src.getValue());
  }
}

class Person {
  private long id;
  private StringProperty firstName;
  private StringProperty lastName;
  
  Person(long id, String firstName, String lastName) {
    this.id = id;
    this.firstName = new SimpleStringProperty(firstName);
    this.lastName = new SimpleStringProperty(lastName);
  }
  
  @Override
  public String toString() {
    return "(id = " + id + ", firstName = " + firstName + ", lastName = " + lastName + ")";
  }
}
```


----------



## 4a61766120617274697374 (31. Jul 2016)

Super. Danke. Den Ansatz mit dem StringPropertyAdapter finde ich super. Den werde ich so verwenden. Danke euch beiden!


----------

