2017-12-19 2 views
1

検索APIのJSON結果を逆シリアル化しようとしています。検索API(およびここでは簡略化しました)には、検索に関するメタデータを持つメインオブジェクトがあり、検索されたオブジェクトが何であれリストがあります。私は一般的なオブジェクトのリストを使用してこれを達成しようとしていますジェネリックオブジェクトのリストを含むPOJOにスプリングブートを使用してJSONを非直列化する

私はこれらのクラスをテストしていません。

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(物事を読みやすくするために)

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

エンドポイント/テストを呼び出した後/ testserialize私のアプリケーションはこのエラー

java.lang.ClassCastExceptionがスロー:java.util.LinkedHashMapはできませんが

:私は戻って、にTestSearchクラスを更新した場合、今

をcom.testapp.entity.TestResultする をキャストします

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; 
    } 
} 

私は私が期待していた結果を得る:

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

このチュートリアルを試しましたか? http://blog.bdoughan.com/2012/11/creating-generic-list-wrapper-in-jaxb.html –

+0

@Rohan私はこれをまだ見ていませんが、JaxBとXML私はJacksonとJSONを探しています。@ XmlAnyElementに匹敵するものを探すのは良い出発点かもしれません。 – AKrush95

答えて

1

あなたが使用する各ジェネリック型のためTypeReferenceオブジェクトを作成し、逆シリアル化のためにそれを使用する必要があります。たとえば、あなたが

public List<T> getResults() 

の型の参照を作成する必要がありますあなたの場合は

  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>>(){}); 

は、あなたがそれに追加の助けを必要とする場合は私に知らせてください。

+0

ありがとう、私は実際には、RestTemplate交換メソッドの内部でParameterizedTypeReferenceを使って考え出しました – AKrush95

1

getForObject機能の内部のgetClass()メソッドParameterizedTypeReference

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

を使用して、この問題を解決するにはタイプ

を見ていないに私は最終的に6歳であることを起こるソリューションを突き止め: Generics with Spring RESTTemplate

関連する問題