首页 前端知识 Jackson @JsonUnwrapped注解扁平化 序列化反序列化数据

Jackson @JsonUnwrapped注解扁平化 序列化反序列化数据

2024-08-08 22:08:20 前端知识 前端哥 729 273 我要收藏

参考资料

  1. Jackson 2.x 系列【7】注解大全篇三
  2. @JsonUnwrapped 以扁平的数据结构序列化/反序列化属性
  3. Jackson扁平化处理对象

目录

  • 一. 前期准备
    • 1.1 前端
    • 1.2 实体类
    • 1.3 Controller层
  • 二. 扁平化序列反序列化数据
    • 2.1 序列化数据
    • 2.2 反序列化数据
  • 三. 前缀后缀处理属性同名
  • 四. Map数据的处理


一. 前期准备

1.1 前端

$(function() {
bindEvent();
});
function bindEvent() {
$("#btn").click(() => {
// 准备提交到后端的数据
const jsonData = {
id: "112",
name: "前端来的name",
houseId: "前端来的houseId",
address: "前端来的address",
blogId: "前端来的blogId",
blogName: "前端来的blogName"
};
$.ajax({
url: `/test34/get_data`,
type: 'POST',
data: JSON.stringify(jsonData),
contentType: 'application/json;charset=utf-8',
success: function (data, status, xhr) {
console.log(data);
}
});
});
}
复制

1.2 实体类

import com.fasterxml.jackson.annotation.*;
import lombok.Data;
@Data
public class Test34Entity {
private String id;
private String name;
@JsonUnwrapped
private House house;
@JsonUnwrapped
private BlogTag blogTag;
}
复制
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class House {
private String houseId;
private String address;
}
复制
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class BlogTag {
private String blogId;
private String blogName;
}
复制

1.3 Controller层

mport org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
import java.io.IOException;
@Controller
@RequestMapping("/test34")
public class Test34Controller {
@GetMapping("/init")
public ModelAndView init() {
ModelAndView modelAndView = new ModelAndView();
modelAndView.setViewName("test34");
return modelAndView;
}
@PostMapping("/get_data")
public ResponseEntity<Test34Entity> getData(@RequestBody Test34Entity data) throws IOException {
System.out.println(data);
Test34Entity entity = new Test34Entity();
// 设置基本类型的属性值
entity.setId("1355930");
entity.setName("贾飞天");
// 设置自定义类型(bean)的属性值
entity.setHouse(new House("house_id_1", "地球"));
entity.setBlogTag(new BlogTag("tag_id_1", "tag_name_1"));
return ResponseEntity.ok(entity);
}
}
复制

二. 扁平化序列反序列化数据

@JsonUnwrapped注解只能处理Bean类型的数据,List<Bean>Map<键,Bean>等数据类型是无法处理的。

2.1 序列化数据

  • 给需要扁平化处理的Bean添加@JsonUnwrapped注解
  • 需要扁平化处理的Bean还需要有构造函数,必须有构造函数,否则后台接收数据时会报错。
  • 这样前台扁平化提交数据的时候,后台可以用一个类组合多个类的方式接收数据

⏹使用@JsonUnwrapped注解之前

  • 前台需要提交如下的数据结构,前台的数据结构层次需要根据后台的Bean结构层次调整
const jsonData = {
id: "112",
name: "前端来的name",
house: {
houseId: "前端来的houseId",
address: "前端来的address"
},
blogTag: {
blogId: "前端来的blogId",
blogName: "前端来的blogName"
}
};
复制
  • 后台使用的数据结构
@Data
public class Test34Entity {
private String id;
private String name;
private House house;
private BlogTag blogTag;
}
复制

⏹使用@JsonUnwrapped注解之后,前台无需根据后台的Bean结构来组装数据,直接扁平化提交即可,对于一些不使用Vue,React框架等前台框架的项目有用,能写起来更简单。

  • 前台数据结构
const jsonData = {
id: "112",
name: "前端来的name",
houseId: "前端来的houseId",
address: "前端来的address",
blogId: "前端来的blogId",
blogName: "前端来的blogName"
};
复制
  • 后台数据结构
@Data
public class Test34Entity {
private String id;
private String name;
@JsonUnwrapped
private House house;
@JsonUnwrapped
private BlogTag blogTag;
}
复制

⏹实质上是Jackson 通过@JsonUnwrapped注解将HouseBlogTag属性拍扁放到Test34Entity实体类中。右下图可以看到,数据自动完成了封装。

在这里插入图片描述

2.2 反序列化数据

⏹不使用@JsonUnwrapped注解,前台的json数据结构和后台的Bean相同。

在这里插入图片描述

⏹使用@JsonUnwrapped注解,后台的嵌套的Bean属性被展平后返回给前台。

在这里插入图片描述


三. 前缀后缀处理属性同名

😅如下图所示,由于Test34Entity类和组合类的属性名相同,从而导致属性丢失。

在这里插入图片描述

⏹可以在@JsonUnwrapped注解上指定前缀或后缀来避免属性重名问题

import com.fasterxml.jackson.annotation.*;
import lombok.Data;
@Data
public class Test34Entity {
private String id;
private String name;
@JsonUnwrapped(prefix = "house_", suffix = "_suffix")
private House house;
@JsonUnwrapped(prefix = "blog_", suffix = "_suffix")
private BlogTag blogTag;
@Data
public static class BlogTag {
private String id;
private String name;
}
@Data
public static class House {
private String id;
private String address;
}
}
复制

⏹反映到前端的截图如下所示

在这里插入图片描述


四. Map数据的处理

😅@JsonUnwrapped注解原生不支持Map,由下图所示,前台得到的json中,blogTagMap属性依然存在。

在这里插入图片描述

⏹将Test34Entity 实体类,进行如下修改

  • 使用@JsonAnySetter@JsonAnyGetter注解
  • addBlogTagMap,getBlogTagMap,setBlogTagMap方法名中的blogTagMap部分和属性名blogTagMap保持一致。
import com.fasterxml.jackson.annotation.*;
import lombok.Data;
import java.util.Map;
@Data
public class Test34Entity {
private String id;
private String name;
private Map<String, BlogTag> blogTagMap;
@JsonAnySetter
public void addBlogTagMap(String key, BlogTag value) {
blogTagMap.put(key, value);
}
@JsonAnyGetter
public Map<String, BlogTag> getBlogTagMap() {
return blogTagMap;
}
public void setBlogTagMap(Map<String, BlogTag> blogTagMap) {
this.blogTagMap = blogTagMap;
}
}
复制

⏹然后在前台查看效果,可以看到外侧的blogTagMap属性名不见了。

在这里插入图片描述

转载请注明出处或者链接地址:https://www.qianduange.cn//article/15076.html
标签
jackson
评论
发布的文章

安装Nodejs后,npm无法使用

2024-11-30 11:11:38

大家推荐的文章
会员中心 联系我 留言建议 回顶部
复制成功!