8

リストをルートノードとして含めようとしているときに問題が発生していますが、これを取得できないようです。説明させてください。クラス「TestClass」があるとしましょう

class TestClass{
    String propertyA;       
}

さて、いくつかのユーティリティメソッドでは、これが私がしていることです

String utilityMethod(){
   List<TestClass> list = someService.getList();
   new ObjectMapper().writeValueAsString(list); 
}

JSONで取得しようとしている出力は

{"ListOfTestClasses":[{"propertyA":"propertyAValue"},{"propertyA":"someOtherPropertyValue"}]}

私は使用しようとしました

objMapper.getSerializationConfig().set(Feature.WRAP_ROOT_VALUE, true);

しかし、私はまだそれを正しく理解していないようです。

今、私は Map < String,TestClass > を作成しているだけで、私がやろうとしていることを達成するためにそれを書いていますが、これは明らかにハックです。誰かがよりエレガントなソリューションを手伝ってくれませんか? ありがとう

4

2 に答える 2

18

残念ながら、このWRAP_ROOT_VALUE機能を有効にしても、Java コレクションをシリアライズするときに生成されるルート名を制御する追加のロジックが必要です (理由の詳細については、この回答を参照してください)。次のオプションがあります。

  • ホルダー クラスを使用してルート名を定義する
  • 地図を使って。
  • カスタムを使用してObjectWriter

3 つの異なるオプションを示すコードを次に示します。

public class TestClass {
    private String propertyA;

    // constructor/getters/setters
}

public class TestClassListHolder {

    @JsonProperty("ListOfTestClasses")
    private List<TestClass> data;

    // constructor/getters/setters
}

public class TestHarness {

    protected List<TestClass> getTestList() {
        return Arrays.asList(new TestClass("propertyAValue"), new TestClass(
                "someOtherPropertyValue"));
    }

    @Test
    public void testSerializeTestClassListDirectly() throws Exception {
        final ObjectMapper mapper = new ObjectMapper();
        mapper.configure(SerializationFeature.WRAP_ROOT_VALUE, true);
        System.out.println(mapper.writeValueAsString(getTestList()));
    }

    @Test
    public void testSerializeTestClassListViaMap() throws Exception {
        final ObjectMapper mapper = new ObjectMapper();
        final Map<String, List<TestClass>> dataMap = new HashMap<String, List<TestClass>>(
                4);
        dataMap.put("ListOfTestClasses", getTestList());
        System.out.println(mapper.writeValueAsString(dataMap));
    }

    @Test
    public void testSerializeTestClassListViaHolder() throws Exception {
        final ObjectMapper mapper = new ObjectMapper();
        final TestClassListHolder holder = new TestClassListHolder();
        holder.setData(getTestList());
        System.out.println(mapper.writeValueAsString(holder));
    }

    @Test
    public void testSerializeTestClassListViaWriter() throws Exception {
        final ObjectMapper mapper = new ObjectMapper();
        final ObjectWriter writer = mapper.writer().withRootName(
                "ListOfTestClasses");
        System.out.println(writer.writeValueAsString(getTestList()));
    }
}

出力:

{"ArrayList":[{"propertyA":"propertyAValue"},{"propertyA":"someOtherPropertyValue"}]}
{"ListOfTestClasses":[{"propertyA":"propertyAValue"},{"propertyA":"someOtherPropertyValue"} "}]}
{"ListOfTestClasses":[{"propertyA":"propertyAValue"},{"propertyA":"someOtherPropertyValue"}]}
{"ListOfTestClasses":[{"propertyA":"propertyAValue"},{"propertyA ":"someOtherPropertyValue"}]}

を使用するObjectWriterと非常に便利です。これを使用してシリアル化されたすべての最上位オブジェクトが同じルート名を持つことに注意してください。それが望ましくない場合は、代わりにマップまたはホルダー クラスを使用してください。

于 2013-04-15T19:27:39.430 に答える
1

基本的な考え方は次のようなものになると思います。

class UtilityClass {
    List listOfTestClasses;
    UtilityClass(List tests) {
        this.listOfTestClasses = tests;
    }
}

String utilityMethod(){
    List<TestClass> list = someService.getList();
    UtilityClass wrapper = new UtilityClass(list);
    new ObjectMapper().writeValueAsString(wrapper); 
}
于 2013-04-15T19:06:53.603 に答える