百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 编程字典 > 正文

jackson实体类包含实体类和时间类型的字符串与类的相互转换

toyiye 2024-08-08 00:14 12 浏览 0 评论


MyObject类包含常见基础类型字段和子类SubObject,SubObject包含LocalDateTime、LocalDate字段,模拟从前端接收到json字符串,然后转为对象,再把对象转为字符串。

之前有粉丝问我类里面包含内部类如何反序列化,所以这个例子也为了给粉丝一个参考。

代码片段如下,需要整个代码的请到gitee下载,文章中的测试类路径:src/test/java/com/javalaoniu/tool/JacksonMapperTest.java

@Test
public void demoTest() {
    JacksonMapper instance = JacksonMapper.getInstance();
    JacksonMapper jacksonMapper = JacksonMapper.nonDefaultMapper();
    System.out.println(instance == jacksonMapper);

    String s = "{\n" +
        "  \"serviceUuid\": \"9430be4f4cb244d79a5c0bf5e77136dc\",  \n" +
        "  \"secretId\": \"dsvb942f67c43cb475\",  \n" +
        "  \"nonceStr\": \"90907e\",  \n" +
        "  \"sign\": \"6071BF709864F21AB1B218F3122358B4\",   \n" +
        "  \"pageIndex\": 1, \n" +
        "  \"pageSize\": 100, \n" +
        "  \"customParams\": {\n" +
        "     \"startTime\": \"2019-11-19 14:42:47\",\n" +
        "     \"endDate\": \"2019-11-20\",\n" +
        "     \"itemCodes\": \"90000700100754196914440306,90000600100754196914440309,90000800100754196914440306," +
        "90000700100754196914440342\"\n" +
        "  }\n" +
        "}";
    MyObject myObject = JacksonMapper.fromJsonString(s, MyObject.class);
    logger.info(myObject.toString());
    String json = instance.toJson(myObject);
    logger.info(json);
}


实体类

/**
* 静态内部类,jackson解析内部类时需要static修饰,否则需要把类单独放到java文件中
*
* @JsonFormat 来自定义时间格式
* @JsonIgnore可以忽略某个 Java 对象中的属性,它将不参与 JSON 的序列化与反序列化
* @JsonGetter可以在对 Java 对象进行 JSON 序列化时自定义属性名称
* @JsonSetter可以在对 JSON 进行反序列化时设置 JSON 中的 key 与 Java 属性的映射关系
*/
static class MyObject {

    private String serviceUuid;

    private String secretId;

    private String nonceStr;

    private String sign;

    private Integer pageIndex;

    private Integer pageSize;

    private SubObject customParams;

      。。。。。get/set等代码

}

/**
* 静态内部类,jackson解析内部类时需要static修饰,否则需要把类单独放到java文件中
*
* @JsonSerialize 指定序列化使用的类
* @JsonDeserialize 指定反序列化使用的类
*/
static class SubObject {
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    @JsonDeserialize(using = LocalDateTimeDeserializer.class)
    @JsonSerialize(using = LocalDateTimeSerializer.class)
    private LocalDateTime startTime;

    @JsonFormat(pattern = "yyyy-MM-dd")
    @JsonDeserialize(using = LocalDateDeserializer.class)
    @JsonSerialize(using = LocalDateSerializer.class)
    private LocalDate endDate;

    private String itemCodes;

    。。。。。get/set等代码

}

jackson工具类

package com.javalaoniu.tool.utils;

import com.fasterxml.jackson.annotation.JsonInclude.Include;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonParser.Feature;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.util.JSONPObject;
import com.fasterxml.jackson.module.jaxb.JaxbAnnotationModule;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.util.TimeZone;

/** 
 * 简单封装Jackson,实现JSON String<->Java Object的Mapper. 
 * 封装不同的输出风格, 使用不同的builder函数创建实例. 
 */  
public class JacksonMapper extends ObjectMapper {
  
    private static final long serialVersionUID = 1L;  
  
    private static Logger logger = LoggerFactory.getLogger(JacksonMapper.class);
  
    private static JacksonMapper mapper;
  
    private JacksonMapper() {
        this(Include.NON_EMPTY);  
    }

    private JacksonMapper(Include include) {
        // 设置输出时包含属性的风格  
        if (include != null) {  
            this.setSerializationInclusion(include);  
        }  
        // 允许单引号、允许不带引号的字段名称  
        this.enableSimple();  
        // 设置输入时忽略在JSON字符串中存在但Java对象实际没有的属性  
        this.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
        // 运行empty的属性
        this.disable(SerializationFeature.FAIL_ON_EMPTY_BEANS);
        // 空值处理为空串
        this.getSerializerProvider().setNullValueSerializer(new JsonSerializer<Object>(){
            @Override  
            public void serialize(Object value, JsonGenerator jgen,  
                    SerializerProvider provider) throws IOException,
                    JsonProcessingException {  
                jgen.writeString("");  
            }  
        });

        //this.registerModule(new SimpleModule().addSerializer(new MyBigDecimalDesirializer()));

        // 进行HTML解码。  
        /*this.registerModule(new SimpleModule().addSerializer(String.class, new JsonSerializer<String>(){  
            @Override  
            public void serialize(String value, JsonGenerator jgen,  
                    SerializerProvider provider) throws IOException,  
                    JsonProcessingException {  
                jgen.writeString(StringEscapeUtils.unescapeHtml4(value));  
            }  
        }));  */
        // 设置时区  
        this.setTimeZone(TimeZone.getDefault());//getTimeZone("GMT+8:00")  
    }

    /**
     * 设定是否使用Enum的toString函数来读写Enum,
     * 为False时使用Enum的name()函数来 读写Enum, 默认为False.
     * 注意本函数一定要在Mapper创建后, 所有的读写动作之前调用.
     */
    public JacksonMapper enableEnumUseToString() {
        this.enable(SerializationFeature.WRITE_ENUMS_USING_TO_STRING);
        this.enable(DeserializationFeature.READ_ENUMS_USING_TO_STRING);
        return this;
    }

    /**
     * 支持使用Jaxb的Annotation,使得POJO上的annotation不用与Jackson耦合。
     * 默认会先查找jaxb的annotation,如果找不到再找jackson的。
     */
    public JacksonMapper enableJaxbAnnotation() {
        JaxbAnnotationModule module = new JaxbAnnotationModule();
        this.registerModule(module);
        return this;
    }

    /**
     * 允许单引号
     * 允许不带引号的字段名称
     */
    public JacksonMapper enableSimple() {
        this.configure(Feature.ALLOW_SINGLE_QUOTES, true);
        this.configure(Feature.ALLOW_UNQUOTED_FIELD_NAMES, true);
        this.configure(SerializationFeature.WRITE_BIGDECIMAL_AS_PLAIN,true);
        return this;
    }

    /**
     * 取出Mapper做进一步的设置或使用其他序列化API.
     */
    public ObjectMapper getMapper() {
        return this;
    }

    /** 
     * Object可以是POJO,也可以是Collection或数组。 
     * 如果对象为Null, 返回"null". 
     * 如果集合为空集合, 返回"[]". 
     */  
    public String toJson(Object object) {  
        try {  
            return this.writeValueAsString(object);  
        } catch (IOException e) {  
            logger.warn("write to json string error:" + object, e);  
            return null;  
        }  
    }  
  
    /** 
     * 反序列化POJO或简单Collection如List<String>. 
     *  
     * 如果JSON字符串为Null或"null"字符串, 返回Null. 
     * 如果JSON字符串为"[]", 返回空集合. 
     *  
     * 如需反序列化复杂Collection如List<MyBean>, 请使用fromJson(String,JavaType) 
     * @see #fromJson(String, JavaType) 
     */  
    public <T> T fromJson(String jsonString, Class<T> clazz) {  
        if (jsonString==null || jsonString.isEmpty()) {  
            return null;  
        }  
        try {  
            return this.readValue(jsonString, clazz);  
        } catch (IOException e) {  
            logger.warn("parse json string error:" + jsonString, e);  
            return null;  
        }  
    }  
  
    /** 
     * 反序列化复杂Collection如List<Bean>, 先使用函数createCollectionType构造类型,然后调用本函数. 
     * @see #createCollectionType(Class, Class...) 
     */  
    @SuppressWarnings("unchecked")  
    public <T> T fromJson(String jsonString, JavaType javaType) {  
        if (jsonString==null || jsonString.isEmpty()) {  
            return null;  
        }  
        try {  
            return (T) this.readValue(jsonString, javaType);  
        } catch (IOException e) {  
            logger.warn("parse json string error:" + jsonString, e);  
            return null;  
        }  
    }  
  
    /** 
     * 构造泛型的Collection Type如: 
     * ArrayList<MyBean>, 则调用constructCollectionType(ArrayList.class,MyBean.class) 
     * HashMap<String,MyBean>, 则调用(HashMap.class,String.class, MyBean.class) 
     */  
    public JavaType createCollectionType(Class<?> collectionClass, Class<?>... elementClasses) {  
        return this.getTypeFactory().constructParametricType(collectionClass, elementClasses);  
    }  
  
    /** 
     * 当JSON里只含有Bean的部分属性时,更新一个已存在Bean,只覆盖该部分的属性. 
     */  
    @SuppressWarnings("unchecked")  
    public <T> T update(String jsonString, T object) {  
        try {  
            return (T) this.readerForUpdating(object).readValue(jsonString);  
        } catch (JsonProcessingException e) {  
            logger.warn("update json string:" + jsonString + " to object:" + object + " error.", e);  
        } catch (IOException e) {  
            logger.warn("update json string:" + jsonString + " to object:" + object + " error.", e);  
        }  
        return null;  
    }

    /** 
     * 输出JSONP格式数据. 
     */  
    public String toJsonP(String functionName, Object object) {  
        return toJson(new JSONPObject(functionName, object));  
    }

    /**
     * 创建只输出非Null且非Empty(如List.isEmpty)的属性到Json字符串的Mapper,建议在外部接口中使用.
     */
    public static JacksonMapper getInstance() {
        if (mapper == null){
            mapper = new JacksonMapper(Include.ALWAYS).enableSimple();
        }
        return mapper;
    }

    /**
     * 创建只输出初始值被改变的属性到Json字符串的Mapper, 最节约的存储方式,建议在内部接口中使用。
     */
    public static JacksonMapper nonDefaultMapper() {
        if (mapper == null){
            mapper = new JacksonMapper(Include.NON_DEFAULT);
        }
        return mapper;
    }


    /**
     * 封装这个方法便于直接类名调用
     * 对象转换为JSON字符串 
     * @param object 
     * @return 
     */  
    public static String toJsonString(Object object){
        return JacksonMapper.getInstance().toJson(object);
    }  
      
    /**
     * 封装这个方法便于直接类名调用
     * JSON字符串转换为对象 
     * @param jsonString 
     * @param clazz 
     * @return 
     */  
    public static <T> T fromJsonString(String jsonString, Class<T> clazz){
        return JacksonMapper.getInstance().fromJson(jsonString, clazz);
    }
}

maven依赖

<jackson.version>2.16.0</jackson.version>

<!--jackson-module-jaxb-annotations 依赖jackson-databind、jackson-core、jackson-annotations,
    所以可以只显示地添加jackson-module-jaxb-annotations依赖,
    jackson-databind、jackson-core、jackson-annotations 也随之添加到 Java 项目工程中-->
<dependency>
    <groupId>com.fasterxml.jackson.module</groupId>
    <artifactId>jackson-module-jaxb-annotations</artifactId>
    <version>${jackson.version}</version>
</dependency>
<dependency>
    <groupId>com.fasterxml.jackson.datatype</groupId>
    <artifactId>jackson-datatype-jsr310</artifactId>
    <version>${jackson.version}</version>
</dependency>



相关推荐

为何越来越多的编程语言使用JSON(为什么编程)

JSON是JavascriptObjectNotation的缩写,意思是Javascript对象表示法,是一种易于人类阅读和对编程友好的文本数据传递方法,是JavaScript语言规范定义的一个子...

何时在数据库中使用 JSON(数据库用json格式存储)

在本文中,您将了解何时应考虑将JSON数据类型添加到表中以及何时应避免使用它们。每天?分享?最新?软件?开发?,Devops,敏捷?,测试?以及?项目?管理?最新?,最热门?的?文章?,每天?花?...

MySQL 从零开始:05 数据类型(mysql数据类型有哪些,并举例)

前面的讲解中已经接触到了表的创建,表的创建是对字段的声明,比如:上述语句声明了字段的名称、类型、所占空间、默认值和是否可以为空等信息。其中的int、varchar、char和decimal都...

JSON对象花样进阶(json格式对象)

一、引言在现代Web开发中,JSON(JavaScriptObjectNotation)已经成为数据交换的标准格式。无论是从前端向后端发送数据,还是从后端接收数据,JSON都是不可或缺的一部分。...

深入理解 JSON 和 Form-data(json和formdata提交区别)

在讨论现代网络开发与API设计的语境下,理解客户端和服务器间如何有效且可靠地交换数据变得尤为关键。这里,特别值得关注的是两种主流数据格式:...

JSON 语法(json 语法 priority)

JSON语法是JavaScript语法的子集。JSON语法规则JSON语法是JavaScript对象表示法语法的子集。数据在名称/值对中数据由逗号分隔花括号保存对象方括号保存数组JS...

JSON语法详解(json的语法规则)

JSON语法规则JSON语法是JavaScript对象表示法语法的子集。数据在名称/值对中数据由逗号分隔大括号保存对象中括号保存数组注意:json的key是字符串,且必须是双引号,不能是单引号...

MySQL JSON数据类型操作(mysql的json)

概述mysql自5.7.8版本开始,就支持了json结构的数据存储和查询,这表明了mysql也在不断的学习和增加nosql数据库的有点。但mysql毕竟是关系型数据库,在处理json这种非结构化的数据...

JSON的数据模式(json数据格式示例)

像XML模式一样,JSON数据格式也有Schema,这是一个基于JSON格式的规范。JSON模式也以JSON格式编写。它用于验证JSON数据。JSON模式示例以下代码显示了基本的JSON模式。{"...

前端学习——JSON格式详解(后端json格式)

JSON(JavaScriptObjectNotation)是一种轻量级的数据交换格式。易于人阅读和编写。同时也易于机器解析和生成。它基于JavaScriptProgrammingLa...

什么是 JSON:详解 JSON 及其优势(什么叫json)

现在程序员还有谁不知道JSON吗?无论对于前端还是后端,JSON都是一种常见的数据格式。那么JSON到底是什么呢?JSON的定义...

PostgreSQL JSON 类型:处理结构化数据

PostgreSQL提供JSON类型,以存储结构化数据。JSON是一种开放的数据格式,可用于存储各种类型的值。什么是JSON类型?JSON类型表示JSON(JavaScriptO...

JavaScript:JSON、三种包装类(javascript 包)

JOSN:我们希望可以将一个对象在不同的语言中进行传递,以达到通信的目的,最佳方式就是将一个对象转换为字符串的形式JSON(JavaScriptObjectNotation)-JS的对象表示法...

Python数据分析 只要1分钟 教你玩转JSON 全程干货

Json简介:Json,全名JavaScriptObjectNotation,JSON(JavaScriptObjectNotation(记号、标记))是一种轻量级的数据交换格式。它基于J...

比较一下JSON与XML两种数据格式?(json和xml哪个好)

JSON(JavaScriptObjectNotation)和XML(eXtensibleMarkupLanguage)是在日常开发中比较常用的两种数据格式,它们主要的作用就是用来进行数据的传...

取消回复欢迎 发表评论:

请填写验证码