Jackson 2.12.4中匹配的JSON与Java字段为何仍需@JsonProperty注解
问题根因
你遇到的冗余注解需求本质是Jackson默认的字段可见性规则限制,结合当前使用的Jersey默认Jackson配置未做自定义优化导致的,具体原因如下:
- Jackson默认只会自动序列化/反序列化两类字段:
- 访问修饰符为
public的类字段 - 非
public但提供了符合JavaBean规范的public getter、setter方法的字段
- 访问修饰符为
- 你代码里的
id、name字段都是包私有访问权限(未加访问修饰符),也没有对应public getter/setter,默认情况下Jackson无法识别这些字段,必须加@JsonProperty注解强制Jackson访问该字段 - 你之前的旧版本项目能省略注解,大概率是旧项目做过以下任意一种配置:全局修改了ObjectMapper的字段可见性规则、所有实体字段都加了public getter/setter、使用的框架(如Spring)自动帮你配置了可见性规则,而Jersey默认引入的Jackson配置没有做这类调整。
解决方案
你可以根据项目需求任选一种方案,都可以省略冗余的@JsonProperty注解:
方案1:遵循JavaBean规范
给所有需要序列化/反序列化的字段添加public getter、setter方法,示例:
@JsonIgnoreProperties(ignoreUnknown = true) public class Location { String id; String name; public String getId() {return id;} public void setId(String id) {this.id = id;} public String getName() {return name;} public void setName(String name) {this.name = name;} }
方案2:给单个实体类加可见性注解
直接给实体类添加@JsonAutoDetect注解,指定字段可见性为任意级别,不需要修改全局配置:
@JsonIgnoreProperties(ignoreUnknown = true) @JsonAutoDetect(fieldVisibility = JsonAutoDetect.Visibility.ANY) public class Location { String id; String name; // 其余代码省略 }
方案3:全局配置Jersey的Jackson规则
自定义Jackson提供器,修改全局ObjectMapper的可见性规则,所有实体类都可以省略冗余注解:
- 编写自定义的Jackson提供器
import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.PropertyAccessor; import com.fasterxml.jackson.annotation.JsonAutoDetect; import org.glassfish.jersey.jackson.JacksonJaxbJsonProvider; import javax.ws.rs.ext.Provider; @Provider public class CustomJacksonProvider extends JacksonJaxbJsonProvider { public CustomJacksonProvider() { ObjectMapper mapper = new ObjectMapper(); // 允许Jackson访问任意访问级别的字段 mapper.setVisibility(PropertyAccessor.FIELD, JsonAutoDetect.Visibility.ANY); // 保留忽略未知属性的配置 mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); setMapper(mapper); } }
- 将这个提供器注册到你的Jersey配置类中即可生效。
内容的提问来源于stack exchange,提问作者djna
相关产品推荐
相关产品推荐

