如何对带有返回的对象进行输出,可以凝练出下面的工具类。
import static com.fasterxml.jackson.core.JsonFactory.Feature.INTERN_FIELD_NAMES;
import static com.fasterxml.jackson.databind.type.TypeFactory.defaultInstance;
import java.io.IOException;
import java.io.InputStream;
import java.util.Collection;
import java.util.Map;
import javax.annotation.Nullable;
import org.apache.commons.lang3.StringUtils;
import com.fasterxml.jackson.core.JsonFactory;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper;
public class ObjectMapperUtils {
private static final String EMPTY_JSON = "{}";
private static final String EMPTY_ARRAY_JSON = "[]";
//解决jackson2.9.x版本内存泄露的问题,详见[2] Jackson2.x中内存泄露的风险点—封装的intern逻辑
private static final ObjectMapper MAPPER = new ObjectMapper(new JsonFactory().disable(INTERN_FIELD_NAMES));
public static String toJSON(@Nullable Object obj) {
if (obj == null) {
return null;
}
try {
return MAPPER.writeValueAsString(obj);
} catch (JsonProcessingException e) {
throw new RuntimeException(e);
}
}
/**
* 实现类型的强转。能实现【父类-->子类】的强转。
* 这一点在{@code (父类)子类}是实现不了的。
*/
public static <T> T value(Object rawValue, Class<T> type) {
return MAPPER.convertValue(rawValue, type);
}
/**
* 注意,一般情况不推荐使用本方法,因为开销还是略大,可以选择的几个方式是:
* <p>
* 1. 直接 {@link #fromJSON} 解析,适用于本身也是要解析JSON并生成DTO,并且是主要分支的场景
* 2. 自己编写一个方法,只检查第一个字符,适合内部特定数据结构兼容的快速检查,并不需要完整的 JSON 检查
*/
public static boolean isJSONWithHeavyweight(String jsonStr) {
if (StringUtils.isBlank(jsonStr)) {
return false;
}
try (JsonParser parser = new ObjectMapper().getFactory().createParser(jsonStr)) {
while (parser.nextToken() != null) {
// do nothing.
}
return true;
} catch (IOException ioe) {
return false;
}
}
/**
* 轻量级的校验方法
*/
public static boolean isJSONWithLightweight(String jsonStr) {
if (StringUtils.isBlank(jsonStr)) {
return false;
}
return jsonStr.startsWith("{") || jsonStr.startsWith("[");
}
/**
* 带有泛型对象的强转
*/
public static <T> T value(Object rawValue, TypeReference<T> type) {
return MAPPER.convertValue(rawValue, type);
}
public static <T> T value(Object rawValue, JavaType type) {
return MAPPER.convertValue(rawValue, type);
}
/**
* 支持带泛型的集合反序列化输出
*/
public static <E, T extends Collection<E>> T fromJSON(String json,
Class<? extends Collection> collectionType, Class<E> valueType) {
if (StringUtils.isEmpty(json)) {
json = EMPTY_ARRAY_JSON;
}
try {
return MAPPER.readValue(json,
defaultInstance().constructCollectionType(collectionType, valueType));
} catch (IOException e) {
throw new RuntimeException(e);
}
}
/**
* 支持带有泛型的Map的输出
*/
public static <K, V, T extends Map<K, V>> T fromJSON(String json, Class<? extends Map> mapType,
Class<K> keyType, Class<V> valueType) {
if (StringUtils.isEmpty(json)) {
json = EMPTY_JSON;
}
try {
return MAPPER.readValue(json,
defaultInstance().constructMapType(mapType, keyType, valueType));
} catch (IOException e) {
throw new RuntimeException(e);
}
}
public static <T> T fromJSON(InputStream inputStream, Class<T> type) {
try {
return MAPPER.readValue(inputStream, type);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
/**
* 当json中只有bean部分属性时,更新一个存在的bean,只覆盖该部分的属性。
* 当存在相同的属性时,json中属性的优先级明显会更高。
*/
public static <T> T update(T rawValue, String jsonString) {
try {
return MAPPER.readerForUpdating(rawValue).readValue(jsonString);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
public static <T> T fromJSON(Object value, Class<T> valueType) {
if (value == null) {
return null;
} else if (value instanceof String) {
return fromJSON((String) value, valueType);
} else if (value instanceof byte[]) {
return fromJSON((byte[]) value, valueType);
} else {
return null;
}
}
public static <T> T fromJSON(@Nullable byte[] bytes, Class<T> valueType) {
if (bytes == null) {
return null;
}
try {
return MAPPER.readValue(bytes, valueType);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
public static <T> T fromJSON(@Nullable String json, Class<T> valueType) {
if (json == null) {
return null;
}
try {
return MAPPER.readValue(json, valueType);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
public static <T> T parseObject(String str, TypeReference<T> type) {
try {
return MAPPER.readValue(str, type);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
对二级数组进行反序列化的操作?
public static void main(String[] args) {
List<List<Integer>> v1 = Lists.newArrayList(Lists.newArrayList(1, 2, 3), Lists.newArrayList(4, 2, 3));
//二维数组的反序列化
List<List<Integer>> lists = parseObject(toJSON(v1), new TypeReference<List<List<Integer>>>() {
});
System.out.println(lists);
}
网友评论