Java jackson常用注解汇总
提起 jackson
,在日常使用中,由于涉及到各种序列化和反序列化的处理,就不能不提 注解
,了解注解的常用方式可以极大地方便我们处理序列化,今天分享一些在使用 jackson 中涉及到的注解。
1.@JsonProperty
- 字段命名2.@JsonPropertyOrder
- 字段序列化顺序3.@JsonAlias
- 字段别名,反序列化4.@JsonIgnore
-序列化时忽略字段5.@JsonIgnoreProperties
- 序列化时忽略某些字段6.@JsonInclude
- 序列化时作用于满足条件的7.@JsonFormat
- 设置格式,如日期时间等8.@JacksonInject
- 反序列化时注入到 java 对象9.@JsonCreator && @ConstructorProperties
- 反序列化时采用的构造方法10.@JsonSerialize && @JsonDeserialize
- 自定义序列化方法11.@JsonAnyGetter && @JsonANySetter
- 序列化对map字段的处理12.@JsonNaming
- 序列化时输出格式13.staic 和 transient 字段
1.@JsonProperty
- 字段命名
@JsonProperty
注解用于在序列化时按照给定的字段名命名,在反序列化时,在 json 串中的注解字段给该字段设置属性值。
下面是注解的简单示例:
package org.example; import com.fasterxml.jackson.annotation.JsonProperty; public class PersonProperty { @JsonProperty("first_name") private String firstName; public PersonProperty() { } public String getFirstName() { return firstName; } public void setFirstName(String firstName) { this.firstName = firstName; } } --- public static void jsonPropertyDemo() { ObjectMapper objectMapper = new ObjectMapper(); PersonProperty pp = new PersonProperty(); pp.setFirstName("Alice"); String jsonString = null; try { jsonString = objectMapper.writeValueAsString(pp); System.out.println("json property: " + jsonString); } catch (Exception e) { e.printStackTrace(); } try { PersonProperty pp1 = objectMapper.readValue(jsonString, PersonProperty.class); System.out.println(pp1.getFirstName()); } catch (Exception e) { e.printStackTrace(); } } ---
2.@JsonPropertyOrder
- 字段序列化顺序
@JsonPropertyOrder
加在类上,用以规定数据序列化时字段出现的顺序。
package org.example; import com.fasterxml.jackson.annotation.JsonPropertyOrder; // {"name":"Bob","id":"111","age":25,"phone":"12345678910"} @JsonPropertyOrder({"name", "id", "age", "phone"}) // 没有定义顺序,就按照字典序排列,{"age":25,"id":"111","name":"Bob","phone":"12345678910"} // @JsonPropertyOrder(alphabetic = true) public class PersonPropertyOrder { private String id; private String name; private int age; private String phone; public PersonPropertyOrder() { } 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; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String getPhone() { return phone; } public void setPhone(String phone) { this.phone = phone; } } --- public static void jsonPropertyOrder() { ObjectMapper objectMapper = new ObjectMapper(); PersonPropertyOrder ppo = new PersonPropertyOrder(); ppo.setAge(25); ppo.setId("111"); ppo.setName("Bob"); ppo.setPhone("12345678910"); String jsonString = null; try { jsonString = objectMapper.writeValueAsString(ppo); System.out.println("json property: " + jsonString); } catch (Exception e) { e.printStackTrace(); } } ---
3.@JsonAlias
- 字段别名,反序列化
在数据反序列化时,通过 @JsonAlias
注解来设置字段的值,只要是 alias中的和字段本身都可以正常反序列化。
package org.example; import com.fasterxml.jackson.annotation.JsonAlias; public class PersonAlias { @JsonAlias({"firstName", "personName"}) private String name; public PersonAlias() { } public String getName() { return name; } public void setName(String name) { this.name = name; } } --- public static void jsonAlias() { String jsonString1 = "{"name":"Bob"}"; String jsonString2 = "{"firstName":"Bob"}"; String jsonString3 = "{"personName":"Bob"}"; ObjectMapper objectMapper = new ObjectMapper(); try { PersonAlias p1 = objectMapper.readValue(jsonString1, PersonAlias.class); PersonAlias p2 = objectMapper.readValue(jsonString2, PersonAlias.class); PersonAlias p3 = objectMapper.readValue(jsonString3, PersonAlias.class); System.out.printf("p1: %s, p2: %s, p3: %s", p1.getName(),p2.getName(), p3.getName()); } catch (Exception e) { e.printStackTrace(); } } ---
4.@JsonIgnore
-序列化时忽略字段
@JsonIgnore
加在字段上,用以在序列化时,忽略其,在反序列化时,仅赋值null。
package org.example; import com.fasterxml.jackson.annotation.JsonIgnore; public class PersonIgnore { private String name; @JsonIgnore // 不将其序列化,忽略该字段 private String[] hobbies; public PersonIgnore() { } public String getName() { return name; } public void setName(String name) { this.name = name; } public String[] getHobbies() { return hobbies; } public void setHobbies(String[] hobbies) { this.hobbies = hobbies; } } --- public static void jsonIgnore() { ObjectMapper objectMapper = new ObjectMapper(); String jsonString = null; try { PersonIgnore pi = new PersonIgnore(); pi.setName("Cathy"); pi.setHobbies(null); jsonString = objectMapper.writeValueAsString(pi); System.out.println(jsonString); } catch (Exception e) { e.printStackTrace(); } } ---
5.@JsonIgnoreProperties
- 序列化时忽略某些字段
@JsonIgnoreProperties
加在类上,用于在序列化时,忽略给定的某些字段。
package org.example; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; @JsonIgnoreProperties({"age"}) public class PersonIgnoreProperties { private String name = "Alice"; private int age; public PersonIgnoreProperties() { } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } } --- public static void jsonIgnoreProperties() { ObjectMapper objectMapper = new ObjectMapper(); PersonIgnoreProperties pip = new PersonIgnoreProperties(); pip.setName("Bob"); pip.setAge(18); try { String jsonString = objectMapper.writeValueAsString(pip); System.out.println(jsonString); } catch (Exception e) { e.printStackTrace(); } } ---
6.@JsonInclude
- 序列化时作用于满足条件的
@JsonInclude
可以加在类上,也可以加在字段上。该注解表示满足某些条件(
NON_NULL,
NON_ABSENT,
NON_EMPTY,
NON_DEFAULT,
等)的才能序列化,e.g.如果加在类上,表示只要对象有null 就忽略该对象,加在字段上,如果字段是null,则忽略该字段。
package org.example; import com.fasterxml.jackson.annotation.JsonInclude; @JsonInclude(JsonInclude.Include.NON_NULL) public class PersonInclude { private int id; private String name; @JsonInclude(JsonInclude.Include.NON_NULL) private String[] hobbies; public PersonInclude() { } public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String[] getHobbies() { return hobbies; } public void setHobbies(String[] hobbies) { this.hobbies = hobbies; } } --- public static void jsonInclude() { ObjectMapper objectMapper = new ObjectMapper(); PersonInclude pi = new PersonInclude(); pi.setName("Cathy"); pi.setId(1111); try { String jsonString = objectMapper.writeValueAsString(pi); System.out.println(jsonString); } catch (Exception e) { e.printStackTrace(); } } ---
7.@JsonFormat
- 设置格式,如日期时间等
用于设置时间格式,或者是数字,或者是日期格式。
package org.example; import com.fasterxml.jackson.annotation.JsonFormat; import java.time.LocalDate; import java.util.Date; public class PersonFormat { @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd hh:mm:ss", timezone = "GMT+8") private Date birthDate; public PersonFormat() { } public Date getBirthDate() { return birthDate; } public void setBirthDate(Date birthDate) { this.birthDate = birthDate; } } --- public static void jsonFormat() { ObjectMapper objectMapper = new ObjectMapper(); PersonFormat pf = new PersonFormat(); pf.setBirthDate(new Date()); try { String jsonString = objectMapper.writeValueAsString(pf); System.out.println(jsonString); } catch (Exception e) { e.printStackTrace(); } } ---
8.@JacksonInject
- 反序列化时注入到 java 对象
该注解用于在数据反序列化时将其他字段注入进 Java对象。
package org.example; import com.fasterxml.jackson.annotation.JacksonInject; import java.time.LocalDate; import java.time.LocalDateTime; public class PersonInject { private String name; private int age; @JacksonInject("responseTime") private LocalDateTime responseTime; public PersonInject() { } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public LocalDateTime getResponseTime() { return responseTime; } public void setResponseTime(LocalDateTime responseTime) { this.responseTime = responseTime; } } --- public static void jsonInject() { InjectableValues.Std iv = new InjectableValues.Std(); ObjectMapper objectMapper = new ObjectMapper(); iv.addValue("responseTime", LocalDateTime.now()); //将JSON字符串反序列化为java对象 String jsonString = "{"name":"Alice","age":23}"; objectMapper.setInjectableValues(iv); try { PersonInject pi = objectMapper.readValue(jsonString, PersonInject.class); System.out.println(pi.getResponseTime()); } catch (Exception e) { e.printStackTrace(); } } ---
9.@JsonCreator && @ConstructorProperties
- 反序列化时采用的构造方法
@JsonCreator
用于在json数据反序列化到实例对象时采用哪个构造方法,同时搭配 @JsonProperty
注解用于相关属性的。
package org.example; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.databind.ObjectMapper; public class PersonCreator { private String name; private int age; // 构造方法1 public PersonCreator(String name) { this.name = name; } // 构造方法2 @JsonCreator // 用于反序列化时的处理 public PersonCreator(@JsonProperty("username") String name, @JsonProperty("age") int age) { this.name = name; this.age = age; } @Override public String toString() { return "Test{" + "name='" + name + ''' + ", age='" + age + ''' + '}'; } public static void main(String[] args) throws Exception { String jsonString = "{"username": "Alice", "age": 18}"; // username -> name ObjectMapper objectMapper = new ObjectMapper(); try { PersonCreator pc = objectMapper.readValue(jsonString, PersonCreator.class); System.out.println(pc); } catch (Exception e) { e.printStackTrace(); } } }
@ConstructorProperties
也用于构造方法,但相比 @JsonCreator
的使用要简单,可以认为 @ConstructorProperties = @JsonCreator + @JsonProperty
。
package org.example; import com.fasterxml.jackson.databind.ObjectMapper; import java.beans.ConstructorProperties; public class PersonConstructorProperties { private String username; private int age; public PersonConstructorProperties(String username) { this.username = username; } @ConstructorProperties({"name", "age"}) public PersonConstructorProperties(String username, int age) { System.out.println("全参构造函数..."); this.username = username; this.age = age; } @Override public String toString() { return "Test{" + "username='" + username + ''' + ", age='" + age + ''' + '}'; } public static void main(String[] args) { String jsonString = "{"name": "Bob", "age": 29}"; ObjectMapper objectMapper = new ObjectMapper(); try { PersonConstructorProperties pcp = objectMapper.readValue(jsonString, PersonConstructorProperties.class); System.out.println(pcp); } catch (Exception e) { e.printStackTrace(); } } }
10.@JsonSerialize && @JsonDeserialize
- 自定义序列化方法
这两个注解用于实现自定义的序列化和反序列化的处理,比如我们有个需求,需要将小数的某个字段规定精确位数,为空时输出空字符串。
@JsonSerialize
package org.example; import com.fasterxml.jackson.core.JsonGenerator; import com.fasterxml.jackson.databind.JsonSerializer; import com.fasterxml.jackson.databind.SerializerProvider; import com.fasterxml.jackson.databind.annotation.JsonSerialize; import java.io.IOException; import java.math.RoundingMode; import java.text.DecimalFormat; public class PersonSerialize { @JsonSerialize(using = CustomDoubleSerialize.class, nullsUsing = NullNumberSerialize.class) private Double model; @JsonSerialize(nullsUsing = NullNumberSerialize.class) private Double business; private String name; public PersonSerialize() { } public Double getModel() { return model; } public void setModel(Double model) { this.model = model; } public Double getBusiness() { return business; } public void setBusiness(Double business) { this.business = business; } public String getName() { return name; } public void setName(String name) { this.name = name; } } /** * Double保留4位小数,输出string */ class CustomDoubleSerialize extends JsonSerializer<Double> { private static final DecimalFormat df = new DecimalFormat("#.####"); @Override public void serialize(Double value, JsonGenerator gen, SerializerProvider serializers) throws IOException { df.setRoundingMode(RoundingMode.HALF_UP); // 4 gen.writeString(df.format(value)); } } /** * 任意类型null值,改为空字符串输出 */ class NullNumberSerialize extends JsonSerializer<Object> { @Override public void serialize(Object value, JsonGenerator gen, SerializerProvider serializers) throws IOException { gen.writeString(""); } } --- public static void jsonSerialize() { ObjectMapper objectMapper = new ObjectMapper(); PersonSerialize ps = new PersonSerialize(); ps.setName("Alice"); ps.setModel(1.2345678); try { String jsonString = objectMapper.writeValueAsString(ps); System.out.println(jsonString); // {"model":"1.2346","business":"","name":"Alice"} } catch (Exception e) { e.printStackTrace(); } } ---
@JsonDeserialize
package org.example; import com.fasterxml.jackson.core.JsonGenerator; import com.fasterxml.jackson.core.JsonParser; import com.fasterxml.jackson.databind.DeserializationContext; import com.fasterxml.jackson.databind.JsonDeserializer; import com.fasterxml.jackson.databind.JsonSerializer; import com.fasterxml.jackson.databind.SerializerProvider; import com.fasterxml.jackson.databind.annotation.JsonDeserialize; import com.fasterxml.jackson.databind.annotation.JsonSerialize; import java.io.IOException; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; import java.time.format.FormatStyle; public class PersonDeserialize { @JsonSerialize(using = LocalDatetimeSerialize.class) @JsonDeserialize(using = LocalDatetimeDeserialize.class) private LocalDateTime birthDate; private String name; public PersonDeserialize() { } public LocalDateTime getBirthDate() { return birthDate; } public void setBirthDate(LocalDateTime birthDate) { this.birthDate = birthDate; } public String getName() { return name; } public void setName(String name) { this.name = name; } } class LocalDatetimeSerialize extends JsonSerializer<LocalDateTime> { static final DateTimeFormatter DATE_FORMATTER = DateTimeFormatter.ofLocalizedDateTime(FormatStyle.MEDIUM); @Override public void serialize(LocalDateTime value, JsonGenerator gen, SerializerProvider provider) throws IOException { String str = value.format(DATE_FORMATTER); gen.writeString(str); } } class LocalDatetimeDeserialize extends JsonDeserializer<LocalDateTime> { @Override public LocalDateTime deserialize(JsonParser p, DeserializationContext ctx) throws IOException { String str = p.getText(); return LocalDateTime.parse(str, LocalDatetimeSerialize.DATE_FORMATTER); } } --- public static void jsonDeserialize() { ObjectMapper objectMapper = new ObjectMapper(); PersonDeserialize pd = new PersonDeserialize(); pd.setName("Dav"); pd.setBirthDate(LocalDateTime.of(2000, 12, 5, 0, 0)); String jsonString = null; // serialize try { jsonString = objectMapper.writeValueAsString(pd); System.out.println(jsonString); // {"birthDate":"2000年12月5日 00:00:00","name":"Dav"} } catch (Exception e) { e.printStackTrace(); } // deserialize try { PersonDeserialize pd1 = objectMapper.readValue(jsonString, PersonDeserialize.class); // person -> name: Dav, birthdate: 2000-12-05T00:00 System.out.printf("person -> name: %s, birthdate: %s\n", pd1.getName(), pd1.getBirthDate()); } catch (Exception e) { e.printStackTrace(); } } ---
11.@JsonAnyGetter && @JsonANySetter
- 序列化对map字段的处理
这两个注解用于在序列化和反序列化时 map 结构的处理,具体说来:
- @JsonAnyGetter,加在 getField() 上,用于序列化时将此map字段的键值对移至json中的键值对
- @JsonAnySetter,加在字段上或者 setField() 都可以,加一个即可,用于反序列化时构造类实例,设置类实例属性,将json中的非明确定义的键值对都设置到map结构的字段中
package org.example; import com.fasterxml.jackson.annotation.JsonAnyGetter; import com.fasterxml.jackson.annotation.JsonAnySetter; import java.util.HashMap; import java.util.Map; public class PersonGetAndSet { private String username; private String pwd; private int age; // @JsonAnySetter // 加方法或者属性都可以,但1个即可 private Map<String, String> map; public PersonGetAndSet() { this.map = new HashMap<>(); } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPwd() { return pwd; } public void setPwd(String pwd) { this.pwd = pwd; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } @JsonAnyGetter // serialize, {"username":"Ada","pwd":"123456","age":26,"key1":"val1","key2":"val2"} public Map<String, String> getMap() { return map; } @JsonAnySetter // deserialize, pwd: 123456, age: 26, map: {key1=val1, key2=val2} public void setMap(String key, String value) { this.map.put(key, value); } } --- public static void jsonGetterAndSetter() { PersonGetAndSet pgs = new PersonGetAndSet(); pgs.setUsername("Ada"); pgs.setAge(26); pgs.setPwd("123456"); pgs.setMap("key1", "val1"); pgs.setMap("key2", "val2"); ObjectMapper objectMapper = new ObjectMapper(); String jsonString = null; try { jsonString = objectMapper.writeValueAsString(pgs); System.out.println(jsonString); } catch (Exception e) { e.printStackTrace(); } try { PersonGetAndSet pgs1 = objectMapper.readValue(jsonString, PersonGetAndSet.class); System.out.printf("person -> username: %s, pwd: %s, age: %d, map: %s\n", pgs1.getUsername(), pgs1.getPwd(), pgs1.getAge(), pgs1.getMap()); } catch (Exception e) { e.printStackTrace(); } } ---
12.@JsonNaming
- 序列化时输出格式
@JsonNaming
加在类上,用以规范序列化时输出的字段键值的形式,主要有以下格式:
- SnakeCaseStrategy, 蛇形体, 如 first_name
- UpperCamelCaseStrategy, 大写驼峰体,如 FirstName
- LowerCaseStratey, 小写连体,如 firstname
- LowerDotCaseStratey, 小写点分,如 first.name
package org.example; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.PropertyNamingStrategy; import com.fasterxml.jackson.databind.annotation.JsonNaming; //@JsonNaming(value = PropertyNamingStrategy.SnakeCaseStrategy.class) // 蛇形体:{"first_name":"Matt","second_name":"Damon"} //@JsonNaming(value = PropertyNamingStrategy.UpperCamelCaseStrategy.class) // {"FirstName":"Matt","SecondName":"Damon"} //@JsonNaming(value = PropertyNamingStrategy.LowerCaseStrategy.class) // {"firstname":"Matt","secondname":"Damon"} @JsonNaming(value = PropertyNamingStrategy.LowerDotCaseStrategy.class) // {"first.name":"Matt","second.name":"Damon"} public class PersonNaming { private String firstName; private String secondName; public PersonNaming() { } public PersonNaming(String firstName, String secondName) { this.firstName = firstName; this.secondName = secondName; } public String getFirstName() { return firstName; } public void setFirstName(String firstName) { this.firstName = firstName; } public String getSecondName() { return secondName; } public void setSecondName(String secondName) { this.secondName = secondName; } public static void main(String[] args) { PersonNaming pn = new PersonNaming(); pn.setFirstName("Matt"); pn.setSecondName("Damon"); ObjectMapper objectMapper = new ObjectMapper(); try { String jsonString = objectMapper.writeValueAsString(pn); System.out.println(jsonString); } catch (Exception e) { e.printStackTrace(); } } }
13.staic 和 transient 字段
如果字段属性中有这两个修饰符,则在序列化处理时忽略相关字段。
参考:
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 【杭电多校比赛记录】2025“钉耙编程”中国大学生算法设计春季联赛(1)
2021-11-08 0020-leetcode算法实现之有效括号-valid-parentheses-python&golang实现
2021-11-08 0232-leetcode算法实现-用栈实现队列-implement-queue-using-stacks-python&golang实现