22

私は次のクラスを持っています:

public class Message {
    private String text;

    public String getText() {
        return text;
    }

    public void setText(String text) {
        this.text = text;
    }    
}

デフォルトでJacksonを使用してインスタンスをJSONに変換すると、次のようになります。

{"text":"Text"}

取得したい:

{"message":{"text":"Text"}}

目標を達成するために使用できるJAXB/Jacksonアノテーションはありますか?

回避策として、クラスを別のクラスでラップできます。

public class MessageWrapper {
    private Message message;

    public Message getMessage() {
        return message;
    }

    public void setMessage(Message message) {
        this.message = message;
    }
}

またはより一般的な解決策:

public class JsonObjectWrapper<T> {
    /**
     * Using a real map to allow wrapping multiple objects
     */
    private Map<String, T> wrappedObjects = new HashMap<String, T>();

    public JsonObjectWrapper() {
    }

    public JsonObjectWrapper(String name, T wrappedObject) {
        this.wrappedObjects.put(name, wrappedObject);
    }

    @JsonAnyGetter
    public Map<String, T> any() {
        return wrappedObjects;
    }

    @JsonAnySetter
    public void set(String name, T value) {
        wrappedObjects.put(name, value);
    }
}

これは次のように使用できます。

Message message = new Message();
message.setText("Text");
JsonObjectWrapper<Message> wrapper = new JsonObjectWrapper<Message>("message", message);

目標を達成するために使用できるJAXB/Jacksonアノテーションはありますか?

ありがとう。

4

7 に答える 7

24

Jackson 2.xを使用すると、以下を使用して、ObjectMapperに追加プロパティを追加せずにラッパーを有効にできます。

import com.fasterxml.jackson.annotation.JsonTypeInfo;
import com.fasterxml.jackson.annotation.JsonTypeName;

@JsonTypeInfo(include = JsonTypeInfo.As.WRAPPER_OBJECT, use = JsonTypeInfo.Id.NAME)
@JsonTypeName(value = "student")
public class Student {
  private String name;
  private String id;
}
于 2019-03-03T09:04:19.113 に答える
15

回避策:これらのゲッター/セッターは絶対に必要ではないので、次のようにすることができます。

public class MessageWrapper {
  public Message message;
}

または、便利なコンストラクターを追加します。

public class MessageWrapper {
  public Message message;
  @JsonCreator
  public MessageWrapper(@JsonProperty("message") Message m) { 
       message = m; 
  }
}

ラッピングを追加する方法もあります。SerializationConfig.Feature.WRAP_ROOT_ELEMENT1.9では、とを使用できますDeserializationConfig.Feature.UNWRAP_ROOT_ELEMENT@JsonRootNameまた、ラッパー名を変更する場合(デフォルトでは、修飾されていないクラス名です)、アノテーションを使用できます。

Jackson 2.0は、JAX-RSアノテーションだけでなく、ObjectReaderおよびを介してさらに動的なオプションを追加します。ObjectWriter

于 2012-05-30T01:54:28.340 に答える
4

ラベル付けされたオブジェクトでクラスをラップするという単純な目標のために、カスタムシリアル化を作成する必要があることを知ったのは悲しいことでした。カスタムシリアライザーを作成して遊んだ後、最も簡単な解決策は汎用ラッパーであると結論付けました。上記の例のより単純な実装は、おそらく次のとおりです。

public final class JsonObjectWrapper {
    private JsonObjectWrapper() {}

    public static <E> Map<String, E> withLabel(String label, E wrappedObject) {
        HashMap<String, E> map = new HashMap<String, E>();
        map.put(label, wrappedObject);
        return map;
    }
}
于 2014-01-22T16:42:48.860 に答える
3

jsonに大文字mが含まれていてもかまわない場合message、これを行う最も簡単な方法は、クラスに。で注釈を付けること@JsonTypeInfoです。

追加します:

@JsonTypeInfo(include=As.WRAPPER_OBJECT, use=Id.NAME)
public class Message {
  // ...
}

取得するため{"Message":{"text":"Text"}}

于 2017-01-06T13:59:54.750 に答える
1

それを行うためのより簡単でより良い方法:

@JsonRootName(value = "message")
public class Message { ...}

次に使用します
new ObjectMapper().configure(SerializationFeature.WRAP_ROOT_VALUE, true).writeValueAs...

于 2016-08-17T20:52:06.703 に答える
1

スプリングを使用している場合は、application.propertiesファイルに以下を追加します。-

spring.jackson.serialization.WRAP_ROOT_VALUE = true

次に@JsonRootName、シリアル化するクラスのいずれかにアノテーションを使用します。例えば

@JsonRootName("user")
public class User {
    private String name;
    private Integer age;
}
于 2018-02-03T15:36:02.150 に答える
0

問題を解決する@JsonWrappedアノテーションを含む小さなjacksonモジュールを作成しました。コードについてはこちらをご覧ください:https ://github.com/mwerlitz/jackson-wrapped

その場合、クラスは次のようになります。

public class Message {
    @JsonWrapped("message")
    private String text;
}
于 2020-06-21T12:29:59.160 に答える