2

我正在使用FasterXML将我的对象映射到 MongoDB

我想使用过期索引,但为此,我需要在文档中使用 ISODate 字段。

如果我的 java 类有一个 Date 字段,它会被数字或字符串序列化,使用DateSerializer如下所述:http ://wiki.fasterxml.com/JacksonFAQDateHandling

我追踪到这个功能:

/**
 * Method that will handle serialization of Date(-like) values, using
 * {@link SerializationConfig} settings to determine expected serialization
 * behavior.
 * Note: date here means "full" date, that is, date AND time, as per
 * Java convention (and not date-only values like in SQL)
 */
public final void defaultSerializeDateValue(Date date, JsonGenerator jgen)
    throws IOException, JsonProcessingException
{
    // [JACKSON-87]: Support both numeric timestamps and textual
    if (isEnabled(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS)) {
        jgen.writeNumber(date.getTime());
    } else {
        jgen.writeString(_dateFormat().format(date));
    }
}

这两条路径都没有最终编写标准的 mongodb 日期类型,因此我的索引不起作用。

有没有办法像从 mongo shell 创建文档时那样强制对 javaDate类型进行序列化?或者,我可以通过“触发器”或类似的方式自动添加该字段吗?(目的是完全绕过序列化器)

4

2 回答 2

3

我对新版本的 FasterXML 有完全相同的问题。(2.7.3)。FasterXML 现在有一个“编解码器”来处理对象,除了序列化器。我使用使编解码器无效的序列化程序解决了该问题,因此日期对象无需触摸即可到达 mongo 驱动程序。

private static class MongoDateSerializer extends JsonSerializer<Date> {

    public void serialize(Date value, JsonGenerator jgen, SerializerProvider provider) throws IOException {
        TokenBuffer buffer = (TokenBuffer) jgen;
        ObjectCodec codec = buffer.getCodec();
        buffer.setCodec(null);

        buffer.writeObject(value);

        buffer.setCodec(codec);
    }
}

看这条线buffer.writeObject(value),这就是旧版本的 FasterXML 的做法。

于 2016-06-09T14:13:29.433 回答
-1

您可以通过调用 setDateFormat() 使用自己的 DateFormat 初始化 ObjectMapper。

例如:

public static void main(String[] args) throws JsonGenerationException, JsonMappingException,
        IOException {
    ObjectMapper mapper = null;
    mapper = new ObjectMapper();
    SimpleDateFormat sdf = new SimpleDateFormat("yyyy~MM~dd");
    mapper.setDateFormat(sdf); // 1.8 and above
    //mapper.getSerializationConfig().setDateFormat(sdf); // for earlier versions (deprecated for 1.8+)
    Map<String, Date> data = new HashMap<>();
    data.put("Key", new Date());
    System.out.println(mapper.writeValueAsString(data));
}

注意:SimpleDateFormat 不是线程安全的。

或者您可以使用 JsonSerialize 注释 bean。

例如:

public static class User {

    private int id;

    private Date createTime;

    public int getId() {
        return id;
    }

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

    @JsonSerialize(using = DateJsonSerializer.class)
    public Date getCreateTime() {
        return createTime;
    }

    public void setCreateTime(Date createTime) {
        this.createTime = createTime;
    }
}

这是 DateJsonSerializer。

public class DateJsonSerializer extends JsonSerializer<Date> {

    @Override
    public void serialize(Date date, JsonGenerator jgen, SerializerProvider provider)
            throws IOException, JsonProcessingException {
        jgen.writeString("generate ISODate yourself");
    }
}
于 2013-08-22T08:35:11.843 回答