使用ProGuard时Jackson序列化数据异常,字段名被混淆
Jackson+JsonProperty开启ProGuard后字段名混淆的解决办法
问题描述
我使用com.fasterxml.jackson库的ObjectMapper结合@JsonProperty注解开发,开启ProGuard后生成的JSON字段被混淆成a、b这类短名称,无法得到预期的结构化JSON。
混淆后生成的JSON:
{"a":{"a":"Oneil Hooper","b":""},"b":[{"a":"1656952356532","b":0,"q":""} ],"c":["+1986535623355"]}
预期的JSON结构:
{"displayName":{"name":"Oneil Hooper","surname":""},"b":[{"phoneNumber":"+1656952356532","b":0,"q":"" }],"c":["+1986535623355"]}
当前使用的ProGuard配置:
-keep @com.fasterxml.jackson.annotation.JsonIgnoreProperties class * { *; } -keep class com.fasterxml.** { *; } -keep class org.codehaus.** { *; } -keepnames class com.fasterxml.jackson.** { *; } -keepclassmembers public final enum com.fasterxml.jackson.annotation.JsonAutoDetect$Visibility { public static final com.fasterxml.jackson.annotation.JsonAutoDetect$Visibility *; } -keep class com.fasterxml.jackson.databind.ObjectMapper { public <methods>; protected <methods>; } -keep class * implements java.io.Serializable -keep class com.fasterxml.jackson.databind.ObjectWriter { public ** writeValueAsString(**); } -dontwarn com.fasterxml.jackson.databind.** -keep class * implements com.fasterxml.jackson.core.type.TypeReference
问题根源
你的ProGuard配置仅保留了Jackson自身的类和核心方法,但未处理业务实体类的字段保留规则——标记了@JsonProperty的字段被混淆,导致Jackson无法通过反射识别到正确的字段名,只能用混淆后的短名称生成JSON。
解决方案
修改ProGuard配置,添加实体类字段保留规则,确保Jackson能正确识别注解标记的字段:
核心补充规则
# 保留所有标记@JsonProperty的字段不被混淆 -keepclassmembers class * { @com.fasterxml.jackson.annotation.JsonProperty <fields>; } # 保留实体类所在包的所有类和字段(替换成你实际的实体包路径) -keep class com.your.app.models.** { *; }
完整推荐配置
结合原有配置调整后的完整规则:
# 保留Jackson核心库不被混淆 -keep class com.fasterxml.** { *; } -keepnames class com.fasterxml.jackson.** { *; } -dontwarn com.fasterxml.jackson.databind.** # 保留Jackson注解相关枚举 -keepclassmembers public final enum com.fasterxml.jackson.annotation.JsonAutoDetect$Visibility { public static final com.fasterxml.jackson.annotation.JsonAutoDetect$Visibility *; } # 保留ObjectMapper和ObjectWriter的核心方法 -keep class com.fasterxml.jackson.databind.ObjectMapper { public <methods>; protected <methods>; } -keep class com.fasterxml.jackson.databind.ObjectWriter { public ** writeValueAsString(**); } # 保留带有Jackson注解的类和字段 -keep @com.fasterxml.jackson.annotation.JsonIgnoreProperties class * -keepclassmembers class * { @com.fasterxml.jackson.annotation.JsonProperty <fields>; @com.fasterxml.jackson.annotation.JsonIgnore <fields>; } # 保留业务实体类(替换为你项目的实体包路径) -keep class com.your.app.models.** { *; } # 保留Serializable和TypeReference实现类 -keep class * implements java.io.Serializable -keep class * implements com.fasterxml.jackson.core.type.TypeReference
关键说明
@JsonProperty标记的字段必须通过ProGuard规则保留,否则混淆后Jackson无法映射到正确的JSON键名;- 直接保留实体类所在包的所有类和字段,能彻底避免实体结构被混淆,是最稳妥的方式;
- 原有配置缺失对业务实体的保护,这是字段混淆的核心原因。
内容的提问来源于stack exchange,提问作者propoLis
相关产品推荐
相关产品推荐

