今天,念念不忘一件事... ✅FastJson在調用JSON#toJSONString時,如何截取比較長的value串?

来源:https://www.cnblogs.com/buguge/archive/2022/10/28/16837507.html
-Advertisement-
Play Games

解決辦法是 利用 com.alibaba.fastjson.serializer.ObjectSerializer 和 com.alibaba.fastjson.annotation.JSONField 。 ...


項目里 前後端頁面的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



您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • Vue(V 3.2.37)使用Three.js(V 0.145.0)載入3D模型的詳細步驟 1、安裝three 命令: pnpm install three 引入 three 和載入器 import * as THREE from 'three' import { OBJLoader } from ...
  • 原博客地址 01、描述事件冒泡的流程,可畫圖 考察點:事件基礎知識 參考答案: // 基於DOM樹結構,事件會順著觸發元素向上冒泡 // 阻止冒泡 event.stopPropagation(); 點擊一個div,會一級一級向父級、爺級元素上冒泡,這個點擊事件不僅能被這個div捕捉到,也能被他的父級 ...
  • Apache Shiro是一個強大且易用的Java安全框架,執行身份驗證、授權、密碼和會話管理。使用Shiro的易於理解的API,您可以快速、輕鬆地獲得任何應用程式,從最小的移動應用程式到最大的網路和企業應用程式。 ...
  • 1. 凱撒加密演算法 1.1 演算法邏輯 根據一個固定偏移值(offset), 將字母向一個方向偏移, 進行加密. 1.2 初步思路 獲取明文(plaintext) 獲取明文字元串的單獨字元 進行字元值偏移 當偏移超出字母範圍時, 回到第一個字母處繼續偏移. 得到密文(ciphertext) 1.3 初 ...
  • 以下為本人的學習筆記 1.認識Annotation JDK1.5開始,java增加了對元數據(即類的組成單元數據)的支持,也就是(Annotation)註解,它是代碼里做的特殊標記,這些標記可以在編譯,類載入,運行時在不改變原有邏輯的情況下,被讀取(通過反射來讀取),並執行相應 的處理,通過使用An ...
  • 2022-10-28 Tomcat (1)含義:Tomcat是一個使用廣泛的JavaWeb伺服器。 (2)官方下載地址: https://tomcat.apache.org/ 使用8.0版本的就OK。 (3)在使用Tomcat之前需要的準備工作: 正確配置JAVA_HOME的環境變數,配置的內容是j ...
  • 本次案例代碼實現思路: 打開考試網站 selenium --> 瀏覽器驅動 --> 操作瀏覽器 <模擬人的行為做操作瀏覽器> 獲取答案 獲取答案網站鏈接 獲取問題以及答案內容 對比題目以及答案 選出正確答案 獲取問題答案選項 和正確的答案進行對比 如果正確答案和選擇答案一致, 那就進行點擊 進行點擊 ...
  • 1:C++的引用,引用和指針的區別? 1:從彙編指令角度上看,引用和指針沒有區別,引用也是通過地址指針的方式訪問指向的記憶體 int &b=a ; 是需要將a的記憶體地址取出並存下來, b=20;(通過引用修改值時,也是先取出指向的地址,然後訪問該地址的值並修改它,和通過指針修改值一樣) 在定義引用的時 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...