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

Spring Boot如何仅序列化自定义派生异常的字段?

解决Spring Boot自定义异常序列化时仅返回指定字段的问题

方案一:使用@JsonIgnoreProperties忽略父类字段

在ApplicationException类上添加Jackson注解,明确排除不需要序列化的父类字段:

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import java.time.LocalDateTime;

@JsonIgnoreProperties(value = {"stackTrace", "cause", "suppressed", "localizedMessage"})
public class ApplicationException extends RuntimeException {
    private String resultCode;
    private int httpStatusCode;
    private LocalDateTime throwedAt;

    // 构造方法示例
    public ApplicationException(String resultCode, String message, int httpStatusCode) {
        super(message);
        this.resultCode = resultCode;
        this.httpStatusCode = httpStatusCode;
        this.throwedAt = LocalDateTime.now();
    }

    // getter方法
    public String getResultCode() { return resultCode; }
    public int getHttpStatusCode() { return httpStatusCode; }
    public LocalDateTime getThrowedAt() { return throwedAt; }
}

该注解会告知Jackson序列化时跳过指定的父类字段,仅保留ApplicationException自身的自定义字段。

方案二:自定义全局异常处理器手动构建响应

通过@RestControllerAdvice实现全局异常拦截,在处理方法中手动组装仅包含所需字段的响应体:

import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import java.util.HashMap;
import java.util.Map;

@RestControllerAdvice
public class GlobalExceptionHandler {

    @ExceptionHandler(ApplicationException.class)
    public ResponseEntity<Map<String, Object>> handleApplicationExceptions(ApplicationException ex) {
        Map<String, Object> responseBody = new HashMap<>();
        responseBody.put("resultCode", ex.getResultCode());
        responseBody.put("message", ex.getMessage());
        responseBody.put("httpStatusCode", ex.getHttpStatusCode());
        responseBody.put("throwedAt", ex.getThrowedAt());

        return new ResponseEntity<>(responseBody, HttpStatus.valueOf(ex.getHttpStatusCode()));
    }
}

这种方式完全掌控响应内容,不受异常类继承关系影响,适合需要统一格式化所有异常响应的场景。

方案三:自定义序列化逻辑

让ApplicationException实现JsonSerializable接口,手动定义序列化规则,确保只输出指定字段:

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.JsonSerializable;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.jsontype.TypeSerializer;
import java.io.IOException;
import java.time.LocalDateTime;

public class ApplicationException extends RuntimeException implements JsonSerializable {
    private String resultCode;
    private int httpStatusCode;
    private LocalDateTime throwedAt;

    // 构造方法、getter同方案一

    @Override
    public void serialize(JsonGenerator gen, SerializerProvider serializers) throws IOException {
        gen.writeStartObject();
        gen.writeStringField("resultCode", resultCode);
        gen.writeStringField("message", getMessage());
        gen.writeNumberField("httpStatusCode", httpStatusCode);
        gen.writeObjectField("throwedAt", throwedAt);
        gen.writeEndObject();
    }

    @Override
    public void serializeWithType(JsonGenerator gen, SerializerProvider serializers, TypeSerializer typeSer) throws IOException {
        serialize(gen, serializers); // 无需类型信息可直接调用普通序列化方法
    }
}

此方案最彻底,完全绕过父类字段的序列化逻辑,适合对序列化有严格定制需求的场景。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 07:52:20