Jackson用法详解,详细解说

String json = objectMapper.writeValueAsString(car);

System.out.println(json);

运行结果:

在这里插入图片描述

2、自定义序列化

有时,想要将Java对象序列化为JSON的方式与使用Jackson的默认方式不同。 例如,可能想要在JSON中使用与Java对象中不同的字段名称,或者希望完全省略某些字段。

Jackson可以在ObjectMapper上设置自定义序列化器。 该序列化器已为某个类注册,然后在每次要求ObjectMapper序列化Car对象时将调用该序列化器。

这是为Car类注册自定义序列化器的示例:

CarSerializer carSerializer = new CarSerializer(Car.class);

ObjectMapper objectMapper = new ObjectMapper();

SimpleModule module =

new SimpleModule(“CarSerializer”, new Version(2, 1, 3, null, null, null));

module.addSerializer(Car.class, carSerializer);

objectMapper.registerModule(module);

Car car = new Car();

car.setBrand(“Mercedes”);

car.setDoors(5);

String carJson = objectMapper.writeValueAsString(car);

自定义序列化器CarSerializer类:

public class CarSerializer extends StdSerializer {

protected CarSerializer(Class t) {

super(t);

}

public void serialize(Car car, JsonGenerator jsonGenerator,

SerializerProvider serializerProvider)

throws IOException {

jsonGenerator.writeStartObject();

jsonGenerator.writeStringField(“producer”, car.getBrand());

jsonGenerator.writeNumberField(“doorCount”, car.getDoors());

jsonGenerator.writeEndObject();

}

}

运行结果:

在这里插入图片描述

三)、Jackson 日期转化


默认情况下,Jackson会将java.util.Date对象序列化为其long型的值,该值是自1970年1月1日以来的毫秒数。但是,Jackson还支持将日期格式化为字符串。

1、Date–>long

默认的Jackson日期格式,该格式将Date序列化为自1970年1月1日以来的毫秒数(long类型)。

这是一个包含Date字段的Java类示例:

private String type = null;

private Date date = null;

public Transaction() {

}

public Transaction(String type, Date date) {

this.type = type;

this.date = date;

}

public String getType() {

return type;

}

public void setType(String type) {

this.type = type;

}

public Date getDate() {

return date;

}

public void setDate(Date date) {

this.date = date;

}

就像使用其他Java对象进行序列化一样,代码如下:

Transaction transaction = new Transaction(“transfer”, new Date());

ObjectMapper objectMapper = new ObjectMapper();

String output = objectMapper.writeValueAsString(transaction);

System.out.println(output);

运行结果:

在这里插入图片描述

2、Date–>String

日期的long序列化格式不符合人类的时间查看格式。 因此,Jackson也支持文本日期格式。 可以通过在ObjectMapper上设置SimpleDateFormat来指定要使用的确切Jackson日期格式。 这是在Jackson的ObjectMapper上设置SimpleDateFormat的示例:

Transaction transaction = new Transaction(“transfer”, new Date());

ObjectMapper objectMapper = new ObjectMapper();

SimpleDateFormat dateFormat = new SimpleDateFormat(“yyyy-MM-dd”);

objectMapper.setDateFormat(dateFormat);

String output2 = objectMapper.writeValueAsString(transaction);

System.out.println(output2);

运行结果:

在这里插入图片描述

四)、Jackson JSON 树模型


Jackson具有内置的树模型,可用于表示JSON对象。 如果不知道接收到的JSON的格式,或者由于某种原因而不能(或者只是不想)创建一个类来表示它,那么就要用到Jackson的树模型。 如果需要在使用或转化JSON之前对其进行操作,也需要被用到Jackson树模型。 所有这些情况在数据流场景中都很常见。

Jackson树模型由JsonNode类表示。 您可以使用Jackson ObjectMapper将JSON解析为JsonNode树模型,就像使用您自己的类一样。

以下将展示如何使用Jackson ObjectMapper读写JsonNode实例。

1、Jackson Tree Model简单例子

下面是一个简单的例子:

String carJson =

“{ “brand” : “Mercedes”, “doors” : 5 }”;

ObjectMapper objectMapper = new ObjectMapper();

try {

JsonNode jsonNode = objectMapper.readValue(carJson, JsonNode.class);

} catch (IOException e) {

e.printStackTrace();

}

只需将JsonNode.class作为第二个参数传递给readValue()方法,而不是本教程前面的示例中使用的Car.class,就可以将JSON字符串解析为JsonNode对象而不是Car对象。 。

ObjectMapper类还具有一个特殊的readTree()方法,该方法返回JsonNode。 这是使用ObjectMapper readTree()方法将JSON解析为JsonNode的示例:

String carJson =

“{ “brand” : “Mercedes”, “doors” : 5 }”;

ObjectMapper objectMapper = new ObjectMapper();

try {

JsonNode jsonNode = objectMapper.readTree(carJson);

} catch (IOException e) {

e.printStackTrace();

}

2、Jackson JsonNode类

通过JsonNode类,可以以非常灵活和动态的方式将JSON作为Java对象导航。这里了解一些如何使用它的基础知识。

将JSON解析为JsonNode(或JsonNode实例树)后,就可以浏览JsonNode树模型。 这是一个JsonNode示例,显示了如何访问JSON字段,数组和嵌套对象:

String carJson =

“{ “brand” : “Mercedes”, “doors” : 5,” +

" “owners” : [“John”, “Jack”, “Jill”]," +

" “nestedObject” : { “field” : “value” } }";

ObjectMapper objectMapper = new ObjectMapper();

try {

JsonNode jsonNode = objectMapper.readValue(carJson, JsonNode.class);

JsonNode brandNode = jsonNode.get(“brand”);

String brand = brandNode.asText();

System.out.println("brand = " + brand);

JsonNode doorsNode = jsonNode.get(“doors”);

int doors = doorsNode.asInt();

System.out.println("doors = " + doors);

JsonNode array = jsonNode.get(“owners”);

JsonNode jsonNode = array.get(0);

String john = jsonNode.asText();

System.out.println("john = " + john);

JsonNode child = jsonNode.get(“nestedObject”);

JsonNode childField = child.get(“field”);

String field = childField.asText();

System.out.println("field = " + field);

} catch (IOException e) {

e.printStackTrace();

}

请注意,JSON字符串现在包含一个称为owners的数组字段和一个称为nestedObject的嵌套对象字段。

无论访问的是字段,数组还是嵌套对象,都可以使用JsonNode类的get()方法。 通过将字符串作为参数提供给get()方法,可以访问JsonNode的字段。 如果JsonNode表示数组,则需要将索引传递给get()方法。 索引指定要获取的数组元素。

3、Java对象–>JsonNode

可以使用Jackson ObjectMapper将Java对象转换为JsonNode,而JsonNode是转换后的Java对象的JSON表示形式。 可以通过Jackson ObjectMapper valueToTree()方法将Java对象转换为JsonNode。 这是一个使用ObjectMapper valueToTree()方法将Java对象转换为JsonNode的示例:

ObjectMapper objectMapper = new ObjectMapper();

Car car = new Car();

car.brand = “Cadillac”;

car.doors = 4;

JsonNode carJsonNode = objectMapper.valueToTree(car);

4、JsonNode–>Java对象

可以使用Jackson ObjectMapper treeToValue()方法将JsonNode转换为Java对象。 这类似于使用Jackson Jackson的ObjectMapper将JSON字符串(或其他来源)解析为Java对象。 唯一的区别是,JSON源是JsonNode。 这是一个使用Jackson ObjectMapper treeToValue()方法将JsonNode转换为Java对象的示例:

ObjectMapper objectMapper = new ObjectMapper();

String carJson = “{ “brand” : “Mercedes”, “doors” : 5 }”;

JsonNode carJsonNode = objectMapper.readTree(carJson);

Car car = objectMapper.treeToValue(carJsonNode);

上面的示例有点“人为”,因为我们首先将JSON字符串转换为JsonNode,然后将JsonNode转换为Car对象。 显然,如果我们有对原始JSON字符串的引用,则最好将其直接转换为Car对象,而无需先将其转换为JsonNode。

四、JsonNode

============================================================================

Jackson JsonNode类com.fasterxml.jackson.databind.JsonNode是Jackson的JSON树形模型(对象图模型)。 Jackson可以将JSON读取到JsonNode实例中,然后将JsonNode写入JSON。 因此,这一节将说明如何将JSON反序列化为JsonNode以及将JsonNode序列化为JSON。 此Jackson JsonNode教程还将说明如何从头开始构建JsonNode对象图,因此以后可以将它们序列化为JSON。

1、JsonNode vs ObjectNode


Jackson JsonNode类是不可变的。 这意味着,实际上不能直接构建JsonNode实例的对象图。 而是创建JsonNode子类ObjectNode的对象图。 作为JsonNode的子类,可以在可以使用JsonNode的任何地方使用ObjectNode。

2、JSON–>JsonNode


要使用Jackson将JSON读取到JsonNode中,首先需要创建一个Jackson ObjectMapper实例。 在ObjectMapper实例上,调用readTree()并将JSON源作为参数传递。 这是将JSON反序列化为JsonNode的示例:

String json = "{ “f1” : “v1” } ";

ObjectMapper objectMapper = new ObjectMapper();

JsonNode jsonNode = objectMapper.readTree(json);

System.out.println(jsonNode.get(“f1”).asText());

3、JsonNode–>JSON


要将Jackson的JsonNode写入JSON,还需要一个Jackson ObjectMapper实例。 在ObjectMapper上,调用writeValueAsString()方法或任何适合需要的写入方法。 这是将JsonNode写入JSON的示例:

ObjectMapper objectMapper = new ObjectMapper();

JsonNode jsonNode = readJsonIntoJsonNode();

String json = objectMapper.writeValueAsString(jsonNode);

4、获取JsonNode字段


JsonNode可以像JSON对象一样具有字段。 假设已将以下JSON解析为JsonNode:

{

“field1” : “value1”,

“field2” : 999

}

此JSON对象具有两个名为field1和field2的字段。 如果有一个表示上述JSON对象的Jackson JsonNode,则可以这样获得两个字段:

JsonNode jsonNode = … //parse above JSON into a JsonNode

JsonNode field1 = jsonNode.get(“field1”);

JsonNode field2 = jsonNode.get(“field2”);

请注意,即使两个字段都是String字段,get()方法也始终返回JsonNode来表示该字段。

5、在路径中获取JsonNode字段


Jackson JsonNode有一个称为at()的特殊方法。 at()方法可以从JSON图中以给定JsonNode为根的任何位置访问JSON字段。 假设JSON结构如下所示:

{

“identification” : {

“name” : “James”,

"ssn: “ABC123552”

}

}

如果将此JSON解析为JsonNode,则可以使用at()方法访问名称字段,如下所示:

JsonNode nameNode = jsonNode.at(“/identification/name”);

注意传递给at()方法的参数:字符串/ identification / name。 这是一个JSON路径表达式。 此路径表达式指定从根JsonNode到您要访问其值的字段的完整路径。 这类似于从文件系统根目录到Unix文件系统中文件的路径。

请注意,JSON路径表达式必须以斜杠字符(/字符)开头。

at()方法返回一个JsonNode,它表示请求的JSON字段。 要获取该字段的实际值,需要调用下一部分介绍的方法之一。 如果没有节点与给定的路径表达式匹配,则将返回null。

6、转换JsonNode字段


Jackson JsonNode类包含一组可以将字段值转换为另一种数据类型的方法。 例如,将String字段值转换为long或相反。 这是将JsonNode字段转换为一些更常见的数据类型的示例:

String f2Str = jsonNode.get(“f2”).asText();

double f2Dbl = jsonNode.get(“f2”).asDouble();

int f2Int = jsonNode.get(“f2”).asInt();

long f2Lng = jsonNode.get(“f2”).asLong();

使用默认值转换:

如果JsonNode中的字段可以为null,则在尝试转换它时可以提供默认值。 这是使用默认值调用转换方法的示例:

ObjectMapper objectMapper = new ObjectMapper();

String json = “{ “f1”:“Hello”, “f2”:null }”;

JsonNode jsonNode = objectMapper.readTree(json);

String f2Value = jsonNode.get(“f2”).asText(“Default”);

在示例的JSON字符串中可以看到,声明了f2字段,但将其设置为null。 在这种情况下,调用jsonNode.get(“ f2”)。asText(“ Default”)将返回默认值,在此示例中为字符串Default。

asDouble(),asInt()和asLong()方法还可以采用默认参数值,如果尝试从中获取值的字段为null,则将返回默认参数值。

请注意,如果该字段在JSON中未显式设置为null,但在JSON中丢失,则调用jsonNode.get(“ fieldName”)将返回Java null值,您无法在该Java值上调用asInt() ,asDouble(),asLong()或asText()。 如果尝试这样做,将会导致NullPointerException。 这是说明这种情况的示例:

ObjectMapper objectMapper = new ObjectMapper();

String json = “{ “f1”:“Hello” }”;

JsonNode jsonNode = objectMapper.readTree(json);

JsonNode f2FieldNode = jsonNode.get(“f2”);

7、创建一个ObjectNode


如前所述,JsonNode类是不可变的。 要创建JsonNode对象图,必须能够更改图中的JsonNode实例,例如 设置属性值和子JsonNode实例等。由于是不可变的,因此无法直接使用JsonNode来实现。

而是创建一个ObjectNode实例,该实例是JsonNode的子类。 这是一个通过Jackson ObjectMapper createObjectNode()方法创建ObjectNode的示例:

ObjectMapper objectMapper = new ObjectMapper();

ObjectNode objectNode = objectMapper.createObjectNode();

8、Set ObjectNode字段


要在Jackson ObjectNode上设置字段,可以调用其set()方法,并将字段名称String和JsonNode作为参数传递。 这是在Jackson的ObjectNode上设置字段的示例:

ObjectMapper objectMapper = new ObjectMapper();

ObjectNode parentNode = objectMapper.createObjectNode();

JsonNode childNode = readJsonIntoJsonNode();

parentNode.set(“child1”, childNode);

9、Put ObjectNode字段


ObjectNode类还具有一组方法,可以直接为字段put(设置)值。 这比尝试将原始值转换为JsonNode并使用set()进行设置要容易得多。 以下是使用put()方法为ObjectNode上的字段设置字符串值的示例:

objectNode.put(“field1”, “value1”);

objectNode.put(“field2”, 123);

objectNode.put(“field3”, 999.999);

10、删除字段


ObjectNode类具有一个称为remove()的方法,该方法可用于从ObjectNode中删除字段。 这是一个通过其remove()方法从Jackson ObjectNode删除字段的示例:

objectNode.remove(“fieldName”);

11、循环JsonNode字段


JsonNode类具有一个名为fieldNames()的方法,该方法返回一个Iterator,可以迭代JsonNode的所有字段名称。 我们可以使用字段名称来获取字段值。 这是一个迭代Jackson JsonNode的所有字段名称和值的示例:

Iterator fieldNames = jsonNode.fieldNames();

while(fieldNames.hasNext()) {

String fieldName = fieldNames.next();

JsonNode field = jsonNode.get(fieldName);

}

五、JsonParser

==============================================================================

Jackson JsonParser类是一个底层一些的JSON解析器。 它类似于XML的Java StAX解析器,差别是JsonParser解析JSON而不解析XML。

Jackson JsonParser的运行层级低于Jackson ObjectMapper。 这使得JsonParser比ObjectMapper更快,但使用起来也比较麻烦。

1、创建一个JsonParser


为了创建Jackson JsonParser,首先需要创建一个JsonFactory。 JsonFactory用于创建JsonParser实例。 JsonFactory类包含几个createParser()方法,每个方法都使用不同的JSON源作为参数。

这是创建一个JsonParser来从字符串中解析JSON的示例:

String carJson =

“{ “brand” : “Mercedes”, “doors” : 5 }”;

JsonFactory factory = new JsonFactory();

JsonParser parser = factory.createParser(carJson);

2、用JsonParser转化JSON


一旦创建了Jackson JsonParser,就可以使用它来解析JSON。 JsonParser的工作方式是将JSON分解为一系列令牌,可以一个一个地迭代令牌。

这是一个JsonParser示例,它简单地循环遍历所有标记并将它们输出到System.out。 这是一个实际上很少用示例,只是展示了将JSON分解成的令牌,以及如何遍历令牌的基础知识。

tring carJson =

“{ “brand” : “Mercedes”, “doors” : 5 }”;

JsonFactory factory = new JsonFactory();

JsonParser parser = factory.createParser(carJson);

while(!parser.isClosed()){

JsonToken jsonToken = parser.nextToken();

System.out.println("jsonToken = " + jsonToken);

}

只要JsonParser的isClosed()方法返回false,那么JSON源中仍然会有更多的令牌。

可以使用JsonParser的nextToken()获得一个JsonToken。 您可以使用此JsonToken实例检查给定的令牌。 令牌类型由JsonToken类中的一组常量表示。 这些常量是:

START_OBJECT

END_OBJECT

START_ARRAY

END_ARRAY

FIELD_NAME

VALUE_EMBEDDED_OBJECT

VALUE_FALSE

VALUE_TRUE

VALUE_NULL

VALUE_STRING

VALUE_NUMBER_INT

VALUE_NUMBER_FLOAT

可以使用这些常量来找出当前JsonToken是什么类型的令牌。 可以通过这些常量的equals()方法进行操作。 这是一个例子:

String carJson =

“{ “brand” : “Mercedes”, “doors” : 5 }”;

JsonFactory factory = new JsonFactory();

JsonParser parser = factory.createParser(carJson);

Car car = new Car();

while(!parser.isClosed()){

JsonToken jsonToken = parser.nextToken();

if(JsonToken.FIELD_NAME.equals(jsonToken)){

String fieldName = parser.getCurrentName();

System.out.println(fieldName);

jsonToken = parser.nextToken();

if(“brand”.equals(fieldName)){

car.brand = parser.getValueAsString();

} else if (“doors”.equals(fieldName)){

car.doors = parser.getValueAsInt();

}

}

}

System.out.println("car.brand = " + car.brand);

System.out.println("car.doors = " + car.doors);

如果指向的标记是字段名称,则JsonParser的getCurrentName()方法将返回当前字段名称。

如果指向的令牌是字符串字段值,则getValueAsString()返回当前令牌值作为字符串。 如果指向的令牌是整数字段值,则getValueAsInt()返回当前令牌值作为int值。 JsonParser具有更多类似的方法来获取不同类型的curren令牌值(例如boolean,short,long,float,double等)。

六、JsonGenerator

=================================================================================

Jackson JsonGenerator用于从Java对象(或代码从中生成JSON的任何数据结构)生成JSON。

1、创建一个JsonGenerator


为了创建Jackson JsonGenerator,必须首先创建JsonFactory实例。 这是创建JsonFactory的方法:

JsonFactory factory = new JsonFactory();

一旦创建了JsonFactory,就可以使用JsonFactory的createGenerator()方法创建JsonGenerator。 这是创建JsonGenerator的示例:

JsonFactory factory = new JsonFactory();

JsonGenerator generator = factory.createGenerator(

new File(“data/output.json”), JsonEncoding.UTF8);

createGenerator()方法的第一个参数是生成的JSON的目标。 在上面的示例中,参数是File对象。 这意味着生成的JSON将被写入给定文件。 createGenerator()方法已重载,因此还有其他版本的createGenerator()方法采用例如OutputStream等,提供了有关将生成的JSON写入何处的不同选项。

createGenerator()方法的第二个参数是生成JSON时使用的字符编码。 上面的示例使用UTF-8。

2、使用JsonGenerator生成JSON


一旦创建了JsonGenerator,就可以开始生成JSON。 JsonGenerator包含一组write …()方法,可以使用这些方法来编写JSON对象的各个部分。 这是一个使用Jackson JsonGenerator生成JSON的简单示例:

JsonFactory factory = new JsonFactory();

JsonGenerator generator = factory.createGenerator(

new File(“data/output.json”), JsonEncoding.UTF8);

generator.writeStartObject();

generator.writeStringField(“brand”, “Mercedes”);

generator.writeNumberField(“doors”, 5);

generator.writeEndObject();

generator.close();

此示例首先调用writeStartObject(),将{写入输出。 然后,该示例调用writeStringField(),将品牌字段名称+值写入输出。 之后,将调用writeNumberField()方法,此方法会将Doors字段名称+值写入输出。 最后,调用writeEndObject(),将}写入输出。

JsonGenerator还可以使用许多其他写入方法。 这个例子只显示了其中一些。

3、关闭JsonGenerator


完成生成JSON后,应关闭JsonGenerator。 您可以通过调用其close()方法来实现。 这是关闭JsonGenerator的样子:

generator.close();

七、Jackson注解

=============================================================================

Jackson JSON工具包包含一组Java注解,可以使用这些注解来设置将JSON读入对象的方式或从对象生成什么JSON的方式。 此Jackson注解教程介绍了如何使用Jackson的注解。

下面是一些常用的注解:

| 注解 | 用法 |

| — | — |

| @JsonProperty | 用于属性,把属性的名称序列化时转换为另外一个名称。示例:

@JsonProperty(“birth_ d ate”)

private Date birthDate; |

| @JsonFormat | 用于属性或者方法,把属性的格式序列化时转换成指定的格式。示例:

@JsonFormat(timezone = “GMT+8”, pattern = “yyyy-MM-dd HH:mm”)

public Date getBirthDate() |

| @JsonPropertyOrder | 用于类, 指定属性在序列化时 json 中的顺序 , 示例:

@JsonPropertyOrder({ “birth_Date”, “name” })

public class Person |

| @JsonCreator | 用于构造方法,和 @JsonProperty 配合使用,适用有参数的构造方法。 示例:

@JsonCreator

public Person(@JsonProperty(“name”)String name) {…} |

| @JsonAnySetter | 用于属性或者方法,设置未反序列化的属性名和值作为键值存储到 map 中

@JsonAnySetter

public void set(String key, Object value) {

map.put(key, value);

} |

| @JsonAnyGetter | 用于方法 ,获取所有未序列化的属性

public Map<String, Object> any() { return map; } |

下面是一些注解的详细说明。

一)、Read + Write注解


Jackson包含一组注解,这些注解会影响从JSON读取Java对象以及将Java对象写入JSON。 我将这些注解称为“读+写注解”。 以下各节将更详细地介绍Jackson的读写注解。

1、@JsonIgnore

Jackson注解@JsonIgnore用于告诉Jackson忽略Java对象的某个属性(字段)。 在将JSON读取到Java对象中以及将Java对象写入JSON时,都将忽略该属性。

这是使用@JsonIgnore注解的示例:

import com.fasterxml.jackson.annotation.JsonIgnore;

public class PersonIgnore {

@JsonIgnore

public long personId = 0;

public String name = null;

}

在上面的类中,不会从JSON读取或写入JSON属性personId。

2、@JsonIgnoreProperties

@JsonIgnoreProperties Jackson注解用于指定要忽略的类的属性列表。 @JsonIgnoreProperties注解放置在类声明上方,而不是要忽略的各个属性(字段)上方。

这是如何使用@JsonIgnoreProperties注解的示例:

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;

@JsonIgnoreProperties({“firstName”, “lastName”})

public class PersonIgnoreProperties {

public long personId = 0;

public String firstName = null;

public String lastName = null;

}

在此示例中,属性firstName和lastName都将被忽略,因为它们的名称在类声明上方的@JsonIgnoreProperties注解声明内列出。

3、@JsonIgnoreType

@JsonIgnoreType Jackson注解用于将整个类型(类)标记为在使用该类型的任何地方都将被忽略。

这是一个示例,展示如何使用@JsonIgnoreType注解:

import com.fasterxml.jackson.annotation.JsonIgnoreType;

public class PersonIgnoreType {

@JsonIgnoreType

public static class Address {

public String streetName = null;

public String houseNumber = null;

public String zipCode = null;

public String city = null;

public String country = null;

}

public long personId = 0;

public String name = null;

public Address address = null;

}

在上面的示例中,所有Address实例将被忽略。

4、@JsonAutoDetect

Jackson注解@JsonAutoDetect用于告诉Jackson在读写对象时包括非public修饰的属性。

这是一个示例类,展示如何使用@JsonAutoDetect注解:

import com.fasterxml.jackson.annotation.JsonAutoDetect;

@JsonAutoDetect(fieldVisibility = JsonAutoDetect.Visibility.ANY )

public class PersonAutoDetect {

private long personId = 123;

public String name = null;

}

JsonAutoDetect.Visibility类包含与Java中的可见性级别匹配的常量,表示ANY,DEFAULT,NON_PRIVATE,NONE,PROTECTED_AND_PRIVATE和PUBLIC_ONLY。

二)、Read注解


Jackson包含一组注解,这些注解仅影响Jackson将JSON解析为对象的方式-意味着它们影响Jackson对JSON的读取。 我称这些为“读注解”。 以下各节介绍了Jackson的读注解。

1、@JsonSetter

Jackson注解@JsonSetter用于告诉Jackson,当将JSON读入对象时,应将此setter方法的名称与JSON数据中的属性名称匹配。 如果Java类内部使用的属性名称与JSON文件中使用的属性名称不同,这个注解就很有用了。

以下Person类用personId名称对应JSON中名为id的字段:

public class Person {

private long personId = 0;

private String name = null;

public long getPersonId() { return this.personId; }

public void setPersonId(long personId) { this.personId = personId; }

public String getName() { return name; }

public void setName(String name) { this.name = name; }

}

但是在此JSON对象中,使用名称id代替personId:

{

“id” : 1234,

“name” : “John”

}

Jackson无法将id属性从JSON对象映射到Java类的personId字段。

@JsonSetter注解指示Jackson为给定的JSON字段使用setter方法。 在我们的示例中,我们在setPersonId()方法上方添加@JsonSetter注解。

这是添加@JsonSetter注解的实例:

public class Person {

private long personId = 0;

private String name = null;

public long getPersonId() { return this.personId; }

@JsonSetter(“id”)

public void setPersonId(long personId) { this.personId = personId; }

public String getName() { return name; }

public void setName(String name) { this.name = name; }

}

@JsonSetter注解中指定的值是要与此setter方法匹配的JSON字段的名称。 在这种情况下,名称为id,因为这是我们要映射到setPersonId()setter方法的JSON对象中字段的名称。

2、@JsonAnySetter

Jackson注解@JsonAnySetter表示Jackson为JSON对象中所有无法识别的字段调用相同的setter方法。 “无法识别”是指尚未映射到Java对象中的属性或设置方法的所有字段。

看一下这个Bag类:

public class Bag {

private Map<String, Object> properties = new HashMap<>();

public void set(String fieldName, Object value){

this.properties.put(fieldName, value);

}

public Object get(String fieldName){

return this.properties.get(fieldName);

}

}

然后查看此JSON对象:

{

“id” : 1234,

“name” : “John”

}

Jackson无法直接将此JSON对象的id和name属性映射到Bag类,因为Bag类不包含任何公共字段或setter方法。

可以通过添加@JsonAnySetter注解来告诉Jackson为所有无法识别的字段调用set()方法,如下所示:

public class Bag {

private Map<String, Object> properties = new HashMap<>();

@JsonAnySetter

public void set(String fieldName, Object value){

this.properties.put(fieldName, value);

}

public Object get(String fieldName){

return this.properties.get(fieldName);

}

}

现在,Jackson将使用JSON对象中所有无法识别的字段的名称和值调用set()方法。

请记住,这仅对无法识别的字段有效。 例如,如果您向Bag Java类添加了公共名称属性或setName(String)方法,则JSON对象中的名称字段将改为映射到该属性/设置器。

3、@JsonCreator

Jackson注解@JsonCreator用于告诉Jackson该Java对象具有一个构造函数(“创建者”),该构造函数可以将JSON对象的字段与Java对象的字段进行匹配。

@JsonCreator注解在无法使用@JsonSetter注解的情况下很有用。 例如,不可变对象没有任何设置方法,因此它们需要将其初始值注入到构造函数中。

以这个PersonImmutable类为例:

小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数初中级Java工程师,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年最新Java开发全套学习资料》送给大家,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
img
img
img

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频

如果你觉得这些内容对你有帮助,可以添加下面V无偿领取!(备注Java)
img

、@JsonAnySetter

Jackson注解@JsonAnySetter表示Jackson为JSON对象中所有无法识别的字段调用相同的setter方法。 “无法识别”是指尚未映射到Java对象中的属性或设置方法的所有字段。

看一下这个Bag类:

public class Bag {

private Map<String, Object> properties = new HashMap<>();

public void set(String fieldName, Object value){

this.properties.put(fieldName, value);

}

public Object get(String fieldName){

return this.properties.get(fieldName);

}

}

然后查看此JSON对象:

{

“id” : 1234,

“name” : “John”

}

Jackson无法直接将此JSON对象的id和name属性映射到Bag类,因为Bag类不包含任何公共字段或setter方法。

可以通过添加@JsonAnySetter注解来告诉Jackson为所有无法识别的字段调用set()方法,如下所示:

public class Bag {

private Map<String, Object> properties = new HashMap<>();

@JsonAnySetter

public void set(String fieldName, Object value){

this.properties.put(fieldName, value);

}

public Object get(String fieldName){

return this.properties.get(fieldName);

}

}

现在,Jackson将使用JSON对象中所有无法识别的字段的名称和值调用set()方法。

请记住,这仅对无法识别的字段有效。 例如,如果您向Bag Java类添加了公共名称属性或setName(String)方法,则JSON对象中的名称字段将改为映射到该属性/设置器。

3、@JsonCreator

Jackson注解@JsonCreator用于告诉Jackson该Java对象具有一个构造函数(“创建者”),该构造函数可以将JSON对象的字段与Java对象的字段进行匹配。

@JsonCreator注解在无法使用@JsonSetter注解的情况下很有用。 例如,不可变对象没有任何设置方法,因此它们需要将其初始值注入到构造函数中。

以这个PersonImmutable类为例:

小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数初中级Java工程师,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年最新Java开发全套学习资料》送给大家,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
[外链图片转存中…(img-zIArYg6v-1710819614147)]
[外链图片转存中…(img-InOpLZtX-1710819614148)]
[外链图片转存中…(img-Q0OPb5P8-1710819614148)]

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频

如果你觉得这些内容对你有帮助,可以添加下面V无偿领取!(备注Java)
[外链图片转存中…(img-05V2bJ9M-1710819614149)]

  • 7
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值