资讯专栏INFORMATION COLUMN

Jackson 使用 defaultTyping 实现通用的序列化和反序列化

104828720 / 1186人阅读

摘要:使用实现通用的序列化和反序列化核心通过方法设置即使使用作为也可以实现相应类型的序列化和反序列化好处只定义一个序列化器就可以了通用引入代码直接使用设置了的直接使用的反序列化,需要给定序列化的类使用设置了的来反序列化,可以使用达到想要的效果

Jackson 使用 defaultTyping 实现通用的序列化和反序列化 核心
private ObjectMapper createObjectMapping() {
    ObjectMapper objectMapper = new ObjectMapper();
    objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
    objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
    return objectMapper;
}

通过 objectMapper.enableDefaultTyping() 方法设置

即使使用 Object.class 作为 jcom.fasterxml.jackson.databind.JavaType 也可以实现相应类型的序列化和反序列化

好处:只定义一个序列化器就可以了(通用)

maven 引入

    com.fasterxml.jackson.core
    jackson-databind
    2.4.1.3


    junit
    junit
    4.12
    test
代码
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.type.TypeFactory;
import org.junit.Assert;
import org.junit.Test;

import java.io.IOException;
import java.io.Serializable;

/**
 * Created by sealde on 6/7/17.
 */
public class SerializerTest {
    private static final String userString =
            "{"id":null,"username":"admin","password":"admin"}";
    private static final String userStringWithDefaultType =
            "["com.seal_de.domain.UserInfo",{"id":null,"username":"admin","password":"admin"}]";

    /** 直接使用 ObjectMapping  **/
    @Test
    public void serialize() throws JsonProcessingException {
        CustomSerializer serializer = new CustomSerializer(Object.class);
        String s = serializer.serialize(createUser());
        Assert.assertEquals(s, userString);
    }

    /** 设置了 DefaultTyping 的 ObjectMapper **/
    @Test
    public void serializeWithDefaultType() throws JsonProcessingException {
        CustomSerializer serializer = new CustomSerializer(Object.class);
        serializer.setObjectMapper(createObjectMapping());
        String s = serializer.serialize(createUser());
        Assert.assertEquals(s, userStringWithDefaultType);
    }

    /** 直接使用 ObjectMapping 的反序列化,需要给定序列化的类 **/
    @Test
    public void deserialize() throws IOException {
        CustomSerializer serializer = new CustomSerializer(UserInfo.class);
        UserInfo userInfo = serializer.deserialize(userString);
        System.out.println(userInfo);
        Assert.assertEquals(userInfo, createUser());
    }

    /** 使用设置了 DefaultTyping 的 ObjectMapping 来反序列化,可以使用 Object 达到想要的效果 **/
    @Test
    public void deserializeWithDefaultTyping() throws IOException {
        CustomSerializer serializer = new CustomSerializer(Object.class);
        serializer.setObjectMapper(createObjectMapping());
        UserInfo userInfo = (UserInfo) serializer.deserialize(userStringWithDefaultType);
        System.out.println(userInfo);
        Assert.assertEquals(userInfo, createUser());
    }

    private ObjectMapper createObjectMapping() {
        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
        return objectMapper;
    }

    private UserInfo createUser() {
        UserInfo userInfo = new UserInfo();
        userInfo.setUsername("admin");
        userInfo.setPassword("admin");
        return userInfo;
    }

    private class CustomSerializer {
        private final JavaType javaType;
        private ObjectMapper objectMapper = new ObjectMapper();

        public CustomSerializer(JavaType javaType) {
            this.javaType = javaType;
        }

        public CustomSerializer(Class clazz) {
            this.javaType = TypeFactory.defaultInstance().constructType(clazz);
        }

        public void setObjectMapper(ObjectMapper objectMapper) {
            this.objectMapper = objectMapper;
        }

        public String serialize(Object o) throws JsonProcessingException {
            return this.objectMapper.writeValueAsString(o);
        }

        public T deserialize(String s) throws IOException {
            return this.objectMapper.readValue(s, this.javaType);
        }
    }

    private class UserInfo implements Serializable {

        private static final long serialVersionUID = 1L;

        private String id;
        private String username;
        private String password;

        public String getId() {
            return id;
        }

        public void setId(String id) {
            this.id = id;
        }

        public String getUsername() {
            return username;
        }

        public void setUsername(String username) {
            this.username = username;
        }

        public String getPassword() {
            return password;
        }

        public void setPassword(String password) {
            this.password = password;
        }

        @Override
        public boolean equals(Object o) {
            if (this == o) return true;
            if (o == null || getClass() != o.getClass()) return false;

            UserInfo userInfo = (UserInfo) o;

            if (id != null ? !id.equals(userInfo.id) : userInfo.id != null) return false;
            if (username != null ? !username.equals(userInfo.username) : userInfo.username != null) return false;
            if (password != null ? !password.equals(userInfo.password) : userInfo.password != null) return false;

            return true;
        }

        @Override
        public int hashCode() {
            int result = id != null ? id.hashCode() : 0;
            result = 31 * result + (username != null ? username.hashCode() : 0);
            result = 31 * result + (password != null ? password.hashCode() : 0);
            return result;
        }

        @Override
        public String toString() {
            return "UserInfo{" +
                    "id="" + id + """ +
                    ", username="" + username + """ +
                    ", password="" + password + """ +
                    "}";
        }
    }
}

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/67191.html

相关文章

  • 简单基于springredis配置(单机和集群模式)

    摘要:优点是反序列化时不需要提供类型信息,但缺点是序列化后的结果非常庞大,是格式的倍左右,这样就会消耗服务器的大量内存。使用库将对象序列化为字符串。优点是速度快,序列化后的字符串短小精悍。 需要的jar包:spring版本:4.3.6.RELEASE,jedis版本:2.9.0,spring-data-redis:1.8.0.RELEASE;如果使用jackson序列化的话还额外需要:jac...

    Tychio 评论0 收藏0
  • Spring Boot 参考指南(开发Web应用程序)

    摘要:开发应用程序非常适合应用程序开发,通过使用嵌入式或,你可以创建一个自包含的服务器。如果你还没有开发过一个应用程序,你可以按照入门部分中的示例进行操作。自动配置为大多数应用程序提供了良好的自动配置。 27. 开发Web应用程序 Spring Boot非常适合web应用程序开发,通过使用嵌入式Tomcat、Jetty、Undertow或Netty,你可以创建一个自包含的HTTP服务器。大多...

    roadtogeek 评论0 收藏0
  • 集成 Spring data redis 笔记

    摘要:本文有部分代码是抄袭的。第二个坑需要指定对象的数据类型,不然反序列化报错。第三的编辑器非常不好用。上面的配置有个缺陷,就是只能指定数据类型去缓存到。其实还可以配置一个但我持久层是。查询分页结果时,会无法反序列化。搜了半天没解决方案。 本文有部分代码是抄袭的。 1 :引入依赖 org.springframework.data spring-data-redis ${spr...

    张迁 评论0 收藏0
  • 关于springboot集成redis及关于redisKey 乱码问题

    摘要:一在文件中引入二配置地址等配置数据库索引默认为服务器地址服务器连接端口服务器连接密码默认为空连接池最大连接数使用负值表示没有限制连接池最大阻塞等待时间使用负值表示没有限制连接池中的最大空闲连接连接池中的最小空闲连接连接超时时 一、在pom文件中引入redis org.springframework.boot spring-boot-starter-redis ...

    RancherLabs 评论0 收藏0

发表评论

0条评论

104828720

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<