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
相关产品推荐
相关产品推荐

