java jackson 序列化_Java序列化与反序列化(原生方式与Jackson方式)

本文介绍了Java的两种主要序列化方式:原生序列化和Jackson JSON序列化。通过示例代码详细展示了如何使用Java原生序列化方法以及Jackson库进行对象的序列化和反序列化操作,包括日期处理、对象转换等。
摘要由CSDN通过智能技术生成

Java序列化与反序列化

交流或更多内容请关注我的公众号:nezha_blog

当两个进程在进行远程通信时,彼此可以发送各种类型的数据。无论是何种类型的数据,都会以二进制序列的形式在网络上传送。发送方需要把这个Java对象转换为字节序列,才能在网络上传送;接收方则需要把字节序列再恢复为Java对象。

现在主要的序列化方式主要是两个种。一种是Java原生以流的方法进行的序列化,另外一种就是Json序列化方式。我这里Json的序列化方式主要是以Jackson为例。

1. Java原生序列化

这种方式只能将支持 java.io.Serializable 接口的对象写入流中。每个 serializable 对象的类都被编码,编码内容包括类名和类签名、对象的字段值和数组值,以及从初始对象中引用的其他所有对象的闭包。

概念

序列化:把Java对象转换为字节序列的过程。

反序列化:把字节序列恢复为Java对象的过程。

用途

把对象的字节序列永久地保存到硬盘上,通常存放在一个文件中;

在网络上传送对象的字节序列。

对象序列化

java.io.ObjectOutputStream代表对象输出流,它的writeObject(Object obj)方法可对参数指定的obj对象进行序列化,把得到的字节序列写到一个目标输出流中。只有实现了Serializable和Externalizable接口的类的对象才能被序列化。

java.io.ObjectInputStream代表对象输入流,它的readObject()方法从一个源输入流中读取字节序列,再把它们反序列化为一个对象,并将其返回。

示例代码

import java.io.*;

import java.util.Date;

public class ObjectSaver{

public static void main(String[] args) throws Exception{

/*其中的 ./objectFile.obj 表示存放序列化对象的文件*/

//序列化对象

ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("./objectFile.obj"));

Customer customer = new Customer("王麻子", 24);

out.writeObject("你好!"); //写入字面值常量

out.writeObject(new Date()); //写入匿名Date对象

out.writeObject(customer); //写入customer对象

out.close();

//反序列化对象

ObjectInputStream in = new ObjectInputStream(new FileInputStream("./objectFile.obj"));

System.out.println("obj1 " + (String) in.readObject()); //读取字面值常量

System.out.println("obj2 " + (Date) in.readObject()); //读取匿名Date对象

Customer obj3 = (Customer) in.readObject(); //读取customer对象

System.out.println("obj3 " + obj3);

in.close();

}

}

class Customer implements Serializable{

private String name;

private int age;

public Customer(String name, int age){

this.name = name;

this.age = age;

}

public String toString(){

return "name=" + name + ", age=" + age;

}

}

复制代码

2. 使用Jackson序列化对象

准备工作:

ObjectMapper mapper = new ObjectMapper(); //转换器

mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);

复制代码

将对象序列化

主要使用的是writeValueAsString的函数

String json=mapper.writeValueAsString(user); //将对象转换成json

复制代码

将Json字符串对象化(反序列化)

主要使用的是readValue的函数

Map m = mapper.readValue(json, Map.class);

复制代码

编程实现

User类

public class User{

private String id; //标识

private String name;//姓名

private int age;//年龄

private double pay;//工资

private boolean valid;//是否有效

private char one; //一个字符

@JsonFormat(pattern = "yyyy-mm-dd")

private Date birthday;//生日

private Link link; //联系方式,自定义

private Map map; //测试用

private List list; //测试用

private Set set; //测试用

public String getId(){

return id;

}

public void setId(String id){

this.id = id;

}

public String getName(){

return name;

}

public void setName(String name){

this.name = name;

}

public int getAge(){

return age;

}

public void setAge(int age){

this.age = age;

}

public double getPay(){

return pay;

}

public void setPay(double pay){

this.pay = pay;

}

public boolean isValid(){

return valid;

}

public void setValid(boolean valid){

this.valid = valid;

}

public char getOne(){

return one;

}

public void setOne(char one){

this.one = one;

}

public Date getBirthday(){

return birthday;

}

public void setBirthday(Date birthday){

this.birthday = birthday;

}

public Link getLink(){

return link;

}

public void setLink(Link link){

this.link = link;

}

public Map getMap(){

return map;

}

public void setMap(Map map){

this.map = map;

}

public List getList(){

return list;

}

public void setList(List list){

this.list = list;

}

public Set getSet(){

return set;

}

public void setSet(Set set){

this.set = set;

}

}

复制代码Link类

public class Link{

private String phone; //移动电话

private String address; //地址

private String qq; //QQ

public String getPhone(){

return phone;

}

public void setPhone(String phone){

this.phone = phone;

}

public String getAddress(){

return address;

}

public void setAddress(String address){

this.address = address;

}

public String getQq(){

return qq;

}

public void setQq(String qq){

this.qq = qq;

}

}

复制代码主函数

public class JacksonTest{

public static void main(String[] args) throws JsonGenerationException,JsonMappingException,IOException{

User user=new User();

user.setId("01");

user.setName("张三");

user.setAge(33);

user.setPay(6666.88);

user.setValid(true);

user.setOne('E');

user.setBirthday(new Date(20l*366*24*3600*1000)); //1990年

Link link = new Link();

link.setAddress("河南省济源市");

link.setPhone("13899995555");

link.setQq("123456");

user.setLink(link);

Map map=new HashMap();

map.put("aa", "this is aa");

map.put("bb", "this is bb");

map.put("cc", "this is cc");

user.setMap(map);

List list=new ArrayList(){};

list.add("普洱");

list.add("大红袍");

user.setList(list);

Set set=new HashSet();

set.add("篮球");

set.add("足球");

set.add("乒乓球");

user.setSet(set);

ObjectMapper mapper = new ObjectMapper(); //转换器

//测试01:对象--json

String json=mapper.writeValueAsString(user); //将对象转换成json

System.out.println(json);

/* 结果如下:

{"id":"01","name":"张三","age":33,"pay":6666.88,"valid":true,"one":"E","birthday":1465185448998,

"link":{"phone":"13899995555","address":"河南省济源市","qq":"123456"},

"map":{"aa":"this is aa","bb":"this is bb","cc":"this is cc"},

"list":["普洱","大红袍"],

"set":["乒乓球","足球","篮球"]}

注意点:(1) 日期--长整型 (2)List、Set均转成数组

*/

//测试02:json--map

Map m = mapper.readValue(json, Map.class); //json转换成map

System.out.println("pay:"+m.get("pay").getClass().getName()); //java.lang.Double

System.out.println("valid:"+m.get("valid").getClass().getName()); //java.lang.Boolean

System.out.println("birthday:"+m.get("birthday").getClass().getName()); //java.lang.Long

System.out.println("link:"+m.get("link").getClass().getName()); //java.util.LinkedHashMap

System.out.println("map:"+m.get("map").getClass().getName()); //java.util.LinkedHashMap

System.out.println("list:"+m.get("list").getClass().getName()); //java.util.ArrayList

System.out.println("set:"+m.get("set").getClass().getName()); //java.util.ArrayList

/* 结果如下:

pay:java.lang.Double

valid:java.lang.Boolean

birthday:java.lang.Long

link:java.util.LinkedHashMap

map:java.util.LinkedHashMap

list:java.util.ArrayList

set:java.util.ArrayList

注意点:(1) 日期--长整型 (2)map、子对象均转换成了LinkedHashMap (3)List、Set均转成ArrayList

*/

mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES,false);

//测试03:map--json

json=mapper.writeValueAsString(m); //map转json

System.out.println(json); //与之前格式完全相同,说明经过map转换后,信息没有丢失

//测试04:json--对象

User u=mapper.readValue(json, User.class); //json转java对象。经测,转成对象后,一切恢复正常

System.out.println("pay:"+u.getPay());

System.out.println("valid:"+u.isValid());

System.out.println("birthday:"+u.getBirthday());

System.out.println("link:"+u.getLink().getAddress());

System.out.println("map:"+u.getMap());

System.out.println("list:"+u.getList());

System.out.println("set:"+u.getSet());

//测试05:其他转换

byte[] data=mapper.writeValueAsBytes(u); //对象转成二进制数组

}

}

复制代码

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值