ObjectMapper

2023-10-19 09:28
文章标签 objectmapper

本文主要是介绍ObjectMapper,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

简介

Jackson ObjectMapper类(com.fasterxml.jackson.databind.ObjectMapper)是使用 Jackson 解析 JSON 最简单的方法。ObjectMapper 可以从字符串、流或文件来解析 JSON,并创建 java 对象或对象图表示已解析的 JSON。将 JSON 解析为java 对象也称从 JSON 反序列化 java 对象

ObjectMapper也可以从 Java 对象创建 JSON。从 java 对象生成 JSON 的过程也称为序列化 java 对象到 JSON

Jackson对象映射器(ObjectMapper)可以把 JSON 解析为用户自定义类对象,或者解析为JSON内置的树模型的对象。

ObjectMapper对象示例

public class Car {private String brand = null;private int doors = 0;public String getBrand() { return this.brand; }public void   setBrand(String brand){ this.brand = brand;}public int  getDoors() { return this.doors; }public void setDoors (int doors) { this.doors = doors; }
}
//----------------------------
ObjectMapper objectMapper = new ObjectMapper();
String carJson = "{ \"brand\" : \"Mercedes\", \"doors\" : 5 }";
try {Car car = objectMapper.readValue(carJson, Car.class);System.out.println("car brand = " + car.getBrand());System.out.println("car doors = " + car.getDoors());
} catch (IOException e) {e.printStackTrace();
}

readValue() 方法的第一个参数是 JSON数据源(字符串、流或者文件),第二个参数是解析目标Java类,这里传入的是Car.class。

反序列化

ObjectMapper从 JSON 属性匹配到 Java 属性的过程

默认情况下,Jackson 映射一个 JSON 对象的属性到 Java 对象,是用 JSON 属性的名字在 Java对象中查找匹配的 getter/setter 方法。Jackson移除了 getter/setter 方法名中的 get/set 字符部分,并把方法名剩余字符的第一个字符小写,得到的就是 JSON 属性名。

在上面的代码示例中,JSON 属性的名称是 brand,匹配了 Java 类中名为 getBrand()/setBrand() 的方法。JSON 属性的名称是 doors,匹配了getDoors()/setDoors()方法。

如果想用其他方法来匹配 JSON 对象属性和 Java 对象属性,可以自定义序列化/反序列化过程,或者使用其他的 Jackson注解。

从 JSON Reader对象读取 Java对象

ObjectMapper objectMapper = new ObjectMapper();
String carJson = "{ \"brand\" : \"Mercedes\", \"doors\" : 4 }";
Reader reader = new StringReader(carJson);
Car car = objectMapper.readValue(reader, Car.class);

从 JSON文件中读取Java对象

ObjectMapper objectMapper = new ObjectMapper();
File file = new File("data/car.json");
Car car = objectMapper.readValue(file, Car.class);

从URL中获取JSON数据读Java对象

可以通过URL(java.net.URL)获取JSON数据后读取Java对象

ObjectMapper objectMapper = new ObjectMapper();
URL url = new URL("file:data/car.json");
Car car = objectMapper.readValue(url, Car.class);	

例子中使用的是文件URL,也可以使用HTTP URL

从Java InputStream获取JSON数据读取Java对象

ObjectMapper objectMapper = new ObjectMapper();
InputStream input = new FileInputStream("data/car.json");
Car car = objectMapper.readValue(input, Car.class);

从字节数组获取JSON数据读取Java对象

ObjectMapper objectMapper = new ObjectMapper();
String carJson = "{ \"brand\" : \"Mercedes\", \"doors\" : 5 }";
byte[] bytes = carJson.getBytes("UTF-8");
Car car = objectMapper.readValue(bytes, Car.class);

从JSON数组字符串读取Java对象数组

String jsonArray = "[{\"brand\":\"ford\"}, {\"brand\":\"Fiat\"}]";
ObjectMapper objectMapper = new ObjectMapper();
Car[] cars2 = objectMapper.readValue(jsonArray, Car[].class);

从JSON数组字符串获取Java List对象

String jsonArray = "[{\"brand\":\"ford\"}, {\"brand\":\"Fiat\"}]";
ObjectMapper objectMapper = new ObjectMapper();
List<Car> cars1 = objectMapper.readValue(jsonArray, new TypeReference<List<Car>>(){});

注意传递给readValue()的TypeReference类型参数,这个参数告诉Jackson读取一列“Car”对象

Jackson 通过反射来生成 Java 对象,但是模板会擦除类型,所以这里用 TypeReference 进行包装。

从JSON字符串读取 Java Map 对象

ObjectMapper 可以从 JSON 字符串读取一个 Map,当我们不知道要提取的JSON的格式的时候非常有用。一般会把 JSON 对象读取到一个 Map 对象中,每一个 JSON 对象的属性都会变成 Map中的键值对。

String jsonObject = "{\"brand\":\"ford\", \"doors\":5}";
ObjectMapper objectMapper = new ObjectMapper();
Map<String, Object> jsonMap = objectMapper.readValue(jsonObject, new TypeReference<Map<String,Object>>(){});

特殊情况

忽略Java对象没有的 JSON 属性

有时候我们要读取的 JSON 数据的属性要多于 Java 对象的属性,默认情况下 Jackson 会抛出异常,含义是无法在 Java 对象找到未知属性 XXX

但是,我们有时候又需要允许 JSON 属性多于要产生的 Java 对象的属性。比如,你想从一个 REST服务中获取 JSON 数据,但是它包含的内容远多于你所需要的。这时,通过配置Jackson的 Feature可以使其忽略掉多余的属性。

objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);

注意:也可以使用ObjectMapper.enabled()/disabled() 方法进行配置

JSON 属性值为 NULL 且对应 Java 原生类型产生的异常

可以配置ObjectMapper 的Feature,使其在 JSON 字符串中包含的属性值是 null,且该属性对应的Java 对象的属性时原生类型(primitive type: int, long, float, double等)时,反序列化失败,抛出异常。

修改 Car 类的定义:

public class Car {private String brand = null;private int doors = 0;public String getBrand() { return this.brand; }public void   setBrand(String brand){ this.brand = brand;}public int  getDoors(){ return this.doors; }public void setDoors (int doors) { this.doors = doors; }
}

注意属性 doors 的类型是 Java 原生类型 int (而不是object)

现在假设有一个 JSON 字符串要匹配 Car类

{ "brand":"Toyota", "doors":null }

注意属性 doors 的值是 null

Java中的原生数据类型的值不能是 null,所以ObjectMapper默认会忽略 null 值的原生类型的属性,不过也可以配置ObjectMapper的 Feature 让它抛出异常,如下:

ObjectMapper objectMapper = new ObjectMapper();objectMapper.configure(DeserializationFeature.FAIL_ON_NULL_FOR_PRIMITIVES, true);

通过设置FAIL_ON_NULL_FOR_PRIMITIVES属性是true,会在试图把 null 值的JSON属性解析为 Java 原生类型属性时抛出异常,如下:

ObjectMapper objectMapper = new ObjectMapper();
objectMapper.configure(DeserializationFeature.FAIL_ON_NULL_FOR_PRIMITIVES, true);
String carJson = "{ \"brand\":\"Toyota\", \"doors\":null }";
Car car = objectMapper.readValue(carJson, Car.class);

异常信息如下:

Exception in thread "main" com.fasterxml.jackson.databind.exc.MismatchedInputException:Cannot map `null` into type int(set DeserializationConfig.DeserializationFeature.FAIL_ON_NULL_FOR_PRIMITIVES to 'false' to allow)at [Source: (String)"{ "brand":"Toyota", "doors":null }"; line: 1, column: 29] (through reference chain: jackson.Car["doors"])

序列化

把对象序列化成JSON

ObjectMapper 也可以用来将一个对象生成 JSON 数据,可以使用下列方法:

writeValue()

writeValueAsString()

writeValueAsBytes()

下面是一个把 Car 对象序列化成 JSON 的例子:

ObjectMapper objectMapper = new ObjectMapper();Car car = new Car();
car.brand = "BMW";
car.doors = 4;objectMapper.writeValue(new FileOutputStream("data/output-2.json"), car);

这里首先创建了一个 ObjectMapper 实例和一个 Car 实例,然后调用 ObjectMapper 的writeValue() 方法把 Car 实例转换成 JSON 后输出到 FileOutputStream。

writeValueAsString() 和 writeValueAsBytes() 也可以从对象中生成 JSON,并且返回一个 String 或者 Byte 数组的 JSON,如下:

ObjectMapper objectMapper = new ObjectMapper();Car car = new Car();
car.brand = "BMW";
car.doors = 4;String json = objectMapper.writeValueAsString(car);
System.out.println(json);

输出结果是:

{"brand":"BMW","doors":4}

自定义序列化过程

有时候我们不想用 Jackson 默认的序列化过程把一个 Java 对象变成 JSON,比如,我们可能会在 JSON中使用和 Java 对象不同的属性名称,或者我们想完全忽略某些属性。

Jackson 可以为 ObjectMapper 设置一个自定义序列化器(custom serializer)这个序列化器会注册为序列化某个实际的类,然后再 ObjectMapper 执行序列化时调用,比如序列化 Car 对象。

下面的例子展示了如何为 Car 类注册一个自定义序列化器:

//用Car类初始化序列化器CarSerializer 
CarSerializer carSerializer = new CarSerializer(Car.class);
ObjectMapper objectMapper = new ObjectMapper();
//新建一个序列化模型, 序列化器使用CarSerializer类
SimpleModule module = new SimpleModule("CarSerializer", new Version(2, 1, 3, null, null, null));
//注册carSerializer用于序列化Car
module.addSerializer(Car.class, carSerializer);objectMapper.registerModule(module);Car car = new Car();
car.setBrand("Mercedes");
car.setDoors(5);String carJson = objectMapper.writeValueAsString(car);

输出的结果是:

{"producer":"Mercedes","doorCount":5}

下面是 Carserializer 类的定义:

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.ser.std.StdSerializer;import java.io.IOException;public class CarSerializer extends StdSerializer<Car> {protected CarSerializer(Class<Car> t) {super(t);}@overridepublic void serialize(Car car, JsonGenerator jsonGenerator, SerializerProvider serializerProvider)throws IOException {jsonGenerator.writeStartObject();jsonGenerator.writeStringField("producer", car.getBrand());jsonGenerator.writeNumberField("doorCount", car.getDoors());jsonGenerator.writeEndObject();}
}

注意:serialize 的第二个参数是一个 JsonGenerator实例,我们可以使用这个实例序列化一个对象,这里是 Car 对象。

这篇关于ObjectMapper的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/238893

相关文章

ObjectMapper[jackson]常用配置及异常处理

在 Java 开发中,Jackson 是最常用的 JSON 处理库之一。ObjectMapper 是 Jackson 的核心类,用于在 Java 对象与 JSON 数据之间进行转换。通过 configure() 方法,我们可以配置 ObjectMapper 的各种特性,以满足不同的需求。本文将详细讲解 ObjectMapper.configure() 方法可以配置的参数及其作用。 ObjectM

序列化和反序列化,objectMapper 详解

序列化和反序列化,objectMapper 详解 1、主要功能2、配置与自定义: 提供了一系列注解和配置方法,允许对序列化和反序列化过程进行高度定制。3、例子3.1. 简单的序列化与反序列化3.2. 使用注解自定义序列化和反序列化 ObjectMapper 是 Jackson 库中的核心类,用于在 Java 对象和 JSON 数据之间进行序列化(将 Java 对象转换为 JSO

使用ObjectMapper对java对象和Map进行json格式转换

依赖包 1.jackson-core-asl-1.9.13.jar 2.jackson-mapper-asl-1.9.13.jar public class Test {public static void main(String[] args) throws Exception{ObjectMapper o = new ObjectMapper();Student std = new Stud

Mybatis和objectMapper的问题

使用了Mybatis的懒加载,即 <!-- 开启延迟加载 --> <setting name="lazyLoadingEnabled" value="true"/> <!-- 按需延迟加载 --> <setting name="aggressiveLazyLoading" value="false"/> xml中 <select id="queryByID" resultMap="pojoR

Jackson ObjectMapper 使用教程

添加 依赖 gradle implementation("com.fasterxml.jackson.dataformat:jackson-dataformat-xml") maven <dependency><groupId>com.fasterxml.jackson.dataformat</groupId><artifactId>jackson-dataformat-

Day23_学点儿IDEA_单元测试@Test在新module项目中失效、Jackson核心对象 ObjectMapper识别不到

版本 IntelliJ IDEA 2023.2.4 目录结构 Study(Project)├──JavaSE(Module)│ └──xxxx└──JavaWeb(Module)└──xxxx 问题 1.1 在JavaSE项目中正常可以用的单元测试@Test,到了JavaWeb项目中不起作用了 1.2 解决方法 如果是新创建的项目,先在以下位置添加一句-Dedita

SpringBoot中这样用ObjectMapper,才够优雅!

目录 背景步骤在SpringBoot项目中要实现对象与Json字符串的互转,每次都需要像如下一样new 一个ObjectMapper对象:这样的代码到处可见,有问题吗?我们要使用jmh测试几种方式的区别:所以在我们真正使用的时候不要在方法中去new ObjectMapper了,使用单例模式实现上述功能。 总结 背景 借助ObjectMapper实现map转对象太慢了,如何解决?

使用objectMapper处理数据之间的转化详解

在项目中使用到了ObjectMapper,故研究了一下。现将自己的几个测试用例和大家分享一下~ 首先在pom.xml文件中,加入依赖: <dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-databind</artifactId><version>2.8.3</version></de

objectMapper、ObjectNode、JsonNode调用接口时进行参数组装

objectMapper、ObjectNode、JsonNode用于调用接口时进行参数组装···  public String sendText( List< String > listUser, String content ) throws JsonProcessingException{if ( listUser.size() <= 0 ){return "用户ID为空!";}if

ObjectMapper 的使用

在项目中使用到了ObjectMapper,故研究了一下。现将自己的几个测试用例和大家分享一下~ 首先在pom.xml文件中,加入依赖:      <dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-databind</artifactId><version>2.10.3</versio