# Jackson 学习使用
Posted 爱码代码的喵
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了# Jackson 学习使用相关的知识,希望对你有一定的参考价值。
Jackson 学习使用
Jackson
是一个简单基于Java
应用库,Jackson
可以轻松的将Java
对象转换成json
对象和xml
文档,同样也可以将json、xml
转换成Java
对象。Jackson
所依赖的jar
包较少,简单易用并且性能也要相对高些,并且Jackson
社区相对比较活跃,更新速度也比较快。
Jackson 优点
- 解析大文件的速度比较快;
- 运行时占用的内存比较少,性能更佳;
API
很灵活,容易进行扩展和定制
Jackson 的核心模块
jackson-core
:核心包,提供基于“流模式”解析的相关API
,包括JsonPaser
和JsonGenerator
。jackson-annotations
:注解包,提供标准的注解功能;jackson-databind
:数据绑定包,提供基于“对象绑定”解析的相关API
和基于“树模型”解析的相关API
引入 Jackson 依赖
要想使用 Jackson
,需要在 pom.xml
文件中添加 Jackson
的依赖。
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.10.1</version>
</dependency>
jackson-databind
依赖于 jackson-core
和 ~,所以添加完 jackson-databind
之后,Maven
会自动将 jackson-core
和 jackson-annotations
引入到项目当中。
多态类型的序列化及反序列化
-
要对
json
对象进行反序列化操作,但是我们并不知知道具体的json
格式,也就是说我们不知道json
有哪些字段。 -
解析抽象类或者接口
@JsonTypeInfo
Animal
抽象类:使用JsonTypeInfo
注解配置反序列化的规则
@JsonTypeInfo(
use = JsonTypeInfo.Id.NAME,
property = "name",
visible = true,
include = JsonTypeInfo.As.EXISTING_PROPERTY)
@JsonSubTypes(
@JsonSubTypes.Type(value = Dog.class, name = "dog"),
@JsonSubTypes.Type(value = Cat.class, name = "cat")
)
public abstract class Animal
private String name;
private String id;
// getset
Cat
子类
public class Cat extends Animal
private String speed;
Dog
子类
public class Dog extends Animal
private String food;
- 测试类
@Test
public void test1()
String tempStr = "\\"speed\\":\\"100\\",\\"name\\":\\"cat\\",\\"food\\":\\"dogfood\\"";
ObjectMapper mapper = new ObjectMapper();
// 配置忽略未知属性
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
try
Dog dog = (Dog) mapper.readValue(tempStr, Animal.class);
logger.info("cat: ", dog.toString());
catch (IOException e)
throw new RuntimeException(e);
ObjectMapper可设置的属性
ObjectMapper objectMapper = new ObjectMapper();
// 属性为Null的不进行序列化,只对pojo起作用,对map和list不起作用
objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
// json进行换行缩进等操作
objectMapper.enable(SerializationFeature.INDENT_OUTPUT);
// json不进行换行缩进等操作 默认就是不进行操作,写了这行和没写的效果一样
objectMapper.disable(SerializationFeature.INDENT_OUTPUT);
// json是否允许属性名没有引号 ,默认是false
objectMapper.configure(JsonParser.Feature.ALLOW_UNQUOTED_FIELD_NAMES, true);
//json是否允许属性名为单引号 ,默认是false
objectMapper.configure(JsonParser.Feature.ALLOW_SINGLE_QUOTES, true);
// 遇到未知属性是否抛出异常 ,默认是抛出异常的
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
// 当实体类没有setter方法时,序列化不报错,返回一个空对象
objectMapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
// 所有的字母小写,没有分隔符,例如 lowercase
objectMapper.setPropertyNamingStrategy(PropertyNamingStrategy.LOWER_CASE);
//序列化的时候序列对象的所有属性
objectMapper.setSerializationInclusion(JsonInclude.Include.ALWAYS);
//取消时间的转化格式,默认是时间戳,可以取消,同时需要设置要表现的时间格式
objectMapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
// 设置日期格式化
objectMapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));
JackSonUtils
public class JackSonUtils
private static Logger logger = LoggerFactory.getLogger(JackSonUtils.class);
private static final String YYYY_MM_DD_HH_MM_SS = "yyyy-MM-dd HH:mm:ss";
private static final ConcurrentHashMap<String, ObjectMapper> mapperMap = new ConcurrentHashMap<>();
/**
* 对象转json字符串
*
* @param object object
* @return String
*/
public static String toJSONString(Object object)
return toJSONString(object, YYYY_MM_DD_HH_MM_SS, false);
/**
* 对象转json字符串, 是否美化输出
*
* @param object object
* @param prettyFormat 是否美化输出
* @return String
*/
public static String toJSONString(Object object, boolean prettyFormat)
return toJSONString(object, YYYY_MM_DD_HH_MM_SS, prettyFormat);
/**
* 对象转json字符串,指定日期格式
*
* @param object object
* @param dataFormatString 时间格式化
* @return String
*/
public static String toJSONString(Object object, String dataFormatString)
return toJSONString(object, dataFormatString, false);
/**
* 对象转json字符串,指定日期格式, 是否美化输出
*
* @param object object
* @param dataFormatString 时间格式化
* @param prettyFormat 是否美化格式
* @return String
*/
public static String toJSONString(Object object, String dataFormatString, boolean prettyFormat)
return toJSONString(object, dataFormatString, prettyFormat, JsonInclude.Include.NON_NULL);
/**
* 对象转json字符串,空值处理
*/
public static String toJSONString(Object object, JsonInclude.Include include)
return toJSONString(object, YYYY_MM_DD_HH_MM_SS, false, include);
/**
* 对象转json字符串,指定日期格式, 空值处理
*/
public static String toJSONString(Object object, String dataFormatString, JsonInclude.Include include)
return toJSONString(object, dataFormatString, false, include);
/**
* 对象转json字符串,指定日期格式, 是否美化输出, 空值处理
*
* @param object object
* @param dataFormatString 时间日期格式化
* @param prettyFormat 是否美化输出
* @param include include
* @return String
*/
public static String toJSONString(Object object, String dataFormatString, boolean prettyFormat, JsonInclude.Include include)
if (ObjectUtils.isEmpty(object))
return null;
if (!StringUtils.hasText(dataFormatString))
dataFormatString = YYYY_MM_DD_HH_MM_SS;
ObjectMapper objectMapper = getObjectMapper(dataFormatString, prettyFormat, include);
try
return objectMapper.writeValueAsString(object);
catch (JsonProcessingException e)
logger.error(e.getMessage(), e);
return null;
/**
* 将json字符串转换成ObjectNode对象
*
* @param content content
*/
public static ObjectNode parseObject(String content)
return parseObject(content, ObjectNode.class);
/**
* 将json字符串转换成指定类型对象
*
* @param <T> T
* @param content 内容
*/
public static <T> T parseObject(String content, Class<T> valueType)
if (!StringUtils.hasText(content))
return null;
ObjectMapper objectMapper = getObjectMapper();
try
return objectMapper.readValue(content, valueType);
catch (Exception e)
logger.error(e.getMessage(), e);
return null;
/**
* 将json字符串转换成ArrayNode数组
*/
public static ArrayNode parseArray(String content)
return parseObject(content, ArrayNode.class);
/**
* 将json字符串转换成指定类型对象数组
*/
public static <T> List<T> parseArray(String content, Class<T> valueType)
if (!StringUtils.hasText(content))
return null;
ObjectMapper objectMapper = getObjectMapper();
try
CollectionType javaType = objectMapper.getTypeFactory().constructCollectionType(List.class, valueType);
return objectMapper.readValue(content, javaType);
catch (Exception e)
logger.error(e.getMessage(), e);
return null;
/**
* 将json字符串转换成Map
*
* @param content c
* @param content
*/
public static Map<String, Object> parseMap(String content)
return parseMap(content, String.class, Object.class);
/**
* 将json字符串转换成Map, 指定泛型
*/
public static <K, V> Map<K, V> parseMap(String content, Class<K> keyType, Class<V> valueType)
if (!StringUtils.hasText(content))
return null;
ObjectMapper objectMapper = getObjectMapper();
try
MapType javaType = objectMapper.getTypeFactory().constructMapType(Map.class, keyType, valueType);
return objectMapper.readValue(content, javaType);
catch (Exception e)
logger.error(e.getMessage(), e);
return null;
/**
* 将json字符串转换成Map数组
*
* @param content content
* @return List
*/
public static List<Map<String, Object>> parseMapArray(String content)
return parseMapArray(content, String.class, Object.class);
/**
* 将json字符串转换成Map数组, 指定泛型
*/
public static <K, V> List<Map<K, V>> parseMapArray(String content, Class<K> keyType, Class<V> valueType)
if (!StringUtils.hasText(content))
return null;
ObjectMapper objectMapper = getObjectMapper();
try
TypeFactory typeFactory = objectMapper.getTypeFactory();
MapType mapType = typeFactory.constructMapType(Map.class, keyType, valueType);
CollectionType collectionType = objectMapper.getTypeFactory().constructCollectionType(List.class, mapType);
return objectMapper.readValue(content, collectionType);
catch (JsonMappingException e)
logger.error("JsonMappingException: ", e);
catch (JsonProcessingException e)
logger.error("JsonProcessingException: ", e);
return null;
/**
* 获取 ObjectMapper
*
* @return ObjectMapper
*/
private static ObjectMapper getObjectMapper()
return getObjectMapper(YYYY_MM_DD_HH_MM_SS, false, JsonInclude.Include.NON_NULL);
/**
* 获取 ObjectMapper
*
* @param dataFormatString 时间格式化格式
* @param prettyFormat 是否美化输出
* @param include include
* @return ObjectMapper
*/
private static ObjectMapper getObjectMapper(String dataFormatString, boolean prettyFormat, JsonInclude.Include include)
String key = prettyFormat ? "P#" + dataFormatString : dataFormatString;
ObjectMapper objectMapper = mapperMap.get(key);
if (objectMapper != null)
return objectMapper;
mapperMap.putIfAbsent(key, new ObjectMapper());
objectMapper = mapperMap.get(key);
objectMapper.setSerializationInclusion(include);
// 忽略未知映射
objectMapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
// 日期格式
objectMapper.setDateFormat(new SimpleDateFormat(dataFormatString));
// 美化输出
if (prettyFormat)
objectMapper.enable(SerializationFeature.INDENT_OUTPUT);
// 处理 BigDecimal 精度问题
SimpleModule module = new SimpleModule();
module.addSerializer(BigDecimal.class, new BigDecimalJsonSerializer());
// 处理 Double 科学计数法
module.addSerializer(Double.class, new DoubleJsonSerializer());
objectMapper.registerModule(module);
return objectMapper;
/**
* BigDecimal 类型的序列设置
*/
private static class BigDecimalJsonSerializer extends JsonSerializer<BigDecimal>
public void serialize(BigDecimal t, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException
if (null == t)
jsonGenerator.writeNull();
else
String valStr = t.toPlainString();
if (valStr.length() > 16)
jsonGenerator.writeString(valStr);
else
jsonGenerator.writeNumber(t);
/**
* Double 类型的序列化设置
*/
private static class DoubleJsonSerializer extends JsonSerializer<Double>
public void serialize(Double value, JsonGenerator gen, SerializerProvider serializers) throws IOException
if (value == null)
gen.writeNull();
else
String valStr = value.toString();
if (valStr.contains("E"))
gen.Jackson 解析 JSON 详细教程
Jackson 时间格式化,时间注解 @JsonFormat 用法时差问题说明