Jackson 默认支持多种基本数据类型和复杂数据类型的序列化和反序列化。例如常见的布尔类型、字符串类型、集合、数组、枚举等,但某些特定类型(如 Java 8 的 LocalDateTime、LocalDate、LocalTime 等)需要额外的模块支持。需要进行如下配置:
1、你需要添加 jackson-datatype-jsr310 模块。
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jsr310</artifactId>
<version>2.13.3</version> <!-- 请根据你的Jackson版本选择合适的版本 -->
</dependency>
2、同时封装如下的公共对象,轻松实现java对象、json对象、json字符串之间的相互转化:
package xxxxxx;
import com.fasterxml.jackson.datatype.jsr310.deser.InstantDeserializer;
import com.fasterxml.jackson.datatype.jsr310.ser.InstantSerializer;
import xxxxxxxxx.JSONConvertException;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.*;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateDeserializer;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateSerializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
import com.fasterxml.jackson.datatype.jsr310.ser.OffsetDateTimeSerializer;
import com.google.gson.Gson;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import com.jayway.jsonpath.Configuration;
import com.jayway.jsonpath.JsonPath;
import com.jayway.jsonpath.PathNotFoundException;
import com.jayway.jsonpath.Predicate;
import lombok.extern.slf4j.Slf4j;
import java.io.IOException;
import java.lang.reflect.Type;
import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.OffsetDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
/**
* @author xxxx
*/
@Slf4j
public class JsonUtils {
private static final ObjectMapper objectMapper;
private static final ObjectMapper rawObjectMapper;
private static final ObjectMapper snakeCaseMapper;
private static final Gson GSON = new Gson();
static {
JavaTimeModule javaTimeModule = new JavaTimeModule();
DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern(TimeUtils.DATETIME_FORMAT_PATTERN);
javaTimeModule.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(dateTimeFormatter));
javaTimeModule.addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(dateTimeFormatter));
DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern(TimeUtils.DATE_FORMAT_PATTERN);
javaTimeModule.addSerializer(LocalDate.class, new LocalDateSerializer(dateFormatter));
javaTimeModule.addDeserializer(LocalDate.class, new LocalDateDeserializer(dateFormatter));
javaTimeModule.addSerializer(Instant.class, InstantSerializer.INSTANCE);
javaTimeModule.addDeserializer(Instant.class, InstantDeserializer.INSTANT);
javaTimeModule.addSerializer(OffsetDateTime.class, OffsetDateTimeSerializer.INSTANCE);
objectMapper = new ObjectMapper()
.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS)
.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
.setSerializationInclusion(com.fasterxml.jackson.annotation.JsonInclude.Include.NON_NULL)
.registerModule(javaTimeModule);
rawObjectMapper = new ObjectMapper()
.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS)
.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
.setSerializationInclusion(com.fasterxml.jackson.annotation.JsonInclude.Include.NON_NULL);
snakeCaseMapper = new ObjectMapper()
.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS)
.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
.setSerializationInclusion(com.fasterxml.jackson.annotation.JsonInclude.Include.NON_NULL)
.registerModule(javaTimeModule)
.setPropertyNamingStrategy(PropertyNamingStrategy.SNAKE_CASE);
}
/**
* json元素到对象
* @param json
* @param classOfT
* @param <T>
* @return
*/
public static <T> T fromJson(JsonElement json, Class<T> classOfT) {
if (json == null) {
return null;
}
return GSON.fromJson(json, classOfT);
}
/**
* 字符串转换成对象
* @param json
* @param typeOfT
* @param <T>
* @return
*/
public static <T> T fromJson(String json, Type typeOfT) {
return GSON.fromJson(json, typeOfT);
}
/**
* 对象 to 字符串
* @param src
* @return
*/
public static String toJson(Object src) {
return GSON.toJson(src);
}
/**
* 字符串解析成 JsonObject
* @param json
* @return
*/
public static JsonObject parserJsonObject(String json) {
return JsonParser.parseString(json).getAsJsonObject();
}
public static ObjectMapper defaultObjectMapper(){
return objectMapper;
}
/**
* 任意对转换为JSON字符串
*
* @param obj
* @return
*/
public static String object2JsonString(Object obj) {
objectMapper.setVisibility(PropertyAccessor.FIELD, JsonAutoDetect.Visibility.ANY);
String jsonString = null;
try {
jsonString = objectMapper.writeValueAsString(obj);
} catch (JsonProcessingException e) {
throw new RuntimeException("Json转换异常");
}
return jsonString;
}
public static ObjectNode createObjectNode() {
return objectMapper.createObjectNode();
}
public static ObjectNode createObjectNode(String key, String value) {
ObjectNode node = createObjectNode();
node.put("key", key);
node.put("value", value);
return node;
}
public static ArrayNode createArrayNode() {
return objectMapper.createArrayNode();
}
/**
* 任意对象转为ObjectNode
*
* @param o
* @return
*/
public static ObjectNode object2ObjectNode(Object o) {
return objectMapper.convertValue(o, ObjectNode.class);
}
public static ObjectNode object2ObjectNodeSnakeCase(Object o){
return snakeCaseMapper.convertValue(o, ObjectNode.class);
}
/**
* 任意对象转为ArrayNode
*
* @param o
* @return
*/
public static ArrayNode objectToArrayNode(Object o) {
return objectMapper.convertValue(o, new TypeReference<ArrayNode>() {
});
}
/**
* Convert object to json
*
* @param fromValue the pojo class
* @param <T> Json node
* @return
*/
public static <T extends JsonNode> T object2Json(Object fromValue) {
return objectMapper.valueToTree(fromValue);
}
/**
* Convert object to json string
*
* @param fromValue the pojo class
* @return string in json format
*/
public static String object2JsonStr(Object fromValue) {
String jsonString = null;
try {
jsonString = objectMapper.writeValueAsString(fromValue);
} catch (JsonProcessingException e) {
throw new JSONConvertException("convert json string error");
}
return jsonString;
}
/**
* Convert json string to java pojo
*
* @param jsonStr the string in json format
* @param type the java class type
* @param <T> the class type
* @return the instance of class type
*/
public static <T> T jsonStr2Object(String jsonStr, Class<T> type) {
T obj;
try {
obj = objectMapper.readValue(jsonStr, type);
} catch (Exception e) {
throw new JSONConvertException(e);
}
return obj;
}
/**
* Convert json to java pojo
*
* @param jsonNode the json object
* @param type the java class type
* @param <T> the class type
* @return the instance of class type
*/
public static <T> T json2Object(JsonNode jsonNode, Class<T> type) {
T obj;
try {
obj = objectMapper.convertValue(jsonNode, type);
} catch (Exception e) {
throw new JSONConvertException(e);
}
return obj;
}
/**
* 获得json path对象,json path对象是使用json path库的基础
*
* @param bluePrintStr String in json format
* @return json path object
*/
public static Object toJsonPath(String bluePrintStr) {
return Configuration.defaultConfiguration().jsonProvider().parse(bluePrintStr);
}
public static <T> T silentReadJsonPath(Object json, String jsonPath, Predicate... filters) {
try {
return readJsonPath(json, jsonPath, filters);
} catch (PathNotFoundException e) {
//keep silent
}
return null;
}
public static <T> T readJsonPath(Object json, String jsonPath, Predicate... filters) {
return JsonPath.read(json, jsonPath, filters);
}
public static <T> T fromJson(String content, Class<T> valueType) {
try {
return objectMapper.readValue(content, valueType);
} catch (IOException ioException) {
throw new RuntimeException(ioException);
}
}
public static String toJsonString(Object value) {
try {
return objectMapper.writeValueAsString(value);
} catch (JsonProcessingException e) {
throw new RuntimeException(e);
}
}
public static <T> List<T> arrayNodeToList(ArrayNode node, Class<T> clazz) {
List<T> list = new ArrayList<>();
node.forEach(n1 -> {
list.add(fromJson(toJsonString(n1), clazz));
});
return list;
}
}
package xxxx.common.exception
public class JSONConvertException extends ProcessException {
public JSONConvertException(String msg, Throwable original) {
super(msg, original);
}
public JSONConvertException(Throwable original) {
super(original);
}
public JSONConvertException(String msg) {
super(msg);
}
}
package xxxxx.common.exception;
import lombok.Getter;
@Getter
public class ProcessException extends RuntimeException{
protected String msg = null;
protected Throwable original = null;
public ProcessException(String msg, Throwable original){
this.msg = msg;
this.original = original;
}
public ProcessException(Throwable original){
this.original = original;
}
public ProcessException(String msg){
this.msg = msg;
}
public static ProcessException create(Throwable original){
return new ProcessException(original.getMessage(),original);
}
public static ProcessException create(String msg){
return new ProcessException(msg);
}
}