專案里 前后端頁面的http請求 及 dubbo服務間的RPC呼叫,回傳值型別統一是一個Result<T>,其結構如下,
@Data public class Result<T> implements Serializable { private static final long serialVersionUID = 1L; /** * 回傳處理訊息 */ private String message = "操作成功!"; /** * 回傳代碼 */ private Integer code = 0; /** * 回傳資料物件 data */ @Getter private T data; }
專案的RPC使用的是dubbo,我們在專案中定義了一個公用的DubboTraceFilter,這個Filter會將介面方法回傳值 Result<T>物件 列印到log檔案里,序列化方式用的是 fastjson 的 JSON#toJSONString,
背景介紹完畢,接下來說我要解決的事情,
注意到Result<T>的data欄位,它是泛型T的實體,就是說,這個data會是任意型別的資料,
從log里看,當data里是集合資料,例如,分頁查詢的場景,列印出來的log會超長,
這導致日志量很大,同時,這種無用的日志刷屏,也不利于我們排查問題,
簡言之,看下面兩段json串(為便于閱讀,進行了格式化),希望log里出現后者,
{ "message": "成功", "code": 200, "result": ["0memob92142f2-ad8a-4812-913e-002f8f9d1894", "1memo77d4ad82-078f-4f73-a26e-c5302a596042", "2memoa69185c2-670d-480b-b1d2-19fd1326ecd5", "3memoee5d13a7-83bd-4430-a4b0-198e65201dc7", "4memo519d9d69-a27f-4864-8dd4-889ada1790a3", "5memo85034936-564b-41d8-94f0-ff1ac7be8d92", "6memoa22d4b20-828a-4ac5-a3fe-461283fc4154", "7memo7b2b8880-80b2-41f8-93d9-553467287e13", "8memo55afe9f2-e6b5-481c-9978-773fb5ff0f14", "9memoa5a92ffd-4e72-42f1-8d81-7221d2f371a3"], "timestamp": 1666961782888 }
{ "code": 200, "message": "成功", "result": "[\"0memob92142f2-ad8a-4812-913e-002f8f9d1894\",\"1memo77d4ad82-078f-4f73-a26e-c5302a596042\",\"2memoa6...", "timestamp": 1666961782888 }
那么,如何解決這個痛點?
我相信,找開發組里的任何一位同學,他都能解決,改DubboTraceFilter里的代碼就行了,對序列化的json串進行相關截取,
而我想說什么呢?
一勞永逸!
程式里有還有其他地方也存在通過 JSON#toJSONString(Result<T>) 列印log的代碼, 難道逐個改嗎?
所以,有沒有簡單的辦法,改一處就全改了,
世上無易事,用心求精進,只要不放棄,辦法就會有,
解決辦法是 利用 com.alibaba.fastjson.serializer.ObjectSerializer 和 com.alibaba.fastjson.annotation.JSONField ,
首先,通過實作ObjectSerializer介面來自定義一個序列化器: StringAbbreviatingSerializer
import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.serializer.JSONSerializer; import com.alibaba.fastjson.serializer.ObjectSerializer; import org.apache.commons.lang.StringUtils; import java.io.IOException; import java.lang.reflect.Type; public class StringAbbreviatingSerializer implements ObjectSerializer { /** * * @param serializer * @param object field的值 * @param fieldName field的name * @param fieldType field的型別,如java.lang.String * @param features * @throws IOException */ @Override public void write(JSONSerializer serializer, Object object, Object fieldName, Type fieldType, int features) throws IOException { serializer.write( StringUtils.abbreviate(JSON.toJSONString(object),100)); } }View Code
然后,使用com.alibaba.fastjson.annotation.JSONField 注解,
@JSONField(serializeUsing = StringAbbreviatingSerializer.class) private T data;
完了嗎?我要補充——一并重寫Result<T>的toString方法,徹底一勞永逸,
@Data public class Result<T> implements Serializable { ,,,, @Override public String toString() { return JSON.toJSONString(this); } }
要說明的是,加上這個注解后,對Result<T>的實際值并不會有影響(包括http請求和dubbo呼叫,親測),所以,放心用,放心去序列化,媽媽再也不用擔心我的日志爆屏了,
over!
附:
使用fastjson提供的介面實作自定義的編解碼器
在專案開發中經常會遇到一些業務需要對某些資料進行特殊的定制化處理,fastjson為我們提供了介面可以用于實作自定義的編解碼器來完成我們的業務要求,
ObjectSerializer和ObjectDeserializer分別是fastjson的編碼器和解碼器介面,
當看到一些不好的代碼時,會發現我還算優秀;當看到優秀的代碼時,也才意識到持續學習的重要!--buguge
本文來自博客園,轉載請注明原文鏈接:https://www.cnblogs.com/buguge/p/16837507.html
<style>hr.signhr{width:80%;margin:0 auto;border: 0;height: 4px;background-image: linear-gradient(to right, rgba(0, 0, 0, 0), rgba(0, 0, 0, 0.75), rgba(0, 0, 0, 0))}</style>
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/522903.html
標籤:其他
上一篇:10道Python面試題
下一篇:<五>掌握左值參考和初識右值參考
