传参请求时jackson大小写取值异常和序列化多出一个属性的问题学习记录

本文记录了在使用Jackson进行参数请求时遇到的大写属性取值异常和序列化出现多余属性的问题。问题源于Jackson识别字段和方法时的规则,解决方案是使用@JsonProperty指定JSON名称。在序列化过程中,由于属性和getter/setter的识别规则,可能导致属性重复。IDE如IDEA在生成get/set方法时,会避免此类问题,但手动编写时需要注意首字母大小写的规范,以防止序列化歧义。

在开发业务中有一个请求接受实体大致如下:

@Data
public class ActivityAddQuery {
   
   
    /**
     * a类标签
     */
    @NotBlank(message="a类标签不能为空")
    @Length(max=64,message = "")
    private String aLabel;
    }

在前端请求参数设置为{“aLabel”:“aaa”}时后端接受到的参数一直为空,查询资料发现,spring的jackson参数发现顺序,依次如下:
1.所有被public修饰的字段;
2.所有被public修饰的getter;
3.所有被public修饰的setter。
由于aLabel被设置成private,不符合第1条,到了第二条得到的是getALabel()方法,jackson不知道第一个A是大写还是小写,默认将从第一个大写开始的所有大写字母识别成小写,即alabel,读取setALabel()也一样。例如属性aLLbel也会由getALLabel()识别成allbel。
解决方案: 添加@JsonProperty(“aLabel”)指定json名称即可。

@Data
public class ActivityAddQuery {
   
   
    /**
     * a类标签
     */
    @JsonProperty("aLabel")
    private String aLabel;
    }

想要知道原因,首先查看编译之后的的class为

@Data
public class ActivityAddQuery {
   
   
    /**
     * a类标签
     */
    @JsonProperty("aLabel")
    private String aLabel;
   
	 public String getALabel() {
   
   
            return this.aLabel;
     }

     @JsonProperty
<think>好的,用户的问题是关于如何在Java后端设置实体类属性,以确保序列化与反序列化大小写一致性。我需要结合提供的引用内容来解答这个问题。 首先,用户提到的是实体类属性序列化序列化大小写问题。根据引用中的信息,有几种注解可以使用,比如@JsonProperty、@JsonSerialize@JSONField。其中,引用[3]提到@JsonProperty可以用来处理字段名序列化为首字母大写的问题,同解决字段重复的问题。这可能与用户的问题相关,因为用户需要确保大小写一致性。 接下来,引用[2][4]讨论了使用不同的注解来控制序列化字段,比如@JSONField(serialize = false)可以阻止某个字段被序列化,而JSONUtil工具类用于转换对象JSON字符串。用户的问题可能涉及到如何配置这些注解来保持属性名在序列化后的JSON中的大小写。 然后,我需要考虑常见的解决方案。通常,JacksonFastjson是常用的库,它们的注解可能不同。例如,Jackson使用@JsonProperty来指定序列化的名称,而Fastjson使用@JSONField。用户需要明确使用的是哪个库,但问题中并没有明确说明,所以可能需要给出两种库的解决方案。 此外,引用[3]中的问题提到,当使用@JsonProperty序列化,可能会出现字段重复的问题,特别是当属性名首字母大写。这可能是因为JavaBean的规范导致getter方法生成了重复的字段。因此,需要配置对象映射器来禁用基于getter的自动检测,或者使用特定的注解来避免这种情况。 总结一下,用户的解决方案可能包括以下步骤: 1. 使用合适的注解(如@JsonProperty或@JSONField)明确指定JSON字段名。 2. 配置序列化库(如Jackson或Fastjson)以禁用某些自动功能,比如基于getter的方法。 3. 统一命名策略,例如使用小写加下划线的策略,并在实体类属性上使用对应的注解。 4. 在全局配置中设置统一的命名策略,确保所有序列化序列化操作遵循相同的规则。 还需要注意用户提到的示例代码中,UserDemo类有一个Method类型的属性,这在序列化可能会出现问题,但用户的问题主要集中在大小写一致性,因此可能需要提醒用户注意复杂类型的序列化问题,但这可能超出当前问题的范围。 最后,生成的相关问题需要围绕序列化配置的其他方面,比如处理字段排除、不同库的注解差异、性能影响以及处理特殊字符等。</think>在Java后端开发中,通过注解配置实体类属性实现序列化/反序列化大小写一致性,可采用以下方案: ### 一、核心注解配置 1. **Jackson库方案** - 使用`@JsonProperty`显式声明JSON字段名 ```java public class UserDemo { @JsonProperty("UserName") private String userName; // 序列化为"UserName" } ``` - 通过`@JsonAutoDetect`关闭自动检测(引用[3]问题的解决方案) ```java @JsonAutoDetect(fieldVisibility = Visibility.ANY, getterVisibility = Visibility.NONE) ``` 2. **Fastjson方案** - 使用`@JSONField`注解指定字段名 ```java public class UserDemo { @JSONField(name = "UserAge") private int userAge; // 序列化为"UserAge" } ``` ### 二、全局命名策略(以Jackson为例) ```java ObjectMapper mapper = new ObjectMapper() .setPropertyNamingStrategy(PropertyNamingStrategies.UPPER_CAMEL_CASE); // 采用大驼峰命名 ``` 此`userName`将序列化为`UserName`,与反序列化自动匹配[^2][^4] ### 三、注意事项 1. **禁用getter自动生成字段** 在`application.properties`添加: ```properties spring.jackson.mapper.auto-detect-getters=false ``` 避免因getter方法导致字段重复(引用[3]问题的核心解决方案) 2. **字段类型兼容性** 如引用[1]中的`Method`类型字段需特别注意,非基础类型建议添加`@JsonIgnore`排除序列化 3. **混合注解冲突** 避免同使用`@JsonProperty``@JSONField`,不同库注解混用会导致不可预期行为 ### 四、验证方法 使用引用[4]的JSON工具类进行测试: ```java UserDemo user = new UserDemo("test"); String json = JSONUtil.toJsonStr(user); // 应输出{"UserName":"test"} UserDemo obj = JSONUtil.toBean(json, UserDemo.class); // 成功反序列化 ```
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值