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

Spring Boot升级后@JsonProperty注解失效问题求助

Spring Boot 1.5.3 → 2.3.5升级后@JsonProperty注解失效,JSON序列化/反序列化字段名格式异常

我最近把Spring Boot从1.5.3版本升级到2.3.5之后,UI端的某个功能出现了异常。调试后发现返回给UI的JSON响应格式变了——原本的驼峰命名字段变成了下划线命名,看起来@JsonProperty注解完全不生效了,这让我头大了一整天都没搞定,希望大家能帮忙看看!


原/新JSON响应对比

升级前的正常响应(驼峰字段)

"modelExplanation": [{ 
    "sectionId": 0, 
    "sectionText": "some text", 
    "startIndex": "0", 
    "endIndex": "105", 
    "modelExplanations": [{ 
        "modelId": "mdl_collusion", 
        "modelName": "collusion", 
        "modelVersion": "3.4.1", 
        "score": "1.0", 
        "riskStatus": "low" 
    }, { 
        "modelId": "mdl_mkt_mnpltn", 
        "modelName": "market_manipulation", 
        "modelVersion": "3.4.1", 
        "score": "1.0", 
        "riskStatus": "low" 
    }, { 
        "modelId": "mdl_secrecy", 
        "modelName": "secrecy", 
        "modelVersion": "3.4.1", 
        "score": "1.0", 
        "riskStatus": "low" 
    }] 
}]

升级后的异常响应(下划线字段)

"section_id": 1, 
"section_text": "some text", 
"start_index": "738", 
"end_index": "1112", 
"model_explanations": [{ 
    "model_id": "mdl_collusion", 
    "model_name": "collusion", 
    "model_version": "3.4.1", 
    "section_score": "0.09059832", 
    "risk_status": "low" 
}, { 
    "model_id": "mdl_mkt_mnpltn", 
    "model_name": "market_manipulation", 
    "model_version": "3.4.1", 
    "section_score": "0.12787165", 
    "risk_status": "low" 
}, { 
    "model_id": "mdl_secrecy", 
    "model_name": "secrecy", 
    "model_version": "3.4.1", 
    "section_score": "0.19208406", 
    "risk_status": "low" 
}]

相关代码

业务逻辑代码

这部分负责调用外部服务获取JSON、映射为Java对象,再序列化返回给UI:

public ModelExplanationResponse getModelExplanation(User user, ModelRequest request) {
    ModelExplanationMetadata metadata = null;
    try {
        String modelExplanationJson = anotherService.getModelExplanation(user, request.getMessageId(), request.getSource(), request.getAvroId(), request.getRundate());
        if (modelExplanationJson != null && !"".equals(modelExplanationJson)) {
            metadata = mapJSONToMetadata(modelExplanationJson);
        }
    } catch (Exception e) {
        throw new AlertMngtServiceException("Unable to retrieve attachment",e);
    }
    return getModelExplanationResponse(metadata, request);
}

private ModelExplanationResponse getModelExplanationResponse(ModelExplanationMetadata metadata, ModelRequest request) {
    ModelExplanationResponse response = new ModelExplanationResponse();
    if (metadata != null && metadata.getModelExplanation() != null) {
        List<ModelExplanationSection> modelExplanation = mapJSONToModelExplanation(metadata.getModelExplanation());
        if (!CollectionUtils.isEmpty(modelExplanation)) {
            modelExplanation.sort(Comparator.comparing(ModelExplanationSection::getSectionId));
            response.setModelExplanation(modelExplanation);
            String formattedMessageBody = new ModelExplanationBasedMessageModifier().modify(request.getMessageBody(), modelExplanation);
            response.setMessageBody(formattedMessageBody);
        }
    } else {
        LOGGER.info("Unable to fetch Model Explanation for {}", request);
    }
    return response;
}

ModelExplanationSection类

该类承担双重职责:反序列化外部服务返回的下划线JSON,同时序列化后返回驼峰JSON给UI:

import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty;
@JsonIgnoreProperties(ignoreUnknown = true)
public class ModelExplanationSection {
    private final int sectionId;
    private final String sectionText;
    private final String startIndex;
    private final String endIndex;
    private final List<ModelExplanation> modelExplanations;

    @JsonCreator
    public ModelExplanationSection(
            @JsonProperty("section_id") int sectionId,
            @JsonProperty("section_text") String sectionText,
            @JsonProperty("start_index") String startIndex,
            @JsonProperty("end_index") String endIndex,
            @JsonProperty("model_explanations") List<ModelExplanation> modelExplanations) {
        super();
        this.sectionId = sectionId;
        this.sectionText = sectionText;
        this.startIndex = startIndex;
        this.endIndex = endIndex;
        this.modelExplanations = modelExplanations;
    }

    public int getSectionId() { return sectionId; }
    public String getSectionText() { return sectionText; }
    public String getStartIndex() { return startIndex; }
    public String getEndIndex() { return endIndex; }
    public List<ModelExplanation> getModelExplanations() { return modelExplanations; }
}

ModelExplanation类

同样承担反序列化和序列化的双重职责:

import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.google.common.base.Strings;
@JsonIgnoreProperties(ignoreUnknown = true)
public class ModelExplanation {
    private final String modelId;
    private final String modelName;
    private final String modelVersion;
    private final String score;
    private final String riskStatus;

    @JsonCreator
    public ModelExplanation(
            @JsonProperty("model_id") String modelId,
            @JsonProperty("model_name") String modelName,
            @JsonProperty("model_version") String modelVersion,
            @JsonProperty("section_score") String score,
            @JsonProperty("risk_status") String riskStatus) {
        super();
        this.modelId = modelId;
        this.modelName = modelName;
        this.modelVersion = modelVersion;
        this.score = score;
        this.riskStatus = getRiskStatus(riskStatus);
    }

    private String getRiskStatus(String riskStatus) {
        return Strings.isNullOrEmpty(riskStatus)?"low":riskStatus;
    }

    public String getModelId() { return modelId; }
    public String getModelName() { return modelName; }
    public String getModelVersion() { return modelVersion; }
    public String getScore() { return score; }
    public String getRiskStatus() { return riskStatus; }
}

已尝试的无效方案

  • 给@JsonCreator添加mode = JsonCreator.Mode.PROPERTIES参数,无效果;
  • 尝试将Jackson注解的导入包从com.fasterxml.jackson.annotate替换为org.codehaus.jackson.annotate,同样无效。

我现在完全搞不懂升级前为什么能正常工作——这些类本来是既要把外部服务返回的下划线JSON映射成Java对象,又要把Java对象序列化成驼峰JSON返回给UI的。已经折腾了一天还是没找到问题根源,有没有大佬能指点一下?

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.29 14:38:10