异常信息:
om.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Unrecognized field "ClinicCaseCode" (class dto.tsb.TsbFeeImportInParam), not marked as ignorable (17 known properties: "medicalRecord", "clinicCaseCode", "drId", "name", "recipeList", "sectionName", "sectionCode", "sexCode", "clinicFlowNo", "drName", "icNo", "hisSectionName", "medicalType", "mdtrtTime", "hisfootSn", "feeAmount", "identID"])
这是一个典型的 Jackson 反序列化字段名不匹配问题。
原因分析
错误信息 Unrecognized field "ClinicCaseCode" 表明 Jackson 在 JSON 中找到了键 "ClinicCaseCode",但在 Java 类 TsbFeeImportInParam 中无法找到对应的属性进行映射。
虽然你的 Java 代码中定义了 private String ClinicCaseCode;,但注意看报错信息中列出的 17 known properties(已知属性):
"medicalRecord", "clinicCaseCode", "drId", ... "hisfootSn", ...
两个关键细节:
1、大小写差异:已知属性列表中是 clinicCaseCode(首字母小写),而 JSON 中传的是 ClinicCaseCode(首字母大写)。
2、命名规范冲突:Java Bean 规范规定,字段名如果前两个字母是大写(如 HISFootSn)或首字母大写后续有小写(如 ClinicCaseCode),Getter/Setter 生成的属性名可能会与预期不符。Jackson 默认遵循 Java Bean 规范,将 getClinicCaseCode() 解析为属性名 clinicCaseCode,而不是 ClinicCaseCode。
因此,Jackson 认为 JSON 中的 ClinicCaseCode 是一个未知字段,因为它只认识 clinicCaseCode。
同理,报错中可能还会涉及其他字段,如 HISFootSn(JSON) vs hisfootSn(已知属性列表显示全小写或特定转换),IdentID 等。
解决方案
推荐以下三种方案,按推荐程度排序:
方案一:使用 @JsonProperty 注解(最推荐,精准控制)
在 TsbFeeImportInParam 类的每个字段上添加 @JsonProperty 注解,明确指定 JSON 中的键名。这样可以完全绕过 Java Bean 命名规范的歧义,确保 JSON 字段与 Java 字段一一映射。
import com.fasterxml.jackson.annotation.JsonProperty;
import java.util.List;
public class TsbFeeImportInParam {
@JsonProperty("HISFootSn")
private String HISFootSn;
@JsonProperty("ClinicFlowNo")
private String ClinicFlowNo;
@JsonProperty("MedicalType")
private String MedicalType;
@JsonProperty("Name")
private String Name;
@JsonProperty("SexCode")
private String SexCode;
@JsonProperty("IdentID")
private String IdentID;
@JsonProperty("IcNo")
private String IcNo;
@JsonProperty("ClinicCaseCode")
private String ClinicCaseCode;
@JsonProperty("MdtrtTime")
private String MdtrtTime;
@JsonProperty("FeeAmount")
private String FeeAmount;
@JsonProperty("MedicalRecord")
private String MedicalRecord;
@JsonProperty("SectionCode")
private String SectionCode;
@JsonProperty("SectionName")
private String SectionName;
@JsonProperty("HisSectionName")
private String HisSectionName;
@JsonProperty("DrId")
private String DrId;
@JsonProperty("DrName")
private String DrName;
@JsonProperty("RecipeList")
private List<Recipe> RecipeList;
// Getter 和 Setter 方法保持不变...
}
优点:明确、稳定,不受 Java 版本或 Jackson 配置影响,完美兼容第三方系统的大写字段名。
缺点:代码略显冗长。
方案二:全局配置忽略未知字段 + 修正字段命名(次选)
如果希望代码更简洁,且可以接受修改 Java 字段名为标准小驼峰(lowerCamelCase),可以这样做:
修改 Java 类字段为标准小驼峰:
将 ClinicCaseCode 改为 clinicCaseCode,HISFootSn 改为 hisFootSn 等。
添加 @JsonProperty 仅用于不匹配的字段:
如果某些字段必须保持大写(如 IdentID),则单独加注解。
配置全局忽略未知字段(防止其他无关字段导致报错):
在 application.yml 或 application.properties 中配置:
yaml
spring:
jackson:
deserialization:
fail-on-unknown-properties: false
或者在类级别添加注解:
java
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
@JsonIgnoreProperties(ignoreUnknown = true)
public class TsbFeeImportInParam {
// ...
}
注意:仅忽略未知字段不能解决当前问题,因为 ClinicCaseCode 不是"未知"而被忽略,而是因为名字不匹配导致映射失败。如果改名后 JSON 仍传 ClinicCaseCode,依然会报错。所以必须配合 @JsonProperty 或自定义命名策略使用。
方案三:自定义 PropertyNamingStrategy(高级)
如果所有字段都遵循某种特定规则(例如全部首字母大写),可以配置全局命名策略。但鉴于你的字段名风格不统一(有的全大写 HIS,有的混合 ClinicCaseCode,有的 IdentID),此方案不适用,容易导致更多映射错误。
额外提醒:嵌套对象 Recipe 和内部列表
JSON 中还包含复杂的嵌套结构:
json
"RecipeList": [
{
"DiagnoseList": ...,
"FeeList": ...,
"RecipeNo": "...",
...
}
]
请确保你的 Recipe 类以及 Diagnose、Fee 等内部类也遵循同样的原则:
如果它们的字段名也是大写字母开头(如 RecipeNo, DiagCode),务必在这些类中也添加 @JsonProperty 注解。否则,会遇到类似的 Unrecognized field "RecipeNo" 错误。
总结操作步骤
打开 TsbFeeImportInParam.java。
为所有字段添加 @JsonProperty("JSON中的确切键名") 注解。
检查 Recipe.java 及其内部引用的类(如 Diagnose, FeeItem 等),同样为它们的字段添加 @JsonProperty 注解,确保与 JSON 中的键名完全一致(包括大小写)。
重新编译并启动项目,再次使用 Postman 测试。
这样即可彻底解决 UnrecognizedPropertyException 问题。