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