Java基础——序列化

Java基础——序列化

  • 序列化:把Java对象转换为字节序列。
  • 反序列化:把字节序列恢复为原先的Java对象。

序列化方式

Serializable 接口

一个对象想要被序列化,那么它的类就要实现此接口或者它的子接口。

Externalizable 接口

它是Serializable接口的子类,用户要实现的writeExternal()和readExternal() 方法,用来决定如何序列化和反序列化。

因为序列化和反序列化方法需要自己实现,因此可以指定序列化哪些属性,而transient在这里无效。

对Externalizable对象反序列化时,会先调用类的无参构造方法,这是有别于默认反序列方式的。如果把类的不带参数的构造方法删除,或者把该构造方法的访问权限设置为private、默认或protected级别,会抛出java.io.InvalidException: no valid constructor异常,因此Externalizable对象必须有默认构造函数,而且必需是public的。

不被序列化的情况

  • 凡是被static修饰的字段是不会被序列化的
  • 凡是被transient修饰符修饰的字段也是不会被序列化的

序列化框架的使用——FastJson

MVC 配置文件 基于Springboot

package com.pengshi.realhole.config;

import com.alibaba.fastjson.serializer.SerializerFeature;
import com.alibaba.fastjson.support.config.FastJsonConfig;
import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

import java.util.ArrayList;
import java.util.List;


/**
 * @description: 开放 静态资源的权限 , 同时配置fastjson
 * @projectName: RealHole
 * @see: com.pengshi.realhole.config.WebMvcConfig
 * @author: pc
 * @createTime: 2022/2/11 17:51
 * @version: 1.0
 */

@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("swagger-ui.html","doc.html")
                .addResourceLocations("classpath:/META-INF/resources/");

        registry.addResourceHandler("/webjars/**")
                .addResourceLocations("classpath:/META-INF/resources/webjars/");
    }

    /**
     * 修改自定义消息转化器 配置FastJSON
     * @param converters 消息转换器列表
     */
    @Override
    public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {

        /*
         先把JackSon的消息转换器删除.
         备注: (1)源码分析可知,返回json的过程为:
                    Controller调用结束后返回一个数据对象,for循环遍历conventers,找到支持application/json的HttpMessageConverter,然后将返回的数据序列化成json。
                    具体参考org.springframework.web.servlet.mvc.method.annotation.AbstractMessageConverterMethodProcessor的writeWithMessageConverters方法
               (2)由于是list结构,我们添加的fastjson在最后。因此必须要将jackson的转换器删除,不然会先匹配上jackson,导致没使用fastjson
        */
        for (int i = converters.size() - 1; i >= 0; i--) {
            if (converters.get(i) instanceof MappingJackson2HttpMessageConverter) {
                converters.remove(i);
            }
        }
        //调用父类的配置

        //创建fastJson消息转换器
        FastJsonHttpMessageConverter fastJsonConverter = new FastJsonHttpMessageConverter();

        //创建配置类
        FastJsonConfig fastJsonConfig = new FastJsonConfig();

        //过滤并修改配置返回内容
        fastJsonConfig.setSerializerFeatures(

                //List字段如果为null,输出为[],而非null
                //SerializerFeature.WriteNullListAsEmpty,

                //字符类型字段如果为null,输出为"",而非null
                SerializerFeature.WriteNullStringAsEmpty,

                //Boolean字段如果为null,输出为falseJ,而非null
                //SerializerFeature.WriteNullBooleanAsFalse,

                //消除对同一对象循环引用的问题,默认为false(如果不配置有可能会进入死循环)
                SerializerFeature.DisableCircularReferenceDetect,

                //是否输出值为null的字段,默认为false
                SerializerFeature.WriteMapNullValue

        );

        //处理中文乱码问题
        List<MediaType> fastMediaTypes = new ArrayList<MediaType>();
        fastMediaTypes.add(MediaType.APPLICATION_JSON_UTF8);
        fastJsonConverter.setSupportedMediaTypes(fastMediaTypes);
        fastJsonConverter.setFastJsonConfig(fastJsonConfig);

        //将fastjson添加到视图消息转换器列表内
        converters.add(fastJsonConverter);
    }
}
FastJSON基本使用
package com.pengshi.realhole;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import com.alibaba.fastjson.annotation.JSONField;
import com.alibaba.fastjson.annotation.JSONType;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.pengshi.realhole.pojo.User;
import org.junit.jupiter.api.Test;

import java.util.*;

/**
 * @description:
 * @projectName: RealHole
 * @see: com.pengshi.realhole
 * @author: pc
 * @createTime: 2022/2/13 17:57
 * @version: 1.0
 */
public class FastJsonTest {

	// java中对象,序列化为json序列化字符串
	@Test
	public void testObjectJson() {
		User user = new User();
		user.setId(1);
		user.setUsername("pengshi");
		user.setPassword("123456");
		String jsonString = JSON.toJSONString(user);
		System.out.println(jsonString);
	}


	// list集合转为字符串
	@Test
	public void testListToJson() {
		List<User> list = new ArrayList<>();
		User user = new User();
		user.setId(1);
		user.setUsername("pengshi");
		user.setPassword("123456");

		User user2 = new User();
		user2.setId(1);
		user2.setUsername("pengshi");
		user2.setPassword("123456");

		list.add(user);
		list.add(user2);
		String jsonString = JSON.toJSONString(list);
		System.out.println(jsonString);
	}


	// 将map集合进行json格式转化
	@Test
	public void testMapToJson() {
		Map<String, User> map = new HashMap();

		User user = new User();
		user.setId(1);
		user.setUsername("pengshi");
		user.setPassword("123456");

		User user2 = new User();
		user2.setId(1);
		user2.setUsername("pengshi");
		user2.setPassword("123456");

		map.put("pengshi", user);
		map.put("dongye", user2);
		String jsonString = JSON.toJSONString(map);
		System.out.println(jsonString);
	}


	// 反序列化操作
	@Test
	public void testJsonToObject() {
		String str = "{\"id\":1,\"username\":\"pengshi\"}";
		System.out.println(JSON.parseObject(str, User.class));
	}

	// 反序列化 为List
	@Test
	public void testJsonToList() {
		String str = "{\"id\":1,\"username\":\"pengshi\"}";
		List<User> list = JSON.parseArray(str, User.class);
	}

	// 反序列化 为Map
	public void testJsonToMap() {
		String str = "{\"pengshi\":{\"id\":1,\"username\":\"pengshi\"},\"dongye\":{\"id\":1,\"username\":\"pengshi\"}}";
		Map map = JSON.parseObject(str, new TypeReference<Map<String, User>>(){}); // 注意这里是一个匿名内部类进行重写
	}

	// SerializerFeature 枚举 : 进行序列化时,定义自己特殊需求
	// JSON静态方法: toJSONString()
	// 方法参数1 : 第一个需要序列化的对象
	// 方法参数2 : SerializerFeature 枚举类型的可变参数
	// SerializerFeature 枚举的常量,做序列化的个性需求
	@Test
	public void testWriteNullValue() {
		// WriteMapNullValue 值为空时候,进行null打印 "email":"null"
		// WriteNullStringAsEmpty 值为空时,打印空,只剩下空 "email":""
		// WriteNullNumberAsZero 值为空时,打印0,对于number类型而言
		User user = new User();
		user.setId(1);
		user.setUsername("pengshi");
		user.setPassword("123456");
		String str = JSON.toJSONString(user, SerializerFeature.WriteNullNumberAsZero);
		System.out.println(str);
	}

	// JSONType 注解
	// 作用在类上,堆该类的字段进行序列化和反序列化的特性功能定制
	// includes 被序列化的字段
	// orders 序列化顺序
	@JSONType(includes = {"username","date"})
	class student {
		// @JSONField 注解
		// name指定序列化名字
		// ordinal 序列化顺序,属性值越小,顺序越靠前
		// serialize 序列化开关
		// format 格式
		// deserialize 反序列化开关
		// defaultValue 默认值
		@JSONField (name = "studentName", ordinal = 1)
		private String username;
		@JSONField (serialize = false, deserialize = false)
		private String password;
		@JSONField (format = "yyyy-MM-dd")
		private Date date;
		private String email;
		private int age;
	}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

pengshi12138

加油加油

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值