当前位置: 首页 > 知识库问答 >
问题:

在jackson与Jongo和MongoDB的反序列化中,将ObjectId_id重命名为id

龚同
2023-03-14

我刚刚开始使用play框架jongo和MongoDB开发一个项目。该项目最初是在Play 2.1中使用POJO编写的,POJO带有一个字符串id字段,该字段用@id和@ObjectId注释。这将作为ObjectId保存到Mongo,反序列化时将id输出为:“id”:“53fcb9ede4b0b18314098d10”例如。

由于升级到Jongo 1.1和Play 2.3.3,反序列化时id属性始终命名为“_id”,我希望属性保留字段名,但我不能像Jongo@id注释在幕后使用@JsonProperty(“自定义_名称”)。

import org.jongo.marshall.jackson.oid.Id;
import org.jongo.marshall.jackson.oid.ObjectId;

public class PretendPojo {

    @Id
    @ObjectId
    private String id;

    private String name;

    public PretendPojo() {
    }

    public PretendPojo(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }
}

如果我通过RoboMongo查看,在MongoDB中持久化的POJO看起来像这样

{
    "_id" : ObjectId("53fc984de4b0c34f1905b8ee"),
    "name" : "Owen"
}

然而,当我对它们进行反序列化时,如果保留这两个注释,我会得到以下json:

{"name":"Owen","_id":{"time":1409072858000,"date":1409072858000,"timestamp":1409072858,"new":false,"timeSecond":1409072858,"inc":308487737,"machine":-458223042}}

如果我只使用@Id注释,则会显示以下输出。

{"name":"Owen","_id":"53fcbedae4b0123e12632639"}

我有一个与上面的Pojo show合作的测试用例:

   @Test
    public void testJongoIdDeserialization() throws UnknownHostException {
        DB database = new MongoClient("localhost", 27017).getDB("jongo");
        Jongo jongo = new Jongo(database);
        MongoCollection collection = jongo.getCollection("jongo");
        collection.save(new PretendPojo("Owen"));
        PretendPojo pretendPojo = collection.findOne("{name:   \"Owen\"}").as(PretendPojo.class);
        JsonNode json = Json.toJson(pretendPojo);
        assertNotNull(json.get("id"));
    }

当尝试使用自定义反序列化程序时,我永远无法获得对象ID,我似乎只能访问当前正在反序列化的日期/时间/时间戳数据。

理想情况下,我正在寻找的输出将是:

  {"name":"Owen","id":"53fcbedae4b0123e12632639"}

任何帮助都将不胜感激!:)

共有3个答案

漆雕恺
2023-03-14

您可以尝试使用@JsonValue,Jongo似乎没有使用它们,但是如果没有开发人员的任何响应,这种行为可能会在未来的版本中发生变化。

@JsonValue
public Map<String, Object> getJson() {
    Map<String, Object> map = new HashMap<>();
    map.put("name", name);
    map.put("id", id);
    return map;
}

更合适的解决方案是尝试将@JsonView@Id注释相结合
记住指定在Jongo的ObjectMapper和您的Jackson ObjectMapper(我想是在REST层中使用的)上使用哪个视图

@Id
@JsonView(Views.DatabaseView.class)
private String id;

@JsonView(Views.PublicView.class)
public String getId() {
    return id;
}
宣星光
2023-03-14

我认为jackson中有一个注释允许您更改属性名称,我认为是:@JsonProperty,但您可以在这个链接中看到所有可能的注释:

https://github.com/FasterXML/jackson-annotations/wiki/Jackson-Annotations

我希望这能解决你的问题

薛楷
2023-03-14

ObjectdSerializer总是将使用@ObjectId映射的属性写入ObjectId的新实例。将此属性映射到字符串时,这是错误的。

为了避免这种行为,我写了一个NoObjectdSerializer:

public class NoObjectIdSerializer extends JsonSerializer<String> {
    @Override
    public void serialize(String value, JsonGenerator jgen, SerializerProvider provider) throws IOException, JsonProcessingException {
        jgen.writeString(value);
    }
}

用法如下:

@ObjectId
@JsonSerialize(using = NoObjectIdSerializer.class)
protected final String _id;

有一个悬而未决的问题。

 类似资料:
  • 为那些像我一样被困的人找到了解决问题的办法!:为了处理用于jackson反序列化的第三方java或scala对象,您可以使用mixin(但需要重新配置jackson映射器或用户模块),也可以简单地创建一个名为MyClassDeserializer的类,该类扩展JsonDeserializer并使用@JsonDeserialize(使用=MyClassDeserializer.class)注释。 例

  • 我有一个JSON字符串,它将空列表标记为而不是。因此,例如,如果我有一个没有子对象的对象,我将收到这样的字符串: 我想将其反序列化为父类,将子类正确设置为子类的空列表。 对于上面的JSON字符串,我想要一个将其id设置为13的对象,并将子元素设置为新的ArrayList 我知道如何为整个类使用注释 然后呢 但是,我想解决从字符串正确实例化列表的一般问题: 我能得到这样的东西吗?

  • 问题内容: 考虑以下枚举和类: 并考虑以下主要功能: 当前,该主输出为: 这种输出并不适合我,因为除了字符串的,我想它是,这是序号值在枚举。 所以我想要得到的实际结果是: 有一些优雅的方法可以使其表现为这种方式吗? 问题答案: 它应该通过指定映射器来工作。 如注解的Javadoc所述,这也适用于反序列化: 注意:当用于Java枚举时,一个附加功能是带注释的方法返回的值也被视为要反序列化的值,而不仅

  • 我有一个POJO类,它将从JSON反序列化,JSON在Spring中作为请求体出现。此POJO类包含列表 我的JSON对象如下所示 下面是示例方法调用 我遵循了给出的建议,下面给出了反序列化程序代码

  • 作为我的应用程序的输入,我可能会得到一个JsonObject或它们的列表: 我可以使用作为两个输入的目标类型 然后评估根节点是阵列节点还是对象节点。 我寻求一种方法来定义我的自定义目标类型,例如

  • 问题内容: 使用Jackson 2,我正在寻找一种 通用的 方式将对象序列化为单个值(然后序列化它们,然后再填充该单个字段),而不必重复创建JsonSerializer / JsonDeserializer来处理每种情况。@JsonIdentityInfo批注非常接近,但由于我知道,它将始终对完整的子对象进行序列化,因此略微遗漏了该标记。 这是我想做的一个例子。给定的类: 我希望Order可以序列