2017-12-19 1 views
1

Ich versuche, ein JSON-Ergebnis einer Such-API zu deserialisieren. Die Such-API (und ich habe es hier vereinfacht) hat ein Hauptobjekt mit Metadaten über die Suche und hat dann eine Liste von dem, was das gesuchte Objekt ist. Ich versuche, dies zu erreichen mit einer Liste von generischen ObjektenDeserialisieren von JSON mit Springboot in ein POJO mit einer Liste von generischen Objekten

Ich habe diese Klassen ohne getestet und alles funktioniert genau so, wie ich es wollen würde.

TestSearch.java

public class TestSearch<T> { 

    private String count; 
    private List<T> results; 

    public String getCount() { 
     return count; 
    } 

    public void setCount(String count) { 
     this.count = count; 
    } 

    public List<T> getResults() { 
     return results; 
    } 

    public void setResults(List<T> results) { 
     this.results = results; 
    } 
} 

TestResult.java

public class TestResult { 

    private String name; 
    private String description; 

    public String getName() { 
     return name; 
    } 

    public void setName(String name) { 
     this.name = name; 
    } 

    public String getDescription() { 
     return description; 
    } 

    public void setDescription(String description) { 
     this.description = description; 
    } 
} 

TestController.java

@RequestMapping("/test/json") 
public String testGetJson() { 
    return "{\"count\":3,\"results\":[{\"name\":\"result 1\",\"description\":\"this is the first result\",\"extra\":\"property\"},{\"name\":\"result 2\",\"description\":\"tqbf\"},{\"name\":\"result 3\",\"description\":\"jotlz\"}]}"; 
} 

@RequestMapping("/test/testserialize") 
public List<TestResult> testSerialize() { 
    TestSearch<TestResult> testSearch = new RestTemplate().getForObject("http://localhost:8957/test/json", new TestSearch<TestResult>().getClass()); 

    List<TestResult> results = testSearch.getResults(); 

    results.forEach(result -> { 
     result.setName("new value"); 
    }); 

    return results; 
} 

JSON (nur um die Dinge besser lesbar)

{ 
    "count": 3, 
    "results": [ 
     { 
      "name": "result 1", 
      "description": "this is the first result", 
      "extra": "property" 
     }, 
     { 
      "name": "result 2", 
      "description": "tqbf" 
     }, 
     { 
      "name": "result 3", 
      "description": "jotlz" 
     } 
    ] 
} 

Nach dem Aufruf der Endpunkt/test/testserialize meine Anwendung wirft diesem Fehler

java.lang.ClassCastException: java.util.LinkedHashMap kann nicht gegossen werden

Jetzt com.testapp.entity.TestResult, wenn ich gehe zurück und aktualisieren Sie die TestSearch Klasse:

public class TestSearch { 

    private String count; 
    private List<TestResult> results; 

    public String getCount() { 
     return count; 
    } 

    public void setCount(String count) { 
     this.count = count; 
    } 

    public List<TestResult> getResults() { 
     return results; 
    } 

    public void setResults(List<TestResult> results) { 
     this.results = results; 
    } 
} 

ich die Ergebnisse erwarte ich:

[ 
    { 
     "name": "new value", 
     "description": "this is the first result" 
    }, 
    { 
     "name": "new value", 
     "description": "tqbf" 
    }, 
    { 
     "name": "new value", 
     "description": "jotlz" 
    } 
] 
+0

Sie haben dieses Tutorial ausprobiert ?? http://blog.bdoughan.com/2012/11/creating-generic-list-wrapper-in-jaxb.html –

+0

@Rohan Ich habe dieses noch nicht gesehen, aber ich stelle fest, dass es für JaxB und XML ist wenn ich nach Jackson und JSON suche.Es könnte ein guter Startpunkt sein, um in ein Äquivalent zu @ XmlAnyElement zu schauen, danke – AKrush95

Antwort

1

Sie benötigen ein TypeReference Objekt für jede generische Art zu schaffen, die Sie verwenden, und dass für die Deserialisierung verwenden. Zum Beispiel

  ObjectMapper mapper = new ObjectMapper(); 

      Map<String, Object> map = new HashMap<String, Object>(); 

      // convert JSON string to Map 
      map = mapper.readValue(json, new TypeReference<Map<String, String>>(){}); 

In Ihrem Fall haben Sie die Typenbezeichnung für

public List<T> getResults() 

Bitte lassen Sie mich schaffen müssen wissen, ob Sie in ihnen zusätzliche Hilfe benötigen.

+0

Danke, ich habe es gerade herausgefunden, indem ich eine ParameterizedTypeReference innerhalb der RestTemplate-Austauschmethode verwendet habe – AKrush95

1

Die getClass() -Methode innerhalb der getForObject Funktion sehen nicht die Art

Um dies zu lösen, ist ein ParameterizedTypeReference verwenden

TestSearch<TestResult> testSearch = new RestTemplate().exchange(
      "http://localhost:8957/test/json", 
      HttpMethod.GET, 
      null, 
      new ParameterizedTypeReference<TestSearch<TestResult>>() {}).getBody(); 

ich eine Lösung schließlich aufgespürt, die 6 Jahre alt sein geschieht : Generics with Spring RESTTemplate

Verwandte Themen