平时写代码处理JSON基本上都是用阿里的fastjson,今天通过学习发现spring boot 内置的jackson也不错
我们都知道,在Spring中使用@ResponseBody
注解可以将方法返回的对象序列化成JSON响应出去
测试接口:
@Controller
public class JacksonTestController {
@ResponseBody
@GetMapping("getStudent")
public Student getStudent(){
Student student = new Student(1,"张三","123456","地球","13600000",new Date());
return student;
}
}
Student 类:
public class Student implements Serializable {
private Integer id;
private String name;
private String password;
private String address;
private String phone;
private Date createDate;
public Student() {
}
public Student(Integer id, String name, String password, String address, String
phone, Date createDate) {
this.id = id;
this.name = name;
this.password = password;
this.address = address;
this.phone = phone;
this.createDate = createDate;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
public Date getCreateDate() {
return createDate;
}
public void setCreateDate(Date createDate) {
this.createDate = createDate;
}
}
像这样,由于我使用的是@RestController所以不用再方法上,因为@RestController注解中包含@ResponseBody
@RestController
public class JacksonTestController {
@GetMapping("getStudent")
public Student getStudent(){
Student student = new Student(1,"张三","123456","地球","13600000",new Date());
return student;
}
}
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Controller
@ResponseBody
public @interface RestController {
@AliasFor(
annotation = Controller.class
)
String value() default "";
}
访问输出:
{"id":1,"name":"张三","password":"123456","address":"地球","phone":"13600000","createDate":"2019-11-07T06:29:52.466+0000"}
可看到时间的 输出形式不是我们想要的,这是只需要在Student的日期字段上加一个注解就可以解决
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date createDate;
再次请求接口,返回结果已经变成我们想要的格式
{"id":1,"name":"张三","password":"123456","address":"地球","phone":"13600000","createDate":"2019-11-07 06:36:10"}
有的时候我们不想把真实的字段名称返回给前端,这里可以使用@JsonProperty
,作用在属性上,用来为JSON Key指定一个别名。
@JsonProperty("number")
private String phone;
再次访问页面phone已经变成了number
{"id":1,"name":"张三","password":"123456","address":"地球","createDate":"2019-11-07 06:40:32","number":"13600000"}
有时候为了脱敏某些字段 比如密码 不返回给前端 可以用@Jsonlgnore注解
@JsonIgnore
private String password;
再次访问页面返回的已经没有了密码
{"id":1,"name":"张三","address":"地球","createDate":"2019-11-07 06:43:39","number":"13600000"}
有时候只返回name属性就行,而某些情况下需要返回全部属性。 因此Student对象可以做如下修改:
public class Student implements Serializable {
/**
* 只显示名字name
*/
public interface BaseStudent {};
/**
* 全部显示
*/
public interface DetailStudent extends BaseStudent {};
@JsonView(DetailStudent.class)
private Integer id;
@JsonView(BaseStudent.class)
private String name;
@JsonView(DetailStudent.class)
private String password;
@JsonView(DetailStudent.class)
private String address;
@JsonView(DetailStudent.class)
@JsonProperty("number")
private String phone;
@JsonView(DetailStudent.class)
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date createDate;
public Student() {
}
public Student(Integer id, String name, String password, String address, String phone, Date createDate) {
this.id = id;
this.name = name;
this.password = password;
this.address = address;
this.phone = phone;
this.createDate = createDate;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
public Date getCreateDate() {
return createDate;
}
public void setCreateDate(Date createDate) {
this.createDate = createDate;
}
}
分开写两个接口测试这两种情况
@RestController
public class JacksonTestController {
@JsonView(Student.DetailStudent.class)
@GetMapping("getStudent")
public Student getStudent(){
Student student = new Student(1,"张三","123456","地球","13600000",new Date());
return student;
}
@JsonView(Student.BaseStudent.class)
@GetMapping("getName")
public Student getName(){
Student student = new Student(1,"张三","123456","地球","13600000",new Date());
return student;
}
}
第一个查询所有信息 返回详细信息
{"id":1,"name":"张三","password":"123456","address":"地球","createDate":"2019-11-07 06:54:18","number":"13600000"}
第二个查询 值返回name
{"name":"张三"}
@ResponseBody和@RequestBody的序列化和反序列化 序列化就是上面看到的把输出的Student序列化成json字符串。反序列化就是前端传过来的json字符串反序列化成Student
@GetMapping("saveStudent")
public Student saveStudent(@RequestBody Student student){
//student 已经是一个实例了
return student;
}