Java Mongodb IsoDate和在microservices上修改if的问题
当我使用spring数据在MongoDB上插入文档时,我会执行以下操作:Java Mongodb IsoDate和在microservices上修改if的问题,java,mongodb,microservices,Java,Mongodb,Microservices,当我使用spring数据在MongoDB上插入文档时,我会执行以下操作: Update update = new Update(); update.currentDate("lastModified"); mongoTemplate.upsert(query, update, MyDocument.class); { "id" : 123, "lastModified" : { "$gt" : { $java : 2016-12-02T12:11:39.000Z } } } 我使用的是Mon
Update update = new Update();
update.currentDate("lastModified");
mongoTemplate.upsert(query, update, MyDocument.class);
{ "id" : 123, "lastModified" : { "$gt" : { $java : 2016-12-02T12:11:39.000Z } } }
我使用的是MongoDB的currentDate,因为我想用MongoDB数据库所在的日期保存上次修改MyDocument的日期
根据:
If Modified Since request header字段与用于
使其有条件:如果未修改请求的变量
由于在此字段中指定的时间,实体将不会被删除
从服务器返回;相反,将使用304(未修改)响应
返回时没有任何消息体
因此,保存此日期的目的是验证MyDocument是否根据接收日期进行了修改
因此,当我执行更新时,将在数据库上创建以下IsoDate:
ISODate("2016-12-02T12:11:33.083Z")
Query query = new Query(where("id").is(filter.getId()));
Criteria criteria = Criteria.where("lastModified").gt(filter.getLastModified());
query.addCriteria(criteria);
return mongoTemplate.findOne(query, MyDocument.class);
因此,当客户想知道文档是否已更改时,他们会将此日期发回给我,我会查询数据库:
ISODate("2016-12-02T12:11:33.083Z")
Query query = new Query(where("id").is(filter.getId()));
Criteria criteria = Criteria.where("lastModified").gt(filter.getLastModified());
query.addCriteria(criteria);
return mongoTemplate.findOne(query, MyDocument.class);
除了一个问题外,这工作得非常好:规范中说,如果修改,则标题的格式如下:
如果修改自:Sat,1994年10月29日19:43:31 GMT
这意味着不会在if-modified-since头上传递毫秒。但是,MongoDB IsoDate以毫秒为单位保存当前日期。因此,当两个日期完全相同时,查询将不会返回304 not Modified,而是返回整个资源,因为查询将如下所示:
Update update = new Update();
update.currentDate("lastModified");
mongoTemplate.upsert(query, update, MyDocument.class);
{ "id" : 123, "lastModified" : { "$gt" : { $java : 2016-12-02T12:11:39.000Z } } }
由于客户端不发送毫秒,java将毫秒设为零(2016-12-02T12:11:39.000Z),这意味着
我的数据库上的日期大于我的客户端发送的日期:
2016-12-02T12:11:33.083Z>2016-12-02T12:11:39.000Z
因为83毫秒
最后一个问题是:解决此问题的正确方法是什么,并且如果修改,则按照规范的建议正确工作?您可以在比较前将上次修改的日期毫秒设置为最大毫秒,这将从技术上否定毫秒偏移量
public static Date setMaxMillis(Date day,Calendar cal) {
cal.setTime(day);
cal.set(Calendar.MILLISECOND, cal.getMaximum(Calendar.MILLISECOND));
return cal.getTime();
}
Query query = new Query(where("id").is(filter.getId()));
Criteria criteria = Criteria.where("lastModified").gt(setMaxMillis(filter.getLastModified(),Calendar.getInstance()));
query.addCriteria(criteria);
return mongoTemplate.findOne(query, MyDocument.class);
我很确定规范中提到的日期格式只是一个例子。您可以更改if modified since的日期格式,以符合服务器的预期。这是如何产生的?我的意思是哪个库正在为您执行此操作。浏览器的标题不接受毫秒。因此,规范不仅仅是一个例子。它应该是这样的。这解决了问题。但是,这是解决问题的正确方法吗?或者,没有正确的模式来解决这个问题?我认为这是一个解决办法,但您正在处理两个不同的日期条目,一个是带毫秒的,另一个是不带毫秒的。这个答案是为了解决我们如何在它们之间架起桥梁的问题。正确的解决方案是让它们具有相同的日期和时间组件。