jackson一些用法总结
闲话就不多说了,之所以想起来看这个是因为我们的项目采用前后端分离,有些参数需要序列化为前端需要的格式,一般java定义参数采用驼峰格式,前端需要的是xxx_xxx,这时候使用jackson的序列化方式就很好实现了。
引入jar包
<dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.5.3</version> </dependency>
2个pojo
package com.vincent.jacksonlearn; import java.util.List; public class School { private String schoolName; private List<Student> students; public String getSchoolName() { return schoolName; } public void setSchoolName(String schoolName) { this.schoolName = schoolName; } public List<Student> getStudents() { return students; } public void setStudents(List<Student> students) { this.students = students; } @Override public String toString() { return "School{" + "schoolName='" + schoolName + '\'' + ", students=" + students + '}'; } }
package com.vincent.jacksonlearn; import java.util.Date; public class Student { private String name; private Integer age; private Date birthdat; public String getName() { return name; } public void setName(String name) { this.name = name; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } public Date getBirthdat() { return birthdat; } public void setBirthdat(Date birthdat) { this.birthdat = birthdat; } @Override public String toString() { return "Student{" + "name='" + name + '\'' + ", age=" + age + ", birthdat=" + birthdat + '}'; } }
先测试下java对象转成json字符串
@Test public void pojo2Json() throws JsonProcessingException { School school = new School(); List<Student> list = new ArrayList<>(); Student student = new Student(); student.setAge(10); student.setName("abc"); student.setBirthdat(new Date()); school.setSchoolName("MIT"); list.add(student); school.setStudents(list); ObjectMapper objectMapper = new ObjectMapper(); String jsonStr = objectMapper.writeValueAsString(school); System.out.println(jsonStr); }
输出结果为:{"schoolName":"MIT","students":[{"name":"abc","age":10,"birthdat":1504160502692}]}
测试下json字符串转成java对象
@Test public void json2Pojo() throws IOException { String jsonStr = "{\"schoolName\":\"MIT\",\"students\":[{\"name\":\"abc\",\"age\":10,\"birthdat\":1504160502692}]}"; ObjectMapper objectMapper = new ObjectMapper(); School school = objectMapper.readValue(jsonStr,School.class); System.out.println(school); }
输出结果为:School{schoolName='MIT', students=[Student{name='abc', age=10, birthdat=Thu Aug 31 14:21:42 CST 2017}]}
基本用法已经介绍完毕,下面开始根据实际需求进行相应改变。
情景一:
以第一个java对象转为json字符的示例来说,后端代码写完了,这时候我们将结果输出给前端(spring开发的小伙伴别忘了@ResponseBody注解),前端一看,不对啊,schoolName怎么是驼峰命名呢?日期怎么没有按照我们约定的yyyy-MM-dd的格式呢。
这时候我们在这两个属性下加上这两个注解就ok了。
@JsonProperty("school_name") private String schoolName; @JsonFormat(pattern = "yyyy-MM-dd") private Date birthdat;
再运行下之前的测试方法会发现结果变成了前端想要的结果了。
{"students":[{"name":"abc","age":10,"birthdat":"2017-08-31"}],"school_name":"MIT"}
情景二:
有时候有些值的结果并不想返回给前端,这时候在这个属性上加上@JsonIgnore就ok了
在student的age上加上这个注解 @JsonIgnore private Integer age;
执行ojo2Json()方法返回结果如下
{"students":[{"name":"abc","birthdat":"2017-08-31"}],"school_name":"MIT"}
说了这么多,大家一定有疑问,问什么这些注解能应用于spring呢?
原因在于spring的AbstractMessageConverterMethodArgumentResolver类的readWithMessageConverters方法
仔细看下去会发现他最终会调用这个一段代码
if (inputMessage instanceof MappingJacksonInputMessage) { Class<?> deserializationView = ((MappingJacksonInputMessage) inputMessage).getDeserializationView(); if (deserializationView != null) { return this.objectMapper.readerWithView(deserializationView).forType(javaType). readValue(inputMessage.getBody()); } } return this.objectMapper.readValue(inputMessage.getBody(), javaType);
---恢复内容结束---
---恢复内容结束---