web-dev-qa-db-ja.com

Jacksonを使用したJSONシリアル化でルートキーの名前を変更する方法

オブジェクトのリストのJSONシリアル化にJacksonを使用しています。

ここに私が得るものがあります:

{"ArrayList":[{"id":1,"name":"test name"}]}

しかし、私はこれが欲しい:

{"rootname":[{"id":1,"name":"test name"}]} // ie showing the string I want as the root name.

これに対する私のアプローチは次のとおりです。

インタフェース:

public interface MyInterface {
    public long getId();
    public String getName();
}

実装クラス:

@JsonRootName(value = "rootname")
public class MyImpl implements MyInterface {
    private final long id;
    private String name;

    public MyImpl(final long id,final name) {
        this.id = id;
        this.name = name;
    }

   // getters     
}

JSonシリアル化:

public class MySerializer {
    public static String serializeList(final List<MyInterface> lists) {
        //check for null value.Throw Exception
        final ObjectMapper mapper = new ObjectMapper();
        mapper.configure(SerializationConfig.Feature.WRAP_ROOT_VALUE, true);
        return mapper.writeValueAsString(lists);
    }
}

テスト:

final List<MyInterface> list = new ArrayList<MyImpl>();
MyImpl item = new MyImpl(1L,"test name");
list.add(item);
final String json = MySerializer.serializeList(list);
System.out.println(json);

ここに私が得るものがあります:

{"ArrayList":[{"id":1,"name":"test name"}]}

しかし、私はこれが欲しい:

{"rootname":[{"id":1,"name":"test name"}]} // ie showing the string I want as the root     name.

提案された解決策をすべて試しましたが、目標を達成できませんでした。私が見た:

それとも何か不足していますか?このためにjackson 1.9.12を使用しています。この点で助けがあれば歓迎します。

26
user2266861

まあ、デフォルトでは、ジャクソンは、ラップされた値に表示されるルート名を決定しようとするときに、2つの注釈のいずれかを使用します- @XmlRootElement または @JsonRootName 。この注釈は、シリアル化される型にあると想定されています。そうでない場合は、型の 単純名 をルート名として使用します。

あなたの場合、リストをシリアル化しています。これが、ルート名が「ArrayList」(シリアル化される型の単純名)である理由です。リスト内の各要素は、@ JsonRootNameアノテーションが付けられたタイプでもかまいませんが、リスト自体はnot

ラップしようとしているルート値がコレクションの場合、ラップ名を定義する何らかの方法が必要です。

ホルダー/ラッパークラス

リストを保持するラッパークラスを作成し、目的のプロパティ名を定義する注釈を付けます(ObjectMapperを直接制御していない場合にのみ、このメソッドを使用する必要があります)/JSON変換プロセス):

class MyInterfaceList {
    @JsonProperty("rootname")
    private List<MyInterface> list;

    public List<MyInterface> getList() {
        return list;
    }

    public void setList(List<MyInterface> list) {
        this.list = list;
    }
}

final List<MyInterface> lists = new ArrayList<MyInterface>(4);
lists.add(new MyImpl(1L, "test name"));
MyInterfaceList listHolder = new MyInterfaceList();
listHolder.setList(lists);
final String json = mapper.writeValueAsString(listHolder);

オブジェクトライター

これは望ましいオプションです。設定済みの ObjectWriter インスタンスを使用してJSONを生成します。特に、 withRootName メソッドに興味があります。

final List<MyInterface> lists = new ArrayList<MyInterface>(4);
lists.add(new MyImpl(1L, "test name"));
final ObjectWriter writer = mapper.writer().withRootName("rootName");
final String json = writer.writeValueAsString(lists);
31
Perception

私は遅れていますが、ホルダー/ラッパークラスを必要としないより良いアプローチがあります。アノテーションからルートキーを選択します。

package com.test;

import com.fasterxml.jackson.annotation.JsonRootName;


@JsonRootName("Products")
public class ProductDTO {
    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;
    }
}

テストクラスは次のとおりです。

package com.test;

import Java.io.IOException;
import Java.util.ArrayList;

import org.junit.Test;

import com.fasterxml.jackson.annotation.JsonRootName;
import com.fasterxml.jackson.core.JsonGenerationException;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;


public class ProductDTOTestCase {
    @Test
    public void testPersistAndFindById() throws JsonGenerationException, JsonMappingException, IOException {
        ObjectMapper mapper = new ObjectMapper();
        ProductDTO productDTO = new ProductDTO();
        productDTO.setDescription("Product 4 - Test");

        ArrayList<ProductDTO> arrayList = new ArrayList<ProductDTO>();
        arrayList.add(productDTO);

        String rootName = ProductDTO.class.getAnnotation(JsonRootName.class).value();
        System.out.println(mapper.writer().withRootName(rootName).writeValueAsString(arrayList));

    }


}

次の出力が得られます

{"Products":[{"name":null,"description":"Product 4 - Test"}]}
7
Vaibhav
@JsonTypeName("usuarios")
@JsonTypeInfo(include= JsonTypeInfo.As.WRAPPER_OBJECT,use= JsonTypeInfo.Id.NAME)
public class UsuarioDT extends ArrayList<Usuario> {

    @JsonProperty("rowsAffected")
    private Integer afectados;

    public Integer getAfectados() {
        return afectados;
    }

    public void setAfectados(Integer afectados) {
        this.afectados = afectados;
    }
}
1

クラスの上部でこの注釈を使用する必要があります

@JsonTypeName("rootname")

0
ekv