使用Jongo和MongoDB在Jackson反序列化中将ObjectId _id重命名为id

我刚刚开始使用play框架,jongo和MongoDB开发项目。 该项目最初是在Play 2.1中用pojos编写的,其字符串ID字段用以下两个注释:@Id和@ObjectId这将作为ObjectId持久保存到Mongo,并且当反序列化时将id输出为:“id”:“53fcb9ede4b0b18314098d10”例如。

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

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

我有一个测试用例,用于处理上面的PretendPojo节目:

  @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"} 

任何帮助将不胜感激! 🙂

ObjectIdSerializer始终将使用@ObjectId映射的属性写入ObjectId的新实例。 将此属性映射到String时,这是错误的。

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

 public class NoObjectIdSerializer extends JsonSerializer { @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中有一个注释允许你更改属性名称,我认为是:@JsonProperty但你可以在这个链接中看到所有可能的注释:

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

我希望这能解决你的问题

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

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

更合适的解决方案是尝试将@JsonView@Id注释相结合
记得指定在Jongo的ObjectMapper和你的Jackson ObjectMapper上使用哪个View(在REST层中使用的那个,我猜)

 @Id @JsonView(Views.DatabaseView.class) private String id; @JsonView(Views.PublicView.class) public String getId() { return id; } 

自1.1以来,Jongo的行为发生了变化,以便更加一致地处理其拥有的注释。

如果你的’_id’是一个字符串,你希望这个字段作为字符串存储到Mongo中,那么只需要@Id。

String属性上的@Id + @ObjectId表示:

“我的名为’foo’的String属性是一个有效的ObjectId。此属性必须以名称’_id’存储,并且必须作为ObjectId处理。”