如何使用Morphia将字符串反序列化为日期

huangapple go评论75阅读模式
英文:

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 = &quot;yyyy-MM-dd&#39;T&#39;HH:mm:ss&#39;Z&#39;&quot;;

    private final SimpleDateFormat simpleDateFormat;

    public DateConverter() {
        super(Date.class);
        this.simpleDateFormat = new SimpleDateFormat(FORMAT);
    }

    @Override
    public Object decode(Class&lt;?&gt; 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(&quot;Documents&quot;)
@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 &quot;Document{&quot; +
	    &quot;id=&quot; + id +
	    &quot;, date=&quot; + date +
	    &#39;}&#39;;
    }

}

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.

huangapple
  • 本文由 发表于 2020年8月6日 21:59:46
  • 转载请务必保留本文链接:https://go.coder-hub.com/63285212.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定