业务场景
工作中,经常出现:JSON 格式的字符串与 Java 对象互相转换的情形。比如单点登陆,将“用户信息”保存到 redis 时,Java 对象要转成 JSON 字符串,从 redis 取出“用户信息”后,要将 JSON 字符串转成 Java 对象。使用MongoDB保存和读取某些运算的结果集也是如此,因此,我们需要一个合适的轮子。
JSON有两种格式,一种是对象,另一种是数组。大括号保存对象,中括号保存数组。
{"name":"JSON","address":"北京市西城区","age":25}//对象格式的字符串
[{"name":"JSON","address":"北京市西城区","age":25}]//数组格式的字符串
从上面的两种格式可以看出对象格式和数组对象格式唯一的不同则是在对象格式的基础上加上了[]。再来看具体的结构,可以看出都是以键值对的形式出现的,多个键值对之间以英文状态下的逗号(,)分隔。
引用 Maven 依赖
我们需要在Maven中引用几个工具包:
org.codehaus.jackson
jackson-core-asl
1.9.12
org.codehaus.jackson
jackson-mapper-asl
1.9.12
log4j
log4j
1.2.17
org.slf4j
slf4j-api
1.7.25
org.slf4j
slf4j-log4j12
1.7.25
test
org.slf4j
slf4j-simple
1.7.25
test
org.projectlombok
lombok
1.18.10
provided
定义、配置工具类
这个工具类完全适合作为“轮子”,用在实际工作中。
importorg.apache.commons.lang3.StringUtils;importorg.apache.log4j.Logger;importorg.codehaus.jackson.map.DeserializationConfig;importorg.codehaus.jackson.map.JsonMappingException;importorg.codehaus.jackson.map.ObjectMapper;importorg.codehaus.jackson.map.SerializationConfig;importorg.codehaus.jackson.type.JavaType;importjava.io.IOException;importjava.util.List;public classJsonUtils {private static final Logger LOG = Logger.getLogger(JsonUtils.class);//定义jackson对象,用于 Java 对象的序列化及反序列化
private static final ObjectMapper MAPPER = newObjectMapper();static{//config//设置实体无属性和json串属性对应时不会出错,只转换对应的属性
MAPPER.disable(DeserializationConfig.Feature.FAIL_ON_UNKNOWN_PROPERTIES);//忽略空bean转 JSON 的错误
MAPPER.configure(SerializationConfig.Feature.FAIL_ON_EMPTY_BEANS, false);
}/*** 将对象转换成json字符串。
*
Title: pojoToJson
*
Description:
*
*@paramdata
*@return
*/
public staticString objectToJson(Object data) {try{returnMAPPER.writeValueAsString(data);
}catch(JsonMappingException e) {
LOG.error(e);
}catch(IOException e) {
LOG.error(e);
}return null;
}/*** 将json结果集转化为对象
*
*@paramjsonData json数据
*@parambeanType 对象中的object类型, 将此方法声明为泛型方法,可传入任何对象
*@return 目标对象*/
public static T jsonToPojo(String jsonData, ClassbeanType) {if (StringUtils.isEmpty(jsonData) || null ==beanType) {return null;
}try{returnMAPPER.readValue(jsonData, beanType);
}catch(Exception e) {
LOG.error(e);
}return null;
}/*** 将json数据转换成pojo对象list
*
Title: jsonToList
*
Description:
*
*@paramjsonData
*@parambeanType
*@return
*/
public static List jsonToList(String jsonData, ClassbeanType) {if (StringUtils.isEmpty(jsonData) || null ==beanType) {return null;
}
JavaType javaType= MAPPER.getTypeFactory().constructParametricType(List.class, beanType);try{returnMAPPER.readValue(jsonData, javaType);
}catch(Exception e) {
LOG.error(e);
}return null;
}
}
测试用例
首先创建一个实体Student:
importlombok.Getter;importlombok.Setter;importlombok.ToString;importjava.io.Serializable;importjava.util.Date;/***@authorWiener*/@Getter
@Setter
@ToStringpublic class Student implementsSerializable {private static final long serialVersionUID = -5246589941647210011L;//姓名
privateString name;//年龄
privateString age;//住址
privateString address;privateDate day;
}
使用上述测试验证工具类:
importorg.apache.log4j.Logger;importjava.util.ArrayList;importjava.util.Date;importjava.util.List;public classJsonTest {private static final Logger LOG = Logger.getLogger(JsonTest.class);public static voidconvertObject() {
Student stu=newStudent();
stu.setName("JSON");
stu.setAge("23");
stu.setDay(newDate());
stu.setAddress("北京市西城区");//1、使用JSONObject
String jsonStr =JsonUtils.objectToJson(stu);
LOG.info("----- jsonStr = " +jsonStr);//2、使用JSONArray
Student stuPojo = JsonUtils.jsonToPojo(jsonStr, Student.class);
LOG.info("stuPojo:" +stuPojo.toString());
List studentList = new ArrayList<>();
studentList.add(stu);
String arrayStr="[{\"name\":\"JSON\",\"age\":\"29\",\"address\":\"北京市朝阳区\",\"addressTest\":\"无对应属性,不转换\"}]";
List students = JsonUtils.jsonToList(arrayStr, Student.class);
LOG.info("addressTest无对应属性,不转换。----- students = " +students);
}public static voidmain(String[] args) {
convertObject();
}
}
执行结果:
- ----- jsonStr = {"name":"JSON","age":"23","address":"北京市西城区","day":1573114596594}- stuPojo:Student(name=JSON, age=23, address=北京市西城区, day=Thu Nov 07 16:16:36 CST 2019)- addressTest无对应属性,不转换。----- students = [Student(name=JSON, age=29, address=北京市朝阳区, day=null)]
Reference
https://www.cnblogs.com/ScarecrowAnBird/p/7804434.html