redis序列化存储及日期格式
在模块开发中,使用redis做缓存是非常常见的技术,当我们注入redistempate模板时
1
|
redistemplate.opsforvalue().set( "item_" +id,itemmodel, 10 , timeunit.minutes); |
key我们可以用固定开头和商品id进行拼接,当然正常的项目开发中最好使用多级目录进行分类,这里只做演示使用
可视化界面看到保存的数据是这样的
这样的数据是很不容易阅读的,原因是redis默认使用的是java序列化方式,在序列化时使用了redis协议中的编码。
不过在这种痛苦的数据面前做调试等工作无疑是非常不舒服的
这时候就需要我们自定义序列化方式
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
|
@configuration public class redisconfig { /** * 修改redis默认的序列化方式,默认文件在redisautoconfiguration * @param redisconnectionfactory * @return */ @bean public redistemplate redistemplate(redisconnectionfactory redisconnectionfactory){ redistemplate redistemplate = new redistemplate(); redistemplate.setconnectionfactory(redisconnectionfactory); //设置key的序列化方式为string stringredisserializer stringredisserializer = new stringredisserializer(); redistemplate.setkeyserializer(stringredisserializer); //设置value的序列化方式为json jackson2jsonredisserializer jackson2jsonredisserializer = new jackson2jsonredisserializer(object. class ); //定制化关于时间格式序列化问题 objectmapper objectmapper = new objectmapper(); simplemodule simplemodule = new simplemodule(); simplemodule.addserializer(datetime. class , new jodadatetimejsonserializer()); simplemodule.adddeserializer(datetime. class , new jodadatetimejsondeserializer()); objectmapper.registermodule(simplemodule); //在保存结果中加入类信息,方便解析数据 objectmapper.enabledefaulttyping(objectmapper.defaulttyping.non_final); jackson2jsonredisserializer.setobjectmapper(objectmapper); redistemplate.setvalueserializer(jackson2jsonredisserializer); return redistemplate; } } |
1
2
3
4
5
6
|
public class jodadatetimejsonserializer extends jsonserializer<datetime> { @override public void serialize(datetime value, jsongenerator gen, serializerprovider serializers) throws ioexception { gen.writestring(value.tostring( "yyyy-mm-dd hh:mm:ss" )); } } |
1
2
3
4
5
6
7
8
|
public class jodadatetimejsondeserializer extends jsondeserializer<datetime> { @override public datetime deserialize(jsonparser p, deserializationcontext ctxt) throws ioexception, jsonprocessingexception { string s = p.readvalueas(string. class ); datetimeformatter datetimeformatter = datetimeformat.forpattern( "yyyy-mm-dd hh:mm:ss" ); return datetime.parse(s,datetimeformatter); } } |
redis序列化localdatetime报错
实体类日期字段使用localdatetime,在redis序列化时报错,会往redis中写入如下数据:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
|
"createtime" : { "date" : { "year" : 2019, "month" : "may" , "day" : 15, "prolepticmonth" : 24232, "era" : [ "java.time.chrono.isoera" , "ce" ], "dayofyear" : 135, "dayofweek" : "wednesday" , "leapyear" : false , "dayofmonth" : 15, "monthvalue" : 5, "chronology" : { "id" : "iso" , "calendartype" : "iso8601" } }, "time" : { "hour" : 11, "minute" : 3, "second" : 43, "nano" : 758000000 }, "dayofyear" : 135, "dayofweek" : "wednesday" , "month" : "may" , "dayofmonth" : 15, "year" : 2019, "monthvalue" : 5, "hour" : 11, "minute" : 3, "second" : 43, "nano" : 758000000, "chronology" : [ "java.time.chrono.isochronology" , { "id" : "iso" , "calendartype" : "iso8601" } ] } |
方案一:实体类日期字段添加注解
每个localdatetime类型字段都需要添加,不建议使用
1
2
3
|
@jsondeserialize (using = localdatetimedeserializer. class ) @jsonserialize (using = localdatetimeserializer. class ) private localdatetime birthday; |
方案二:设置redis对日期序列化处理
添加配置:
1
2
3
4
5
|
// 日期序列化处理 om.disable(serializationfeature.write_dates_as_timestamps); om.registermodule( new jdk8module()) .registermodule( new javatimemodule()) .registermodule( new parameternamesmodule()); |
完整配置:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
|
@configuration public class redisconfig { @bean public redistemplate<string, object> redistemplate(redisconnectionfactory factory) { redistemplate<string, object> template = new redistemplate<>(); // 配置连接工厂 template.setconnectionfactory(factory); //使用jackson2jsonredisserializer来序列化和反序列化redis的value值(默认使用jdk的序列化方式) jackson2jsonredisserializer jacksonseial = new jackson2jsonredisserializer(object. class ); objectmapper om = new objectmapper(); // 指定要序列化的域,field,get和set,以及修饰符范围,any是都有包括private和public om.setvisibility(propertyaccessor.all, jsonautodetect.visibility.any); // 指定序列化输入的类型,类必须是非final修饰的,final修饰的类,比如string,integer等会跑出异常 om.enabledefaulttyping(objectmapper.defaulttyping.non_final); jacksonseial.setobjectmapper(om); // 值采用json序列化 template.setvalueserializer(jacksonseial); //使用stringredisserializer来序列化和反序列化redis的key值 template.setkeyserializer( new stringredisserializer()); // 设置hash key 和value序列化模式 template.sethashkeyserializer( new stringredisserializer()); template.sethashvalueserializer(jacksonseial); template.afterpropertiesset(); // 日期序列化处理 om.disable(serializationfeature.write_dates_as_timestamps); om.registermodule( new jdk8module()) .registermodule( new javatimemodule()) .registermodule( new parameternamesmodule()); return template; } } |
以上为个人经验,希望能给大家一个参考,也希望大家多多支持服务器之家。
原文链接:https://blog.csdn.net/qq_15038565/article/details/108418122