概述
springboot配置jackson处理类属性,javabean序列化为json格式,常用框架:阿里fastjson,谷歌gson、jackson等。
- ① 性能:jackson > fastjson > gson >同个结构
- ② jackson、fastjson、gson 类库各有特点,各有自己的专长
jackson是spring-boot-starter-json依赖的一部分,spring-boot-starter-web中包含spring-boot-starter-json。也就是说当项目中引入了
spring-boot-starter-web后会自动引入spring-boot-starter-json,而不需要单独引入。
常用注解
基础注解
| 注解 | 用法 |
|---|---|
| @jsonproperty | 用于属性,把属性的名称序列化时转换为另外一个名称。示例:@jsonproperty("birth_date") private date birthdate |
| @jsonignore | 可用于字段、getter/setter、构造函数参数上,作用相同,都会对相应的字段产生影响。使相应字段不参与序列化和反序列化。 |
| @jsonignoreproperties | 该注解是类注解,使得相应字段不参与序列化和反序列化。eg:@jsonignoreproperties({"password","id"}) public class person |
| @jsonformat | 用于属性或者方法,把属性的格式序列化时转换成指定的格式。示例:@jsonformat(timezone = "gmt+8", pattern = "yyyy-mm-dd hh:mm") public date getbirthdate() |
| @jsonpropertyorder | 该注解是类注解,和 @jsonproperty的index属性类似,指定属性在序列化时 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; } |
| @jsonsetter | 应用于属性或方法,指定反序列化的字段名 @jsonsetter("_id") public string setid(string id) { return this.id=id; } |
| @jsongetter | 应用于方法或字段,指定序列化的字段名 @jsongetter("_id") public string getid() { return id; } |
| @jsonnaming | 类注解。序列化的时候该注解可将驼峰命名的字段名转换为下划线分隔的小写字母命名方式。反序列化的时候可以将下划线分隔的小写字母转换为驼峰命名的字段名。示例:@jsonnaming(propertynamingstrategy.snakecasestrategy.class) |
| @jsonrootname | 类注解。需开启mapper.enable(serializationfeature.wrap_root_value),用于序列化时输出带有根属性名称的json串,形式如 {"root_name":{"id":1,"name":"zhangsan"}}。 |
| @jsonautodetect | 指定属性(反)序列化范围 |
| @jsonignoretype | 将忽略这个类型的(反)序列化 |
| @jsoninclude | 对空值如何序列化 |
| @jsonpropertydescription | json的schema描述 |
| @jsonunwrapped | 将其属性上拉一个层级展开 |
| @jsonview | 不同接口下返回不同的属性 eg:@jsonview的使用 |
| @jacksoninject | json字段有一些缺少的属性,抓换成实体类的时候没有的属性将为null,但是我们在某些需求当中需要将为null的属性都设置为默认 |
| @jsonenumdefaultvalue | 反序列化时未知时的枚举值 |
| @jsonrawvalue | 使用原始值,而不会进行转义 eg:"content":"test content",而不是\"content\":\"test content\" |
| @jsonvalue | 最多能用于类的一个属性(多个属性应用此注解将抛出异常),并将此属性上拉一个层级展开,其他字段不参与(反)序列化 |
| @jsonkey | 最多能用于类的一个属性(多个属性应用此注解将抛出异常),这个类型对象作为map数据结构的key时,标记此注解的属性值将作为json字符串的字段名 |
| @jsonfilter | 应用于属性, 过滤属性 eg:@jsonfilter("non-pwd") private char[] password = new char[]{'0', '\u0343', '&'}; mapper.setfilterprovider(new simplefilterprovider().addfilter("non-pwd", simplebeanpropertyfilter.serializeallexcept("password"))); |
| @jsonalias | 应用于属性,反序列化时多个候选字段名能够映射到同一个属性上 |
| @jsonmerge | 应用于属性,反序列化时集合类型属性时,将json中的元素与字段中的默认元素融合 eg:@jsonmerge private list<string> hobbies = new arraylist<>(collections.singletonlist("篮球")); |
常用注解示例
1、jsonproperty
类似于sql里字段的别名,用于序列化,使用注解字段属性,替代原字段属性
@jsonproperty("username")
private string name;
序列化结果为:在序列化的json串中,username替代了name
{"username":"tom"}2、jsonignore
在序列化时忽略该字段
@data
@builder
@noargsconstructor
@allargsconstructor
public class user {
@jsonignore
private long id;
@jsonproperty("username")
private string name;
@jsonignore
private integer age;
@jsonignore
private date birthday;
}
序列化结果为:
{"username":"tom"}3、jsonignoreproperties
- 序列化@jsonignoreproperties与@jsonignore类似,用于类上,注解使用的是字段别名
import com.fasterxml.jackson.annotation.jsonignoreproperties;
import com.fasterxml.jackson.annotation.jsonproperty;
import lombok.allargsconstructor;
import lombok.builder;
import lombok.data;
import lombok.noargsconstructor;
import java.util.date;
@data
@builder
@noargsconstructor
@allargsconstructor
@jsonignoreproperties({"id","username","birthday"})
public class user {
private long id;
@jsonproperty("username")
private string name;
private integer age;
private date birthday;
}
序列化结果为:
{"age":23}- @jsonignoreproperties(ignoreunknown = true)用于忽略字段不匹配情况,相当于mapper.disable(deserializationfeature.fail_on_unknown_properties);
【@jsontypename @jsontypeinfo】用在类上,在序列化时增加一层
import com.fasterxml.jackson.annotation.jsonproperty;
import com.fasterxml.jackson.annotation.jsontypeinfo;
import com.fasterxml.jackson.annotation.jsontypename;
import lombok.allargsconstructor;
import lombok.builder;
import lombok.data;
import lombok.noargsconstructor;
import java.util.date;
@data
@builder
@noargsconstructor
@allargsconstructor
@jsontypename(value = "user")
@jsontypeinfo(include = jsontypeinfo.as.wrapper_object, use = jsontypeinfo.id.name)
public class user {
private long id;
@jsonproperty("username")
private string name;
private integer age;
private date birthday;
}
序列化结果:
{"user":{"id":1,"age":23,"birthday":1587891781603,"username":"tom"}}4、jsonrootname
组合在序列化上等于类上注解@jsonrootname(“user”) 和 mapper.enable(serializationfeature.wrap_root_value),反序列化无用;
5、jsonformat
格式化日期格式
@data
@builder
@noargsconstructor
@allargsconstructor
public class user {
private long id;
@jsonproperty("username")
private string name;
private integer age;
@jsonformat(pattern = "yyyy-mm-dd hh:mm:ss:sss",locale = "zh", timezone = "gmt+8")
private date birthday;
}
序列化结果:
{"id":1,"age":23,"birthday":"2020-04-26 17:09:32:818","username":"tom"}配置
基础配置
spring:
jackson:
# 设置属性命名策略,对应jackson下propertynamingstrategy中的常量值,snake_case-返回的json驼峰式转下划线,json body下划线传到后端自动转驼峰式
property-naming-strategy: snake_case
# 全局设置@jsonformat的格式pattern
date-format: yyyy-mm-dd hh:mm:ss
# 当地时区
locale: zh_cn
# 设置全局时区
time-zone: gmt+8
# 常用,全局设置pojo或被@jsoninclude注解的属性的序列化方式
default-property-inclusion: non_null #不为空的属性才会序列化,具体属性可看jsoninclude.include
# 常规默认,枚举类serializationfeature中的枚举属性为key,值为boolean设置jackson序列化特性,具体key请看serializationfeature源码
visibility:
#属性序列化的可见范围
getter: non_private
#属性反序列化的可见范围
setter: protected_and_public
#静态工厂方法的反序列化
creator: public_only
#字段
field: public_only
#布尔的序列化
is_getter: public_only
#所有类型(即getter setter field)不受影响,无意义
none: public_only
#所有类型(即getter setter field)都受其影响(慎用)
all: public_only
serialization:
#反序列化是否有根节点
wrap_root_value: false
#是否使用缩进,格式化输出
indent_output: false
fail_on_empty_beans: true # 对象不含任何字段时是否报错,默认true
fail_on_self_references: true #循环引用报错
wrap_exceptions: true #是否包装异常
fail_on_unwrapped_type_identifiers: true #jsonunwrapped标记的类有类型信息是否报错
write_self_references_as_null: false #循环引用返回null
close_closeable: true #若对象实现了closeable接口,在序列化后是否调用close方法
flush_after_write_value: false #流对象序列化之后是否强制刷新
write_dates_as_timestamps: true # 返回的java.util.date转换成时间戳
write_dates_with_zone_id: true #2011-12-03t10:15:30+01:00[europe/paris]带时区id
write_durations_as_timestamps: true #将durations转换成时间戳
write_char_arrays_as_json_arrays: false #是否字符数组输出json数组 (false则输出字符串)
write_enums_using_to_string: false # 将枚举输出tostring
write_enums_using_index: false #枚举下标
write_enum_keys_using_index: false #枚举key类似
write_null_map_values: false #是否输出map中的空entry(此特性已过期,请使用jsoninclude注解)
write_empty_json_arrays: true # 对象属性值是空集合是否输出空json数组
write_single_elem_arrays_unwrapped: false #是否将单个元素的集合展开,(即:去除数组符号"[]")
write_bigdecimal_as_plain: false #是否调用bigdecimal#toplainstring()输出
write_date_timestamps_as_nanoseconds: #将timestamp输出为纳秒
order_map_entries_by_keys: false #map序列化后,是否用key对其排序
eager_serializer_fetch: true #是否马上获取序列化器
use_equality_for_object_id: false #是否使用objectid比较是否相等(在orm框架hibernate中有应用)
# 枚举类deserializationfeature中的枚举属性为key,值为boolean设置jackson反序列化特性,具体key请看deserializationfeature源码
deserialization:
use_big_decimal_for_floats: false #将浮点数反序列化为big_decimal
use_big_integer_for_ints: false #将整数反序列化为big_integer
use_long_for_ints: false #将整型反序列化为长整
use_java_array_for_json_array: false #无明确类型时,是否将json数组反序列化为java数组(若是true,就对应object[] ,反之就是list<?>)
fail_on_unknown_properties: false # 常用,json中含pojo不存在属性时是否失败报错,默认true
fail_on_null_for_primitives: false #将null反序列化为基本数据类型是否报错
fail_on_numbers_for_enums: false #用整数反序列化为枚举是否报错
fail_on_invalid_subtype: false #找不至合适的子类否报错 (如注解jsontypeinfo指定的子类型)
fail_on_reading_dup_tree_key: false #出现重复的json字段是否报错
fail_on_ignored_properties: false #如果json中出现了java实体字段中已显式标记应当忽略的字段,是否报错
fail_on_unresolved_object_ids: true #如果反序列化发生了不可解析的objectid是否报错
fail_on_missing_creator_properties: false #如果缺少静态工厂方法的参数是否报错(false,则使用null代替需要的参数)
fail_on_null_creator_properties: false #将空值绑定到构造方法或静态工厂方法的参数是否报错
fail_on_missing_external_type_id_property: false #注解jsontypeinfo.as#external_property标记的属性缺失,是否报错
fail_on_trailing_tokens: false #出现尾随令牌是否报错(如果是true,则调用jsonparser#nexttoken,检查json的完整性)
wrap_exceptions: true #是否包装反序列化出现的异常
accept_single_value_as_array: true #反序列化时是否将一个对象封装成单元素数组
unwrap_single_value_arrays: false #反序列化时是否将单元素数组展开为一个对象
unwrap_root_value: false #是否将取消根节点的包装
accept_empty_string_as_null_object: false #是否将空字符("")串当作null对象
accept_empty_array_as_null_object: false #是否接受将空数组("[]")作为null
accept_float_as_int: true #是否接受将浮点数作为整数
read_enums_using_to_string: false #按照枚举tostring()方法读取,(false则按枚举的name()方法读取)
read_unknown_enum_values_as_null: false #读取到未知的枚举当作null
read_unknown_enum_values_using_default_value: false #读取到未知的枚举,将其当作被jsonenumdefaultvalue注解标记的枚举
read_date_timestamps_as_nanoseconds: true #将时间戳视为纳秒(false,则视为毫秒)
adjust_dates_to_context_time_zone: true #反序列化是否会适应deserializationcontext#gettimezone()提供的时区 (此特性仅对java8的时间/日期有效)
eager_deserializer_fetch: true #是否马上获取反序列化器
# 枚举类mapperfeature中的枚举属性为key,值为boolean设置jackson objectmapper特性
# objectmapper在jackson中负责json的读写、json与pojo的互转、json tree的互转,具体特性请看mapperfeature,常规默认即可
mapper:
use_annotations: true #是否使用注解自省(检查jsonproperties这些)
# 使用getter取代setter探测属性,这是针对集合类型,可以直接修改集合的属性
use_getters_as_setters: true #默认false
propagate_transient_marker: false #如何处理transient字段,如果true(不能访问此属性) ,若是false则不能通过字段访问(还是可以使用getter和setter访问)
auto_detect_creators: true #是否自动检测构造方法或单参且名为valueof的静态工厂方法
auto_detect_fields: true #是否自动检测字段 (若true,则将所有public实例字段视为为属性)
auto_detect_getters: true #确定是否根据标准 bean 命名约定自动检测常规“getter”方法的(不包括is getter)
auto_detect_is_getters: true #确定是否根据标准 bean 命名约定自动检测“is getter”方法
auto_detect_setters: false # 确定是否根据标准 bean 命名约定自动检测“setter”方法
require_setters_for_getters: false #getter方法必需要有对应的setter或字段或构造方法参数,才能视为一个属性
allow_final_fields_as_mutators: true #是否可以修改final成员字段
infer_property_mutators: true #是否能推断属性,(即使用字段和setter是不可见的,但getter可见即可推断属性)
infer_creator_from_constructor_properties: true #是否自动推断constructorproperties注解
can_override_access_modifiers: true #调用accessibleobject#setaccessible设为true .将原来不可见的属性,变为可见
override_public_access_modifiers: true #对所有的属性调用accessibleobject#setaccessible设为true .(即使用是公共的)
use_static_typing: false #序列化使用声明的静态类型还是动态类型 jsonserialize#typing注解可覆盖它
use_base_type_as_default_impl: false # 反序列化是否使用基本类作为默实现 @jsontypeinfo.defaultimpl
default_view_inclusion: true #没有jsonview注解标记的属性是否会被包含在json序列化视图中
sort_properties_alphabetically: false #按字母表顺序序列化字段(若false,按字段声明的顺序)
accept_case_insensitive_properties: false #反序列化属性时不区分大小写 (true时,会影响性能)
accept_case_insensitive_enums: false #枚举反序列化不区别大小写
accept_case_insensitive_values: false #允许解析一些枚举的基于文本的值类型但忽略反序列化值的大小写 如日期/时间类型反序列化器
use_wrapper_name_as_property_name: false # 使用包装器名称覆盖属性名称 annotationintrospector#findwrappername指定的
use_std_bean_naming: false # 是否以强制与 bean 名称自省严格兼容的功能,若开启后(geturl())变成url (jackson默认false, url)
allow_explicit_property_renaming: false #是否允许jsonproperty注解覆盖propertynamingstrategy
allow_coercion_of_scalars: true # 是否允许强制使用文本标题 ,即将字符串的"true"当作布尔的true ,字符串的"1.0"当作"double"
ignore_duplicate_module_registrations: true #如果模块相同(module#gettypeid()返回值相同),只有第一次能会真正调用注册方法
ignore_merge_for_unmergeable: true #在合并不能合并的属性时是否忽略错误
block_unsafe_polymorphic_base_types: false #阻止不安全的基类(如object closeable cloneable autocloseable serializable)
parser:
auto_close_source: true #是否自动关闭不属于解析器的底层输入流
allow_comments: false #是否允许json注解(json规范是不能加注释的,但这里可以配置)
allow_yaml_comments: false #是否允许出现yaml注释
allow_unquoted_field_names: false #是否允许出现字段名不带引号
allow_single_quotes: false # 是否允许出现单引号,默认false
allow_unquoted_control_chars: false #是否允许出现未加转义的控制字符
allow_backslash_escaping_any_character: false #是否允许对所有字符都可加反斜杠转义
allow_numeric_leading_zeros: false #是否允许前导的零 000001
allow_leading_decimal_point_for_numbers: false #是否允许前导的小点数 如 ".04314"会被解析成"0.04314"
allow_non_numeric_numbers: false #是否允许nan型的浮点数 ("inf"当作正无穷 "-inf"当作负无穷 "nan"非数字,类型于除数为0)
allow_missing_values: false # 是否允许json数组中出现缺失值 (如["value1",,"value3",]将被反序列化为["value1", null, "value3", null])
allow_trailing_comma: false # 是否允许json尾部有逗号 (如{"a": true,})
strict_duplicate_detection: false #是否启用严格的字段名重复检查(开启后会增加20-30%左右的性能开销)
ignore_undefined: false #属性定义未找到是否报错(这不是针对json,是针对avro, protobuf等需要schema的格式)
include_source_in_location: false #是否包含其源信息(如总字节数,总字符数 行号 列号 )
generator:
auto_close_target: true #是否自动关闭不属于生成器的底层输出流
auto_close_json_content: true #是否自动补全json(当有不匹配的jsontoken#start_array jsontoken#start_object时)
flush_passed_to_stream: true #是否刷新generator
quote_field_names: true #是否为字段名添加引号
quote_non_numeric_numbers: true #对于nan浮点数是否加引号
escape_non_ascii: false #非ascii码是否需要转义
write_numbers_as_strings: false #将数字当作字符串输出 (防止javascript长度限制被截断)
write_bigdecimal_as_plain: false #按bigdecimal的toplainstring()输出
strict_duplicate_detection: false #是否启用严格的字段名重复检查
ignore_unknown: false #属性定义未找到是否报错(这不是针对json,是针对avro, protobuf等需要schema的格式)常用配置
spring:
jackson:
#时间格式化
date-format: yyyy-mm-dd hh:mm:ss
time-zone: gmt+8
#设置空如何序列化
default-property-inclusion: non_null
serialization:
#格式化输出
indent_output: true
#忽略无法转换的对象
fail_on_empty_beans: false
deserialization:
#允许对象忽略json中不存在的属性
fail_on_unknown_properties: false
parser:
#允许出现特殊字符和转义符
allow_unquoted_control_chars: true
#允许出现单引号
allow_single_quotes: true总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持代码网。
发表评论