英文:
How to deserialize a String to a Date with Morphia
问题
{
"我有一个Mongo集合,其中包含以下格式的对象:": "I have a Mongo collection with objects of this format:",
"{\n    id: 1,\n    date: "2020-08-06T12:00:00Z",\n    ...\n}": "{\n    id: 1,\n    date: "2020-08-06T12:00:00Z",\n    ...\n}",
"我有Java代码需要从这个集合中读取,但从不写入它。写入此集合的进程不是由我拥有,因此我不能改变该日期字符串的格式。我最初尝试将我的Java Morphia对象建模如下:": "I have Java code that needs to read from this collection but never writes to it. The process that writes to this collection is not owned by me so I can't necessarily change the format of that date string. I initially tried to model my Java Morphia object like this:",
"@Entity public class MyDocument {\n    @Id\n    private Integer id;\n\n    private Date date; \n    ...\n}": "@Entity public class MyDocument {\n    @Id\n    private Integer id;\n\n    private Date date; \n    ...\n}",
"这不起作用,因为Morphia不知道如何将该日期格式反序列化为Date对象。我想到的解决方法是将日期视为POJO上的字符串,然后有一个执行实际反序列化的getDate()方法。我想知道,是否有更好的方法可以做到这一点?我知道如果您使用Jackson,可以使用@JsonDeserialize注解某些字段并传递反序列化程序,所以我想知道Morphia是否有类似的东西。": "This did not work because Morphia didn't know how to deserialize that date format into a Date object. The solution that I came up with was treating the date as a String on the POJO and then having a getDate() method that did the actual deserialization. I am wondering, is there a better way for me to do this? I know if you're using Jackson you can annotate certain fields with @JsonDeserialize and pass a deserializer so I was wondering if there was something similar for Morphia.",
"我的解决方案(对我来说感觉不太理想):": "My solution (which feels suboptimal to me):",
"@Entity public class MyDocument {\n    @Id\n    private Integer id;\n\n    private String date; \n    ...\n\n    private Date getDate() {\n        DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");\n        try {\n            return dateFormat.parse(date);\n        } catch (Exception ex) {\n            return null;\n        }\n    }\n}": "@Entity public class MyDocument {\n    @Id\n    private Integer id;\n\n    private String date; \n    ...\n\n    private Date getDate() {\n        DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");\n        try {\n            return dateFormat.parse(date);\n        } catch (Exception ex) {\n            return null;\n        }\n    }\n}"
}
英文:
I have a Mongo collection with objects of this format:
{
    id: 1,
    date: "2020-08-06T12:00:00Z",
    ...
}
I have Java code that needs to read from this collection but never writes to it. The process that writes to this collection is not owned by me so I can't necessarily change the format of that date string. I initially tried to model my Java Morphia object like this:
@Entity public class MyDocument {
    @Id
    private Integer id;
    private Date date; 
    ...
}
This did not work because Morphia didn't know how to deserialize that date format into a Date object. The solution that I came up with was treating the date as a String on the POJO and then having a getDate() method that did the actual deserialization. I am wondering, is there a better way for me to do this? I know if you're using Jackson you can annotate certain fields with @JsonDeserialize and pass a deserializer so I was wondering if there was something similar for Morphia.
My solution (which feels suboptimal to me):
@Entity public class MyDocument {
    @Id
    private Integer id;
    private String date; 
    ...
    private Date getDate() {
        DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
        try {
            return dateFormat.parse(date);
        } catch (Exception ex) {
            return null;
        }
    }
}
答案1
得分: 1
您可以继续创建一个简单的转换器,扩展TypeConverter,如下所示:
public class DateConverter extends TypeConverter {
    private static final String FORMAT = "yyyy-MM-dd'T'HH:mm:ss'Z'";
    private final SimpleDateFormat simpleDateFormat;
    public DateConverter() {
        super(Date.class);
        this.simpleDateFormat = new SimpleDateFormat(FORMAT);
    }
    @Override
    public Object decode(Class<?> targetClass, Object fromDBObject, MappedField optionalExtraInfo) {
        try {
            return simpleDateFormat.parse((String) fromDBObject);
        } catch (ParseException e) {
            return null;
        }
    }
}
然后,继续为您的文档实体注册格式化程序,如下所示:
@Entity("Documents")
@Converters(DateConverter.class)
public class Document {
    @Id
    private Integer id;
    public Integer getId() { return id; }
    public void setId(Integer id) { this.id = id; }
    private Date date;
    public Date getDate() { return date; }
    public void setDate(Date date) { this.date = date; }
    @Override
    public String toString() {
        return "Document{" +
            "id=" + id +
            ", date=" + date +
            '}';
    }
}
这将有效地告诉 Morphia 使用所需的模式解码数据库传入的值,直接生成一个具体的 Date 对象,而无需任何额外的转换逻辑。
英文:
You can go ahead and create a simple converter extending the TypeConverter like so:
public class DateConverter extends TypeConverter {
    private static final String FORMAT = "yyyy-MM-dd'T'HH:mm:ss'Z'";
    private final SimpleDateFormat simpleDateFormat;
    public DateConverter() {
        super(Date.class);
        this.simpleDateFormat = new SimpleDateFormat(FORMAT);
    }
    @Override
    public Object decode(Class<?> targetClass, Object fromDBObject, MappedField optionalExtraInfo) {
	    try {
	        return simpleDateFormat.parse(((String) fromDBObject));
	    } catch (ParseException e) {
	        return null;
	    }
    }
}
The go ahead and register your formatter for your document entity like so:
@Entity("Documents")
@Converters(DateConverter.class)
public class Document {
    @Id
    private Integer id;
    public Integer getId() { return id; }
    public void setId(Integer id) { this.id = id; }
    private Date date;
    public Date getDate() { return date; }
    public void setDate(Date date) { this.date = date; }
    @Override
    public String toString() {
	return "Document{" +
	    "id=" + id +
	    ", date=" + date +
	    '}';
    }
}
This will effectively tell Morphia to decode the database incoming values via parsing the string with the desired pattern, resulting directly into a concrete Date object without any additional conversion logic.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论