SpringBoot系列——Jackson序列化
前⾔
Spring Boot提供了与三个JSON映射库的集成:
Gson
Jackson
JSON-B
Jackson是⾸选的默认库。
官⽹介绍:
通常,我们将Java对象转成Json时称之为序列化,反之将Json转成Java对象时称之为反序列化,本⽂简单介绍⼀下Jackson,以及在SpringBoot项⽬开发中常⽤的Jackson ⽅法
如何引⼊
SpringBoot提供了JSON依赖,我们可以按下⾯⽅式引⼊
1、直接引⼊JSON依赖
<!-- springboot-json -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-json</artifactId>
</dependency>
2、⼀般情况下我们引⼊MVC,MVC⾥⾯帮我们引⼊了JSON依赖
<!-- springboot web(MVC)-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
最终引⼊的依赖是
Jackson注解
Jackson的注解详细介绍
英⽂官⽅介绍:
常⽤注解
@JsonProperty 序列化、反序列化时,属性的名称
@JsonIgnoreProperties 序列化、反序列化忽略属性,多个时⽤“,”隔开
@JsonIgnore 序列化、反序列化忽略属性
@JsonAlias 为反序列化期间要接受的属性定义⼀个或多个替代名称,可以与@JsonProperty⼀起使⽤
@JsonInclude 当属性的值为空(null或者"")时,不进⾏序列化,可以减少数据传输
@JsonFormat 序列化、反序列化时,格式化时间
测试
写⼀个controller测试⼀下
先写⼀个页⾯跳转
/**
* 跳转页⾯,页⾯引⼊了jquery,主要⽤于下⾯的ajax调⽤测试
*/
@GetMapping("/")
public ModelAndView index(){
return new ModelAndView("index");
}
反序列化⽅式
完整测试Vo:
@Data
//序列化、反序列化忽略的属性,多个时⽤“,”隔开
@JsonIgnoreProperties({"captcha"})
//当属性的值为空(null或者"")时,不进⾏序列化,可以减少数据传输
@JsonInclude(JsonInclude.Include.NON_EMPTY)
public class UserVoByJson {
// 序列化、反序列化时,属性的名称
@JsonProperty("userName")
private String username;
// 为反序列化期间要接受的属性定义⼀个或多个替代名称,可以与@JsonProperty⼀起使⽤
@JsonAlias({"pass_word", "passWord"})
@JsonProperty("pwd")
private String password;
//序列化、反序列化时,格式化时间
@JsonFormat(locale = "zh", timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
private Date createDate;
//序列化、反序列化忽略属性
@JsonIgnore
private String captcha;
}
使⽤@RestController标注类,相对于所有的⽅法都⽤@ResponseBody标注,MVC会帮我们调⽤序
列化,将Java对象转成Json再响应给调⽤⽅,同时形参要加@RequestBody标注,MVC会帮我们调⽤反序列化将Json转成Java对象,这就要求我们调⽤的时候需要传⼀个Json字符串过来
/*
$.ajax({
type:"POST",
url:"localhost:10099/testByJson",
data:JSON.stringify({
userName:"sa",
pass_word:"123fff",
captcha:"abcd",
createDate:"2019-08-05 11:34:31"
}),
dataType:"JSON",
contentType:"application/json;charset=UTF-8",
success:function(data){
console.log(data);
},
error:function(data){
console.log("报错啦");
}
})
*/
/**
* 反序列化⽅式注⼊,只能post请求
*/
@PostMapping("testByJson")
public UserVoByJson testByJson(@RequestBody UserVoByJson userVo) {
System.out.println(userVo);
return userVo;
}
调⽤测试
1、先注释所有注解,仅打开这个两个类上⾯的注解@JsonIgnoreProperties、@JsonInclude
@Data
//序列化、反序列化忽略的属性,多个时⽤“,”隔开
@JsonIgnoreProperties({"captcha"})
//当属性的值为空(null或者"")时,不进⾏序列化,可以减少数据传输
@JsonInclude(JsonInclude.Include.NON_EMPTY)
public class UserVoByJson {
// 序列化、反序列化时,属性的名称
// @JsonProperty("userName")
private String username;
// 为反序列化期间要接受的属性定义⼀个或多个替代名称,可以与@JsonProperty⼀起使⽤
// @JsonAlias({"pass_word", "passWord"})
// @JsonProperty("pwd")
private String password;
/
/序列化、反序列化时,格式化时间
// @JsonFormat(locale = "zh", timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
private Date createDate;
//序列化、反序列化忽略属性
// @JsonIgnore
private String captcha;
}
前端调⽤时全部按属性名称
data:JSON.stringify({
username:"sa",
password:"123fff",
captcha:"abcd"
})
反序列化(后端控制台打印)
UserVoByJson(username=sa, password=123fff, createDate=null, captcha=null)
序列化(ajax的回调)
{username: "sa", password: "123fff"}
captcha属性前端已经传值,但设置了@JsonIgnoreProperties注解反序列化时该属性被忽略,因此为空,⽽序列化的时候@JsonInclude配置的是JsonInclude.Include.NON_EMPTY,当属性的值为空(null或者"")时,不进⾏序列化,所以序列化的最终结果如上所⽰
2、先注释所有注解,放开@JsonProperty、@JsonAlias、@JsonIgnore
@Data
//序列化、反序列化忽略的属性,多个时⽤“,”隔开
//@JsonIgnoreProperties({"captcha"})
//当属性的值为空(null或者"")时,不进⾏序列化,可以减少数据传输
//@JsonInclude(JsonInclude.Include.NON_EMPTY)
public class UserVoByJson {
// 序列化、反序列化时,属性的名称
@JsonProperty("userName")
private String username;
// 为反序列化期间要接受的属性定义⼀个或多个替代名称,可以与@JsonProperty⼀起使⽤
@JsonAlias({"pass_word", "passWord"})
@JsonProperty("pwd")
private String password;
/
/序列化、反序列化时,格式化时间
// @JsonFormat(locale = "zh", timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
private Date createDate;
//序列化、反序列化忽略属性
@JsonIgnore
private String captcha;
}
前端调⽤还是按属性名称
data:JSON.stringify({
username:"sa",
password:"123fff",
captcha:"abcd"
})
反序列化(后端控制台打印)
UserVoByJson(username=null, password=null, createDate=null, captcha=null)
序列化(ajax的回调)
{createDate: null, userName: null, pwd: null}
captcha被@JsonIgnore标注,序列化、反序列忽略它,username、password被@JsonProperty标注,传参的时候只能⽤别名,password同时被@JsonAlias标注,可以⽤
代替名称
因此我们可以这样调⽤
data:JSON.stringify({
userName:"sa",
pass_word:"123fff",
//以下两种也⼀样
//passWord:"123fff",
//pwd:"123fff",
captcha:"abcd"
})
反序列化(后端控制台打印)
UserVoByJson(username=sa, password=123fff, createDate=null, captcha=null)
序列化(ajax的回调)
{userName: "sa", pwd: "123fff"}
3、先注释所有注解,放开@JsonFormat
@Data
//序列化、反序列化忽略的属性,多个时⽤“,”隔开
//@JsonIgnoreProperties({"captcha"})
//当属性的值为空(null或者"")时,不进⾏序列化,可以减少数据传输
//@JsonInclude(JsonInclude.Include.NON_EMPTY)
public class UserVoByJson {
// 序列化、反序列化时,属性的名称
// @JsonProperty("userName")
private String username;
// 为反序列化期间要接受的属性定义⼀个或多个替代名称,可以与@JsonProperty⼀起使⽤
// @JsonAlias({"pass_word", "passWord"})
/
/ @JsonProperty("pwd")
private String password;
//序列化、反序列化时,格式化时间
@JsonFormat(locale = "zh", timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
private Date createDate;
//序列化、反序列化忽略属性
// @JsonIgnore
private String captcha;
}
前端调⽤
data:JSON.stringify({
createDate:"2019-08-05 11:34:31"
})
反序列化(后端控制台打印)
UserVoByJson(username=null, password=null, createDate=Mon Aug 05 11:34:31 GMT+08:00 2019, captcha=null)
序列化(ajax的回调)
{username: null, password: null, createDate: "2019-08-05 11:34:31", captcha: null}
PS:没有配置之前这样调⽤会报错400
Resolved [org.verter.HttpMessageNotReadableException: JSON parse error: Cannot deserialize value of type `java.util.Date` from String "2019-08-05 11:34:31": not a valid representation (error: Failed to parse Date value
MVC⽅式注⼊
Vo类
@Data
public class UserVoByMvc {
private String username;
private String password;
private Date createDate;
private String captcha;
}
如果不是以反序列化的⽅式注⼊,⽽是MVC的⽅式注⼊⼜是怎么样呢?去掉@RequestBody就变成MVC注⼊
/*
$.ajax({
type:"POST",
url:"localhost:10099/testByMvc",
data:{
username:"sa",
password:"123fff",
captcha:"abcd"
},
dataType:"JSON",
//contentType:"application/json;charset=UTF-8",//使⽤这个,get请求能接到参数,post接不到
contentType:"application/x-www-form-urlencoded",//使⽤这个,get、post都能接收到参数
success:function(data){
console.log(data);
},
error:function(data){
console.log("报错啦");
json值的类型有哪些}
})
*/
/**
* MVC⽅式注⼊
*/
@RequestMapping("testByMvc")
public UserVoByMvc testByMvc(UserVoByMvc userVo) {
System.out.println(userVo);
return userVo;
}
MVC注⼊的时候,接参过程Jackson的注解就不再⽣效了,这时候我们传参就得按照MVC的规则来,Date类型⾸先就不能传字符串
前端调⽤
data:{
username:"sa",
password:"123fff",
captcha:"abcd"
}
后台打印
UserVoByMvc(username=sa, password=123fff, createDate=null, captcha=abcd)
ajax回调
{username: "sa", password: "123fff", createDate: null, captcha: "abcd"}
那MVC⽅式注⼊,Date⽇期类型该怎么⽀持传字符串呢?在配置⽂件新增MVC⽇期格式化就可以愉快的传输固定格式的⽇期字符串了
#MVC接参时,⽇期处理
spring.mvc.date-format=yyyy-MM-dd HH:mm:ss
(偷个懒,效果与预期⼀样,就贴图了。。。)
同时,不管是采⽤哪种注⼊⽅法,我们可以配置全局的⽇期处理,这样⼀来就可以愉快开发了
#全局⽇期格式化处理
#MVC接参时,⽇期处理
spring.mvc.date-format=yyyy-MM-dd HH:mm:ss
#Jackson序列化、反序列化时,⽇期处理
spring.jackson.date-format=yyyy-MM-dd HH:mm:ss
我们顺便来看⼀下在配置⽂件都有哪些Jackson配置,每个配置的具体功能见名思意,就不阐述了
接收集合对象
1、反序列化⽅式
/*
let datas = [];//对象集合
for(let i = 0; i < 5; i++){
let data = {"userName":i + ""};//对象
datas.push(data);
}
$.ajax({
type:"POST",
url:"localhost:10099/testListByJson",
data:JSON.stringify(datas),
dataType:"JSON",
contentType:"application/json;charset=UTF-8",
success:function(data){
console.log(data);
},
error:function(data){
console.log("报错啦");
}
})
*/
/
**
* 反序列化⽅式,接收集合对象,只能post请求
*/
@PostMapping("testListByJson")
public String testListByJson(@RequestBody List<UserVoByJson> userVos){
userVos.forEach(System.out::println);
return "{\"code\":200}";
}
后台打印
UserVoByJson(username=0, password=null, createDate=null, captcha=null)
UserVoByJson(username=1, password=null, createDate=null, captcha=null)
UserVoByJson(username=2, password=null, createDate=null, captcha=null)
UserVoByJson(username=3, password=null, createDate=null, captcha=null)
UserVoByJson(username=4, password=null, createDate=null, captcha=null)
ObjectMapper
以上都是配置注解,具体操作都是MVC帮我们做了,那我们如何使⽤Jackson进⾏Json操作呢?我们在官⽅⽂档可以看到Jackson为我们提供了
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论