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