You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Boot中如何便捷地以JSON格式记录自定义对象日志?

便捷输出自定义对象为JSON日志的方案

针对你遇到的问题,这里提供几个实用且低侵入的解决方案:

方案一:自定义Logback日志转换器(全局生效)

通过自定义Logback的日志参数转换器,让所有日志中的非基础类型对象自动转为JSON格式,无需手动调用ObjectMapper。

步骤1:实现自定义转换器类

import ch.qos.logback.classic.pattern.ClassicConverter;
import ch.qos.logback.classic.spi.ILoggingEvent;
import com.fasterxml.jackson.databind.ObjectMapper;

public class JsonObjectConverter extends ClassicConverter {
    // 复用ObjectMapper实例,避免重复创建
    private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();

    @Override
    public String convert(ILoggingEvent event) {
        StringBuilder sb = new StringBuilder();
        for (Object arg : event.getArgumentArray()) {
            if (arg != null && !(arg instanceof String || arg instanceof Number || arg instanceof Boolean)) {
                try {
                    sb.append(OBJECT_MAPPER.writeValueAsString(arg));
                } catch (Exception e) {
                    // 转换失败时 fallback 到默认toString
                    sb.append(arg.toString());
                }
            } else {
                sb.append(arg);
            }
            sb.append(" ");
        }
        return sb.toString().trim();
    }
}

步骤2:配置Logback

在logback-spring.xml或logback.xml中添加转换器规则,并修改日志输出格式:

<appender name="stdout" class="ch.qos.logback.core.ConsoleAppender">
    <encoder>
        <!-- 用自定义转换器替换原有的%s占位符 -->
        <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %customJsonConverter%n</pattern>
        <!-- 注册自定义转换器 -->
        <conversionRule conversionWord="customJsonConverter" converterClass="com.your.package.JsonObjectConverter"/>
    </encoder>
</appender>

之后直接用常规方式打日志即可:

log.info("获取到用户信息:{}", userInfo);

转换器会自动把userInfo转为JSON格式输出。

方案二:封装全局日志工具类

如果不想修改日志框架配置,可以封装一个工具类,统一处理对象转JSON的逻辑,同时规避异常和NPE问题。

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.fasterxml.jackson.databind.ObjectMapper;

public class LogUtil {
    private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();

    // 封装info级别日志
    public static void info(Class<?> clazz, String message, Object... args) {
        Logger logger = LoggerFactory.getLogger(clazz);
        if (logger.isInfoEnabled()) {
            Object[] processedArgs = processArgs(args);
            logger.info(message, processedArgs);
        }
    }

    // 统一处理日志参数
    private static Object[] processArgs(Object[] args) {
        if (args == null) return new Object[0];
        for (int i = 0; i < args.length; i++) {
            Object arg = args[i];
            if (arg != null && !(arg instanceof String || arg instanceof Number || arg instanceof Boolean)) {
                try {
                    args[i] = OBJECT_MAPPER.writeValueAsString(arg);
                } catch (Exception e) {
                    args[i] = arg.toString();
                }
            }
        }
        return args;
    }

    // 可按需封装warn/error等其他级别日志
    public static void error(Class<?> clazz, String message, Object... args) {
        Logger logger = LoggerFactory.getLogger(clazz);
        if (logger.isErrorEnabled()) {
            Object[] processedArgs = processArgs(args);
            logger.error(message, processedArgs);
        }
    }
}

调用示例:

LogUtil.info(UserController.class, "更新用户:{}", userInfo);

方案三:基于抽象类统一实体类toString

如果实体类数量不多,可以定义一个抽象类,让所有需要JSON输出的实体类继承它,统一实现JSON格式的toString方法。

步骤1:定义抽象基类

import com.fasterxml.jackson.databind.ObjectMapper;

public abstract class JsonToString {
    private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();

    @Override
    public String toString() {
        try {
            return OBJECT_MAPPER.writeValueAsString(this);
        } catch (Exception e) {
            // 转换失败时使用父类默认toString
            return super.toString();
        }
    }
}

步骤2:实体类继承基类

import lombok.Data;
import com.fasterxml.jackson.annotation.JsonInclude;

@Data
@JsonInclude(JsonInclude.Include.NON_NULL) // 忽略null字段,优化日志输出
public class UserInfo extends JsonToString {
    private Long id;
    private String name;
    private String email;
}

之后直接打印对象即可输出JSON:

log.info("用户详情:{}", userInfo);

内容的提问来源于stack exchange,提问作者Roberto

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.02 13:43:13