Java对MongoDB的ObjectId的序列化问题
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;
@ControllerAdvice
public class MyResponseBodyAdvice implements ResponseBodyAdvice<Object> {
@Override
public boolean supports(MethodParameter returnType, Class<? extends HttpMessageConverter<?>> converterType) {
return true;
}
@Override
public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType,
Class<? extends HttpMessageConverter<?>> 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") + "\"");
}
}

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
-
上一篇
Springboot+ajax传输json数组以及单条数据的方法
Springboot+ajax传输json数组以及单条数据的方法 下面是用ajax传输到后台单条以及多条数据的解析的Demo: 结构图如下: image 下面是相关的代码: pom.xml: <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.example</groupId> <artifactId>springboot-ssm</artifactId> <ve...
-
下一篇
Python编程入门基础语法详解经典
一、基本概念 1.内置的变量类型: Python是有变量类型的,而且会强制检查变量类型。内置的变量类型有如下几种: #浮点 float_number=2.3 #复数 complex_number=1+5j #整型 integer_number=1 #list 序列 sample_list=[2,52,36,'abc'] #嵌套 sample_nest=[(2,4,6),{5:7,9:11,'key':[2,5]},6] #dictionary 字典 sample_dic={"key":value, 5:10} #tuple 只读的序列 sample_tuple=(3,9,"ab") 从上面的示例可以看出,python的变量无需声明,可直接给变量赋值。 2.字符串 python中声明一个字符串通常有三种方法,''、" "和''' ''',这三种方法在声明普通字符串时的效果是完全一样的,区别在于字符串本身中存在引号的情况,举例如下: word='good' sentence="hello world" paragraph='''good noon:"nice to meet you."''...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- SpringBoot2全家桶,快速入门学习开发网站教程
- SpringBoot2配置默认Tomcat设置,开启更多高级功能
- SpringBoot2更换Tomcat为Jetty,小型站点的福音
- CentOS8编译安装MySQL8.0.19
- MySQL数据库在高并发下的优化方案
- SpringBoot2编写第一个Controller,响应你的http请求并返回结果
- Springboot2将连接池hikari替换为druid,体验最强大的数据库连接池
- SpringBoot2初体验,简单认识spring boot2并且搭建基础工程
- Dcoker安装(在线仓库),最新的服务器搭配容器使用
- CentOS7,8上快速安装Gitea,搭建Git服务器