博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Java对MongoDB的ObjectId的序列化问题
阅读量:6989 次
发布时间:2019-06-27

本文共 3562 字,大约阅读时间需要 11 分钟。

MongoDB在不特殊指认的情况下,默认的集合主键是“_id”,类型是ObjectId。ObjectId是一个12字节的BSON类型字符串,包含了UNIX时间戳,机器识别码,进程号,计数值信息。机器码用来防止分布式系统生成id时冲突的问题,保证每台机器生成的识别码不同,进程号保证多线程情况下生成的id不同。

ObjectId在java程序中是对象类型,JavaBean中常这样使用:

@Document(collection = "c_userinfo")public class UserInfo{    @Id    private ObjectId id;    private String name;    // getter setter略}

此时,如果直接实体类序列化为json,id将被作为对象处理,前段无法将此对象转为字符串,也无法将此id作为唯一标识调用其他数据。

{id: {        "time": 1494233455000,        "timestamp": 1494233455,        "date": 1494233455000,        "new": false,        "timeSecond": 1494233455,        "inc": -125534200,        "machine": -1248386109      }}

故有时需要将ObjectId的序列化做处理,将ObjectId直接序列化为字符串。

以springmvc为例,在接口返回数据前统一处理序列化问题。自定义类实现ResponseBodyAdvice接口,重写beforeBodyWrite方法,自定义序列化方法。

import com.alibaba.fastjson.JSON;import com.alibaba.fastjson.JSONObject;import com.alibaba.fastjson.serializer.SerializeConfig;import org.bson.types.ObjectId;import org.springframework.core.MethodParameter;import org.springframework.http.MediaType;import org.springframework.http.converter.HttpMessageConverter;import org.springframework.http.server.ServerHttpRequest;import org.springframework.http.server.ServerHttpResponse;import org.springframework.web.bind.annotation.ControllerAdvice;import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;@ControllerAdvicepublic class MyResponseBodyAdvice implements ResponseBodyAdvice {    @Override    public boolean supports(MethodParameter returnType, Class
> converterType) { return true; } @Override public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType, Class
> selectedConverterType, ServerHttpRequest request, ServerHttpResponse response) { SerializeConfig config = new SerializeConfig(); config.put(ObjectId.class, new ObjectIdJsonSerializer()); return JSONObject.parse(JSON.toJSONString(body, config)); }}

然后实现一个ObjectIdJsonSerializer

import com.alibaba.fastjson.serializer.JSONSerializer;import com.alibaba.fastjson.serializer.ObjectSerializer;import com.alibaba.fastjson.serializer.SerializeWriter;import org.bson.types.ObjectId;import java.io.IOException;import java.lang.reflect.Type;public class ObjectIdJsonSerializer implements ObjectSerializer {    @Override    public void write(JSONSerializer serializer, Object object, Object fieldName, Type fieldType,int features) throws IOException {        SerializeWriter out = serializer.getWriter();        if (object == null) {            serializer.getWriter().writeNull();            return;        }        out.write("\"" + ((ObjectId) object).toString() + "\"");    }}

这样处理后接口返回的id将变成字符串类型。

{"id":"5ae078ada0f091000be702b8"}

同理spring mvc对于Date类型的输出默认为时间戳格式,我们可以自定义输出为格式化字符串,这样可以免去在前端格式化处理。需要在MyResponseBodyAdvice 中注册DateJsonSerializer 。

import com.alibaba.fastjson.serializer.JSONSerializer;import com.alibaba.fastjson.serializer.ObjectSerializer;import com.alibaba.fastjson.serializer.SerializeWriter;import org.bson.types.ObjectId;import java.io.IOException;import java.lang.reflect.Type;import java.util.Date;public class DateJsonSerializer implements ObjectSerializer {    @Override    public void write(JSONSerializer serializer, Object object, Object fieldName, Type fieldType,int features) throws IOException {        SerializeWriter out = serializer.getWriter();        if (object == null) {            serializer.getWriter().writeNull();            return;        }        out.write("\"" + DateUtil.format(((Date)object),"yyyy-MM-dd: HH:mm:ss") + "\"");    }}

转载地址:http://xpzvl.baihongyu.com/

你可能感兴趣的文章
对Java、C#转学swift的提醒:学习swift首先要突破心理障碍。
查看>>
面向对象 2017-4-15
查看>>
java项目导出war包
查看>>
算法第三章实践报告
查看>>
linux应用之Mongodb的安装及配置(centos)
查看>>
Python 面向对象 --- eval 函数
查看>>
PHP的错误和异常处理
查看>>
z-index兼容问题:关于ie6/7下的z-index
查看>>
腾讯2014年实习生招聘笔试面试经历
查看>>
不浮躁,获取充实感
查看>>
Pyqt 国际化多语言支持
查看>>
大多数女生为什么不适合当程序员?
查看>>
SID1190471 / 烦人的幻灯片 暴力出奇迹 !!!!!!!!!!!!!!!!!!...
查看>>
高速排序 与 随机高速排序 算法分析
查看>>
使用MyEclipse 2014构建Maven项目的两种方法
查看>>
WebGIS中以version方式实现代码更新后前端自动读取更新代码的方法
查看>>
Centos 安装Apache软件
查看>>
微信小程序中在swiper-item中遍历循环添加多个数据内容(微信小程序交流群:604788754)...
查看>>
java-mybaits-00503-延迟加载
查看>>
看淡你的权力
查看>>