Jackson 应用指北
1. 概述
Jackson 是目前在 web 开发中应用最多,速度最快的一种 json 序列化和反序列化框架。本文次要联合 Jackson 在我的项目中的理论应用进行介绍。
2. 字段疏忽
2.1 json 转 POJO 时,疏忽某些字段
只须要在实体类上加上 @JsonIgnoreProperties(ignoreUnknown = true)
注解就能够。
2.2 POJO 转 json 时,疏忽某些字段
@JsonIgnore
注解用来疏忽某些字段,能够用在 Field 或者 Getter 办法上,用在 Setter 办法时,和 Filed 成果一样
3. json 转换为 POJO
3.1 json 字符串间接转 POJO
objectMapper.readValue(json, xxx.class)
实用于 json 字符串与 POJO 间接一一对应。
3.2 json 字符串转 JsonNode
JsonNode rootNode = objectMapper.readTree(json);
// 获取其中某个字段的数据
JsonNode dataNode = rootNode.findValue("xxx");
// 将数据反序列化为 POJO
objectMapper.treeToValue(dataNode, xxx.class);
实用于 Json 字符串的某一部分与 JsonNode 对应。先获取 json 响应中的某一部分数据,再将该数据转换为 POJO
3.3 json 转泛型类
AiReply<SensitiveImageReply> reply = objectMapper.readValue(json, new TypeReference<AiReply<SensitiveImageReply>>() {});
3.4 json 转数组和列表
List<Person> personList = new ArrayList<Person>() {
{add(new Person("yangjian", 22));
add(new Person("zhanghaoman", 22));
}
};
String personJson = this.objectMapper.writeValueAsString(personList);
List<Person> persons = this.objectMapper.readValue(personJson, List.class);
System.out.println("persons =" + persons);
3.5 类拷贝
// 拷贝成 map
Person person = new Person("yangjian", 23);
String json = this.objectMapper.writeValueAsString(person);
Map<String, Object> map = this.objectMapper.convertValue(person, Map.class);
// 链表到数组拷贝
List<String> list = new ArrayList<String>() {
{add("one");
add("two");
}
};
String[] strings = this.objectMapper.convertValue(list, String[].class);
System.out.println("this.objectMapper.writeValueAsString(strings) =" + this.objectMapper.writeValueAsString(strings));
4. POJO 转换为 json
4.1 设置视图
@JsonView(xxx.class)
注解能够实现视图显示,序列化的 json 只会蕴含有雷同视图润饰的字段。并且,视图能够继承。此注解,POJO 类上和 controller 的办法上都须要加。
4.2 自定义某个字段的序列化 / 反序列化形式
应用 SpringMVC 的 @RestController
时,咱们都晓得如果返回的是一个 POJO,那么 SpringMVC 将会主动进行 POJO 的序列化。但有些时候咱们往往须要对该 POJO 某个字段的序列化和反序列化的形式进行一些批改,以满足咱们的业务需要。这时候就能够用到 @JsonSerialize
和@JsonDeserialize
用法:
-
POJO
/**
*
- @author rainbow
- @since 2020/3/20 10:56
*/
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@JsonIgnoreProperties(ignoreUnknown = true)
@NoArgsConstructor
public class IdCardOcrData {
private String name;
private String sex;
private String nation;
@JsonDeserialize(using = IdCardLocalDateDeserializer.class)
@JsonSerialize(using = IdCardLocalDateSerializer.class)
private LocalDate birth;
private String address;
private String id;
private String authority;
/**
* 无效时限
*/
private String valid_date;
}
- IdCardLocalDateSerializer 类
/**
- @author rainbow
- @since 2020/3/20 16:25
*/
public class IdCardLocalDateSerializer extends JsonSerializer<LocalDate> {
@Override
public void serialize(LocalDate value, JsonGenerator gen, SerializerProvider serializers) throws IOException {DateTimeFormatter timeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
gen.writeString(timeFormatter.format(value));
}
}
- IdCardLocalDateDeserializer 类
/**
- @author rainbow
- @since 2020/3/20 13:05
*/
public class IdCardLocalDateDeserializer extends JsonDeserializer<LocalDate> {
@Override
public LocalDate deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {String dateString = p.getText();
if (StringUtils.isNotBlank(dateString)) {String[] split = dateString.split("/");
return LocalDate.of(Integer.parseInt(split[0]), Integer.parseInt(split[1]), Integer.parseInt(split[2]));
}
return null;
}
}
以上的例子能够将“2020/2/1”格局的字符串反序列化为 LocalDate 类,并将其序列化为“2020-02-02”格局的 json 数据。### 4.3 自定义字段序列化形式 @JsonFormat
此注解用于属性或者办法上(最好是属性上),能够不便的把 Date 类型间接转化为咱们想要的模式,比方 `@JsonFormat(pattern = "yyyy-MM-dd HH-mm-ss",timezone = "GMT+8")`
## 5. 自定义 objectMapper
应用 SpringBoot 主动拆卸的 ObjectMapper 在某些状况不太实用,比方它会将值为 null 的字段也进行序列化返回。因而,咱们对 ObjectMapper 进行设置,达到本人想要的成果。具体配置类为:
@Configuration
public class JacksonConfig {
private static final String FORMAT = "yyyy-MM-dd HH:mm:ss";
@Bean
public Jackson2ObjectMapperBuilderCustomizer customizer() {
return builder -> {builder.locale(Locale.CHINA);
builder.timeZone(TimeZone.getTimeZone(ZoneId.systemDefault()));
builder.simpleDateFormat(FORMAT);
JavaTimeModule javaTimeModule = new JavaTimeModule();
javaTimeModule.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(DateTimeFormatter.ofPattern(FORMAT)));
javaTimeModule.addSerializer(LocalDate.class, new LocalDateSerializer(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
javaTimeModule.addSerializer(LocalTime.class, new LocalTimeSerializer(DateTimeFormatter.ofPattern("HH:mm:ss")));
javaTimeModule.addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
javaTimeModule.addDeserializer(LocalDate.class, new LocalDateDeserializer(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
javaTimeModule.addDeserializer(LocalTime.class, new LocalTimeDeserializer(DateTimeFormatter.ofPattern("HH:mm:ss")));
builder.modules(javaTimeModule);
};
}
@Bean
@Primary
public ObjectMapper jacksonObjectMapper(Jackson2ObjectMapperBuilder builder)
{ObjectMapper objectMapper = builder.createXmlMapper(false).build();
// 通过该办法对 mapper 对象进行设置,所有序列化的对象都将按改规定进行系列化
// Include.Include.ALWAYS 默认
// Include.NON_DEFAULT 属性为默认值不序列化
// Include.NON_EMPTY 属性为 空("")或者为 NULL 都不序列化,则返回的 json 是没有这个字段的
// Include.NON_NULL 属性为 NULL 不序列化
objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
// 容许呈现特殊字符和本义符
objectMapper.configure(JsonParser.Feature.ALLOW_UNQUOTED_CONTROL_CHARS, true);
// 容许呈现单引号
objectMapper.configure(JsonParser.Feature.ALLOW_SINGLE_QUOTES, true);
//objectMapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
//objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
/**
* 将 Long,BigInteger 序列化的时候, 转化为 String
*/
// SimpleModule simpleModule = new SimpleModule();
//
// simpleModule.addSerializer(Long.class, ToStringSerializer.instance);
// simpleModule.addSerializer(Long.TYPE, ToStringSerializer.instance);
// simpleModule.addSerializer(BigInteger.class, ToStringSerializer.instance);
//
// objectMapper.registerModule(simpleModule);
return objectMapper;
}
}
该配置类能对类的 `LocalDateTime` 等新工夫类进行序列化,也能对序列化和反序列化解析形式进行设置。