美文网首页
Jackson使用POJO简单对象生成JSON

Jackson使用POJO简单对象生成JSON

作者: 木木与呆呆 | 来源:发表于2021-11-19 11:21 被阅读0次

1.说明

在开发中,经常需要测试Restful接口,
需要生成POJO简单对象的JSON字符串,
如果对象类的字段比较多,
手工生成的时候会很麻烦,
下面提供一个基于Jackson的工具类,
能够根据POJO简单对象类,
初始化对象类中字段的默认值,
然后生成JSON字符串。

2.POJO简单对象

简单对象类UserEntity.java如下,
省略了get/set/toString等方法:

package com.yuwen.spring.demo.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import java.io.Serializable;
import java.time.LocalDate;
import java.time.LocalDateTime;
/**
 * 用户实体类
 */
public class UserEntity implements Serializable {
    private static final long serialVersionUID = 1L;

    /**
     * 用户ID
     */
    private Long id;
    /**
     * 姓名
     */
    private String name;
    /**
     * 邮箱
     */
    private String email;
    /**
     * 生日
     */
    private LocalDate birthday;
    /**
     * 创建时间
     */
    private LocalDateTime createTime;
    /**
     * 修改时间
     */
    private LocalDateTime updateTime;
}

3.Jackson工具类

工具类JacksonJsonGenerator.java如下,
每次使用的时候只需要修改targetClass:

package com.yuwen.spring.jackson.generator;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import org.apache.commons.lang3.StringUtils;
import org.springframework.util.ReflectionUtils;
import org.springframework.util.ReflectionUtils.FieldCallback;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateSerializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalTimeSerializer;
import com.yuwen.spring.demo.entity.UserEntity;

/**
 * 使用Jackson,指定Java的POJO简单对象类,生成对应的JSON字符串
 */
public class JacksonJsonGenerator {
    // 指定需要生成JSON的Java类
    public static Class<?> targetClass = UserEntity.class;

    public static void main(String[] args) throws Exception {
        Object object = initObjectDefaultValue(targetClass);

        genetateJson(object);
    }

    /**
     * 初始化对象字段的默认值
     */
    private static Object initObjectDefaultValue(Class<?> targetClass)
            throws InstantiationException, IllegalAccessException {
        Object object = targetClass.newInstance();

        // 根据属性类型给属性设默认值
        FieldCallback fc = new FieldCallback() {
            @Override
            public void doWith(Field field) throws IllegalArgumentException, IllegalAccessException {
                Class<?> fieldType = field.getType();

                // final修饰的字段无法设置新的值
                if (Modifier.isFinal(field.getModifiers())) {
                    return;
                }

                String type = fieldType.getSimpleName();
                Object fieldValue = StringUtils.EMPTY;
                switch (type) {
                case "String":
                    fieldValue = StringUtils.EMPTY;
                    break;
                case "int":
                case "Integer":
                    fieldValue = 0;
                    break;
                case "long":
                case "Long":
                    fieldValue = 0L;
                    break;
                case "LocalDate":
                    fieldValue = LocalDate.now();
                    break;
                case "LocalDateTime":
                    fieldValue = LocalDateTime.now();
                    break;
                default:
                    fieldValue = StringUtils.EMPTY;
                    break;
                }
                try {
                    field.setAccessible(true);
                    field.set(object, fieldValue);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        };
        ReflectionUtils.doWithFields(targetClass, fc);
        return object;
    }

    /**
     * 生成对象的JSON字符串
     */
    private static void genetateJson(Object object) throws JsonProcessingException {
        System.out.println("POJO对象:");
        System.out.println(object);

        ObjectMapper mapper = new ObjectMapper();
        // 用于序列化Java8新的时间类型
        JavaTimeModule javaTimeModule = new JavaTimeModule();
        javaTimeModule.addSerializer(LocalDateTime.class,
                new LocalDateTimeSerializer(DateTimeFormatter.ISO_LOCAL_DATE_TIME));
        javaTimeModule.addSerializer(LocalDate.class, new LocalDateSerializer(DateTimeFormatter.ISO_LOCAL_DATE));
        javaTimeModule.addSerializer(LocalTime.class, new LocalTimeSerializer(DateTimeFormatter.ISO_LOCAL_DATE));
        mapper.registerModule(javaTimeModule);
        String json = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(object);

        System.out.println("JSON字符串:");
        System.out.println(json);
    }
}

4.生成JSON字符串

运行main方法输出结果:

POJO对象:
UserEntity{id=0, name=, email=, birthday=2021-11-19, 
createTime=2021-11-19T15:10:32.874, updateTime=2021-11-19T15:10:32.874}
JSON字符串:
{
  "id" : 0,
  "name" : "",
  "email" : "",
  "birthday" : "2021-11-19",
  "createTime" : "2021-11-19T15:10:32.874",
  "updateTime" : "2021-11-19T15:10:32.874"
}

5.更多的数据类型

在initObjectDefaultValue方法中,
修改swith-case增加更多的case,
可以支持更多的数据类型,
也可以修改类型对应的默认值。

6.问题解决

Jackson无法序列化Java8新的时间类型,
异常如下:

Exception in thread "main" com.fasterxml.jackson.databind.exc.InvalidDefinitionException: 
Java 8 date/time type `java.time.LocalDate` not supported by default: 
add Module "com.fasterxml.jackson.datatype:jackson-datatype-jsr310" to enable handling
 (through reference chain: com.yuwen.spring.demo.entity.UserEntity["birthday"])

因为birthday字段为LocalDate类型,
按照提示在pom.xml新增
如下依赖:

<dependency>
  <groupId>com.fasterxml.jackson.datatype</groupId>
  <artifactId>jackson-datatype-jsr310</artifactId>
  <version>2.12.5</version>
</dependency>

然后在ObjectMapper注册JavaTimeModule即可:

ObjectMapper mapper = new ObjectMapper();
mapper.registerModule(new JavaTimeModule());

7.其他方案

使用Jsr310NullKeySerializer,
也可以设置字段值为NULL时的序列化动作,
但是只能设置为""空字符串,
同时由于无法获取值为NULL的字段的类型,
无法为数据类型设置对应的默认值。
Jsr310NullKeySerializer.java代码如下:

package com.fasterxml.jackson.datatype.jsr310.ser.key;
import java.io.IOException;
import java.util.Map;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;

/**
 * This class is to be used in case {@code null} keys are needed to be serialized in a {@link Map} with Java 8 temporal keys. By default the
 * {@code null} key is not supported by jackson, the serializer needs to be registered manually.
 *
 * @author Zoltan Kiss
 * @since 2.6
 */
@Deprecated // since 2.10 -- not sure why module should provide general purpose null serializer
//   (maybe add in databind)
public class Jsr310NullKeySerializer extends JsonSerializer<Object> {

    public static final String NULL_KEY = "";
    @Override
    public void serialize(Object value, JsonGenerator gen, SerializerProvider serializers) throws IOException
    {
        if (value != null) {
            throw JsonMappingException.from(gen,
                    "Jsr310NullKeySerializer is only for serializing null values.");
        }
        gen.writeFieldName(NULL_KEY);
    }
}

相关文章

  • Jackson使用POJO简单对象生成JSON

    1.说明 在开发中,经常需要测试Restful接口,需要生成POJO简单对象的JSON字符串,如果对象类的字段比较...

  • Jackson的注解

    Jackson JSON工具包包含一组Java注释,您可以使用它们来影响如何将JSON读入对象,或者从对象生成JS...

  • json转换工具jackson使用

    Jackson是一个简单基于Java应用库,Jackson可以轻松的将Java对象转换成json对象和xml文档,...

  • 2018-09-18

    json和对象互转 json和pojo之间的转换

  • Jackson解析数据,部分数据缺失问题

    IDEA0使用GsonFormat解析postman调试的json数据为对象,然后使用Jackson解析数据时,发...

  • Jackson忽略字段

    1.概述 本文将展示如何使用Jackson 2.x将对象序列化为JSON时忽略某些字段。 将对象转换为json时,...

  • Jackson忽略未知的JSON属性

    在本文中,我们将学习如何使用Jackson ,将JSON解析为Java 对象时忽略未知的JSON属性。 要了解更多...

  • jackson

    jackson 将String的json文件转换为对象 实体类 jackson String类型转换为对象类型,需...

  • 2018-02-05 springmvc debug日志

    在测试直接给后台传入实体类对象时发生空指针错误 原因 jackson按getter,setter生成对应json字...

  • @JsonFormat、@JSONField、@DateTime

    1、JsonFormat来源于Jackson,Jackson可以轻松的将Java对象转换成Json对象和Xml文档...

网友评论

      本文标题:Jackson使用POJO简单对象生成JSON

      本文链接:https://www.haomeiwen.com/subject/fjbstrtx.html