java 强制杰克逊使用注释添加额外的包装

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/10795232/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-31 02:36:08  来源:igfitidea点击:

Force Hymanson to add addional wrapping using annotations

javaHymanson

提问by MosheElisha

I have the following class:

我有以下课程:

public class Message {
    private String text;

    public String getText() {
        return text;
    }

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

When converting the instance to JSON using Hymanson by default I get:

默认情况下,当使用 Hymanson 将实例转换为 JSON 时,我得到:

{"text":"Text"}

I would like to get:

我想得到:

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

Is there any JAXB / Hymanson annotation I can use to achieve my goal?

我可以使用任何 JAXB/Hymanson 注释来实现我的目标吗?

As a workaround, I can wrap my class with another class:

作为一种解决方法,我可以用另一个类来包装我的类:

public class MessageWrapper {
    private Message message;

    public Message getMessage() {
        return message;
    }

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

or a more generic solution:

或更通用的解决方案:

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

Which can be used like so:

可以这样使用:

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

Is there any JAXB / Hymanson annotation I can use to achieve my goal?

我可以使用任何 JAXB/Hymanson 注释来实现我的目标吗?

Thanks.

谢谢。

采纳答案by StaxMan

On workaround: you don't absolutely need those getters/setters, so could just have:

解决方法:您并不绝对需要这些 getter/setter,所以可以只需要:

public class MessageWrapper {
  public Message message;
}

or perhaps add convenience constructor:

或者添加便利构造函数:

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

There is a way to add wrapping too; with 1.9 you can use SerializationConfig.Feature.WRAP_ROOT_ELEMENTand DeserializationConfig.Feature.UNWRAP_ROOT_ELEMENT. And if you want to change the wrapper name (by default it is simply unqualified class name), you can use @JsonRootNameannotation

还有一种方法可以添加包装;在 1.9 中,您可以使用SerializationConfig.Feature.WRAP_ROOT_ELEMENTDeserializationConfig.Feature.UNWRAP_ROOT_ELEMENT。如果您想更改包装器名称(默认情况下它只是不合格的类名),您可以使用@JsonRootName注释

Hymanson 2.0 adds further dynamic options via ObjectReaderand ObjectWriter, as well as JAX-RS annotations.

Hymanson 2.0 通过ObjectReaderObjectWriter以及 JAX-RS 注释添加了更多动态选项。

回答by Raunaque Srivastava

With Hymanson 2.x use can use the following to enable wrapper without adding addition properties in the ObjectMapper

使用 Hymanson 2.x 可以使用以下内容启用包装器,而无需在 ObjectMapper 中添加附加属性

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

@JsonTypeInfo(include = JsonTypeInfo.As.WRAPPER_OBJECT, use = JsonTypeInfo.Id.NAME)
@JsonTypeName(value = "student")
public class Student {
  private String name;
  private String id;
}

回答by Sam Berry

It was sad to learn that you must write custom serialization for the simple goal of wrapping a class with a labeled object. After playing around with writing a custom serializer, I concluded that the simplest solution is a generic wrapper. Here's perhaps a more simple implementation of your example above:

遗憾的是,您必须编写自定义序列化来实现用标记对象包装类的简单目标。在尝试编写自定义序列化程序后,我得出结论,最简单的解决方案是通用包装器。这可能是上面示例的更简单的实现:

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

回答by thelastshadow

Provided you don't mind the json having a capital min message, then the simplest way to do this is to annotate your class with @JsonTypeInfo.

只要你不介意资本的JSONmmessage,那么这样做是注释类最简单的方法@JsonTypeInfo

You would add:

你会补充:

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

to get {"Message":{"text":"Text"}}

要得到 {"Message":{"text":"Text"}}

回答by Vinay Prajapati

If using spring, then in application.propertiesfile add following:-

如果使用 spring,则在application.properties文件中添加以下内容:-

spring.Hymanson.serialization.WRAP_ROOT_VALUE=true

spring.Hymanson.serialization.WRAP_ROOT_VALUE=true

And then use @JsonRootNameannotation on any of your class that you wish to serialize. e.g.

然后@JsonRootName在您希望序列化的任何类上使用注释。例如

@JsonRootName("user")
public class User {
    private String name;
    private Integer age;
}

回答by Hazel Troost

A Simpler/Better way to do it:

一种更简单/更好的方法:

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

then use
new ObjectMapper().configure(SerializationFeature.WRAP_ROOT_VALUE, true).writeValueAs...

然后使用
new ObjectMapper().configure(SerializationFeature.WRAP_ROOT_VALUE, true).writeValueAs...