使用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处理。”
- Spring REST,JSON“无法处理托管/后向引用’defaultReference’”415不支持的媒体类型
- jackson解析json与unwraping root,但没有能力设置@JsonRootName
- 使用Jackson XmlMapper对POJO进行XML反序列化
- 如何有效地将org.json.JSONObject映射到POJO?
- 将Jackson ObjectMapper类设置为不使用双重科学记数法
- Jackson 2.1多态反序列化:如何在pojo上填充类型字段?
- jackson:无法反序列化START_OBJECT令牌中的Number实例
- Spring 3使用Jackson将ArrayList序列化为JSON而不包装到对象(没有名称)
- 使用超大的json文件。 总是内存不足