json java对象 简书_工具类—Json字符串及Java对象互转

前言

本篇文章中,所使用的架构是前后端半分离,采用 SpringMVC + JSP + JS 实现视图层,三者的分工,如下:

SpringMVC :1. JSP 模版绑定;2. 数据提交及返回;

JSP : 前台页面展示;

JS :1. 数据提交/接收;2. 数据渲染;3. 网页效果。

业务场景

工作中,经常出现:JSON 格式的字符串与 Java 对象互相转换的情形。如果我们使用 SpringMVC 框架,就可以用 :

@ResponseBody 返回 JSON 数据

@RequestBody 接收 JSON 数据

但这种方式只能用于 Controller 的接收及返回,无法应用在其它场景。比如:

拦截器中,对某些非法参数进行拦截,并返回错误信息。这时候就要重写 HttpResponse,再返回 JSON 格式。

单点登陆,将“用户信息”保存到 redis 时,Java 对象要转成 JSON 字符串;从 redis 取出“用户信息”后,要将 JSON 字符串转成 Java 对象。

在上述这两种情景中,我们需要一个工具类,来实现:JSON 字符串及 Java 对象的互转。

基本设计

这个工具类,我们命名为:JsonMapper,有 2 个核心方法:

JSON 字符串转 Java 对象;

Java 对象转 JSON 字符串;

功能实现

这个工具类已经用在实际工作上,完全适合作为“轮子”,供大家在日常工作中使用,“源码地址”放在文末。

这里,我们为了更清晰地解释代码的作用及设计思路,会把分析写在“代码注释”上。所以,大家如果想比较深入的理解代码及知识点,可以认真阅读下面的“代码注释”及“知识点介绍”。

1. 引用 Maven 依赖

我们需要在Maven中,引用 1 个工具包,

org.codehaus.jackson

jackson-mapper-asl

1.9.12

2. 定义、配置 ObjectMapper

这里,我们需要新建 JsonMapper 类,代码如下:

public class JsonMapper {

// 日志

private static Logger log = LoggerFactory.getLogger(JsonMapper.class);

// 用于 Java 对象的序列化及反序列化

private static ObjectMapper objectMapper = new ObjectMapper();

// objectMapper 配置

static {

// 对象的所有字段全部列入

objectMapper.setSerializationInclusion(Inclusion.ALWAYS);

// 取消默认转换 timestamps

objectMapper.configure(SerializationConfig.Feature.WRITE_DATES_AS_TIMESTAMPS, false);

// 忽略空bean转 JSON 的错误

objectMapper.configure(SerializationConfig.Feature.FAIL_ON_EMPTY_BEANS, false);

// 所有日期格式都统一为:yyyy-MM-dd HH:mm:ss

objectMapper.setDateFormat(new SimpleDateFormat(DateTimeUtil.STANDARD_FORMAT));

// 忽略 JSON 字符串存在,但 Java 对象中不存在对应属性的情况,防止错误

objectMapper.configure(DeserializationConfig.Feature.FAIL_ON_UNKNOWN_PROPERTIES, false);

}

}

3. Java 对象序列化为 JSON 字符串

/**

* 对象转换json字符串

* @param obj 任意对象

* @param 将此方法声明为泛型方法,可传入任何对象

* @return json字符串

*/

public static String obj2String(T obj) {

if (obj == null) {

return null;

}

// 如果是String,则返回原对象,否则执行对象转json

try {

return obj instanceof String ? (String) obj : objectMapper.writeValueAsString(obj);

} catch (Exception e) {

log.warn("Parse Object to String error:", e);

return null;

}

}

/**

* 对象转换json字符串,并返回格式化好的json字符串

* @param obj 任意对象

* @param 将此方法声明为泛型方法,可传入任何对象

* @return json字符串

*/

public static String obj2StringPretty(T obj) {

if (obj == null) {

return null;

}

// 如果是String,则返回原对象,否则执行对象转json

try {

return obj instanceof String ? (String) obj : objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(obj);

} catch (Exception e) {

log.warn("Parse Object to String error:", e);

return null;

}

}

4. JSON 字符串反序列化为 Java 对象

/**

* json字符串转换对象

* @param str json字符串

* @param clazz 转换目标对象

* @param 将此方法声明为泛型方法,可传入任何对象

* @return 目标对象

*/

public static T string2Obj(String str, Class clazz) {

if (StringUtils.isEmpty(str) || clazz == null) {

return null;

}

try {

return clazz.equals(String.class) ? (T) str : objectMapper.readValue(str, clazz);

} catch (IOException e) {

log.warn("Parse String to Object error:", e);

return null;

}

}

/**

* json字符串转换对象

* @param str json字符串

* @param typeReference 转换目标对象

* @param 将此方法声明为泛型方法,可传入任何对象

* @return 目标对象的集合

*/

public static T string2Obj(String str, TypeReference typeReference) {

if (StringUtils.isEmpty(str) || typeReference == null) {

return null;

}

try {

return (T) (typeReference.getType().equals(String.class) ? str : objectMapper.readValue(str, typeReference));

} catch (IOException e) {

log.warn("Parse String to Object error:", e);

return null;

}

}

/**

* json 字符串转换成“集合对象”

* @param str json字符串

* @param collectionClass 集合类型

* @param elementClass Java对象

* @param 将此方法声明为泛型方法,可传入任何对象

* @return 目标对象的集合

*/

public static T string2Obj(String str, Class> collectionClass, Class>... elementClass) {

JavaType javaType = objectMapper.getTypeFactory().constructParametricType(collectionClass, elementClass);

try {

return objectMapper.readValue(str, javaType);

} catch (IOException e) {

log.warn("Parse String to Object error:", e);

return null;

}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值