springboot @JsonSerialize的使用讲解

 更新时间:2021年10月12日 14:42:24   作者:FS小山  
这篇文章主要介绍了springboot @JsonSerialize的使用,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教

@JsonSerialize的使用讲解

解决前端显示和后台存储数据单位不一致的问题。

在返回对象时,进行自定义数据格式转换。

1.写一个类继承JsonSerializer 抽象类

实现其serialize()方法,然后在方法中写入转换规则即可

举例是把Date时间戳从 毫秒 转换成 秒 为单位

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider; 
import java.io.IOException;
import java.util.Date;
 
/**
 * @program: sell
 * @description: 时间转换Json序列化工具
 * @author: Liang Shan
 * @create: 2019-08-06 16:58
 **/
public class Date2LongSerializer extends JsonSerializer<Date> {
    @Override
    public void serialize(Date date, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
        jsonGenerator.writeNumber(date.getTime() / 1000);
    }
}

2.然后在传输的实体类中的属性上

打上@JsonSerialize注解即可

import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.ls.sell.enums.OrderStatusEnum;
import com.ls.sell.enums.PayStatusEnum;
import com.ls.sell.util.serializer.Date2LongSerializer;
import lombok.Data;
import org.hibernate.annotations.DynamicUpdate; 
import javax.persistence.Entity;
import javax.persistence.Id;
import java.math.BigDecimal;
import java.util.Date;
 
/**
 * @program: sell
 * @description: 订单主表
 * @author: Liang Shan
 * @create: 2019-07-24 09:44
 **/
@Entity
@Data
@DynamicUpdate
public class OrderMaster { 
    @Id
    private String orderId; 
    private String buyerName; 
    private String buyerPhone; 
    private String buyerAddress; 
    private String buyerOpenid; 
    private BigDecimal orderAmount;
 
    /** 订单状态,默认为新下单. */
    private Integer orderStatus = OrderStatusEnum.NEW.getCode(); 
    /** 支付状态,默认为0未支付. */
    private Integer payStatus = PayStatusEnum.WAIT.getCode(); 
    @JsonSerialize(using = Date2LongSerializer.class)
    private Date createTime; 
    @JsonSerialize(using = Date2LongSerializer.class)
    private Date updateTime;
}

3.附加:还有一个比较好用的注解

如果返回对象中变量存在null,可以使用@JsonInclude(JsonInclude.Include.NON_NULL)注解来忽略为null的变量,这样前端比较好处理

package com.ls.sell.dto; 
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.ls.sell.entity.OrderDetail;
import com.ls.sell.entity.OrderMaster;
import lombok.Data; 
import java.util.List;
 
/**
 * @program: sell
 * @description: 数据传输对象,传给前端时忽略值为null的属性
 * @author: Liang Shan
 * @create: 2019-07-25 16:05
 **/
@Data
@JsonInclude(JsonInclude.Include.NON_NULL)
public class OrderDTO extends OrderMaster {
    private List<OrderDetail> orderDetailList;
}

使用注解之前的返回值:

使用注解之后:

还是比较好用的。

4.附加:之前附件3的注解,还是有个问题

如果一个一个实体类配置的话,未免太过麻烦,所以可以在配置文件中直接配置,yml配置文件如下:

@JsonSerialize 相关使用(jsonUtil)

基础注解使用

1、实现JsonSerializer接口

例:

public class MySerializerUtils extends JsonSerializer<Integer> {
    @Override
    public void serialize(Integer status, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException, JsonProcessingException {
        String statusStr = "";
         switch (status) {
             case 0:
                 statusStr = "新建状态";
                 break;
                 }
                 jsonGenerator.writeString(statusStr);
     }
 }

2、添加注解

注:@JsonSerialize注解,主要应用于数据转换,该注解作用在该属性的getter()方法上。

①用在属性上(自定义的例子)

@JsonSerialize(using = MySerializerUtils.class)
private int status;

②用在属性上(jackson自带的用法)

@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    @JsonDeserialize(using = LocalDateTimeDeserializer.class)
    @JsonSerialize(using = LocalDateTimeSerializer.class)
private LocalDateTime sendTime;

③用在空对象上可以转化

@JsonSerialize
public class XxxxxBody {
 // 该对象暂无字段,直接new了返回
}

框架层面的使用

jsonUtil工具类

实现json转换时所有的null转为“”

1、实现JsonSerializer类

public class CustomizeNullJsonSerializer {
    public static class NullStringJsonSerializer extends JsonSerializer<Object> {
        @Override
        public void serialize(Object value, JsonGenerator jsonGenerator,
                              SerializerProvider serializerProvider) throws IOException {
            jsonGenerator.writeString("");
        }
    }
}

2、实现BeanSerializerModifier类

public class CustomizeBeanSerializerModifier extends BeanSerializerModifier {
    @Override
    public List<BeanPropertyWriter> changeProperties(SerializationConfig config,
                                                     BeanDescription beanDesc,
                                                     List<BeanPropertyWriter> beanProperties) {
        for (int i = 0; i < beanProperties.size(); i++) {
            BeanPropertyWriter writer = beanProperties.get(i);
            if (isStringType(writer)) {
                writer.assignNullSerializer(new CustomizeNullJsonSerializer.NullStringJsonSerializer());
            }
        }
        return beanProperties;
    }
    /**
     * 是否是String
     */
    private boolean isStringType(BeanPropertyWriter writer) {
        Class<?> clazz = writer.getType().getRawClass();
        return CharSequence.class.isAssignableFrom(clazz) || Character.class.isAssignableFrom(clazz);
    }
}

3、工具类调用

public class JsonUtil {
//序列化时String 为null时变成""
    private static ObjectMapper mapperContainEmpty = new ObjectMapper();
static {
        mapperContainEmpty.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
        mapperContainEmpty.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
        mapperContainEmpty.setSerializerFactory(mapperContainEmpty.getSerializerFactory()
                .withSerializerModifier(new CustomizeBeanSerializerModifier()));
    }
 /**
     * 将对象转换为Json串,针对String 类型 null 转成""
     */
    public static String toJsonContainEmpty(Object o) {
        try {
            return mapperContainEmpty.writeValueAsString(o);
        } catch (IOException e) {
            logger.error("render object to json error: {}", e.getMessage(), e);
            throw new RuntimeException("render object to json error!", e);
        }
    }
}

附:jsonUtil完整代码

/**
 * json串和对象之间相互转换工具类
 */
public class JsonUtil {
    private static Logger logger = LoggerFactory.getLogger(JsonUtil.class);
    private static ObjectMapper mapper = new ObjectMapper();
    //序列化时String 为null时变成""
    private static ObjectMapper mapperContainEmpty = new ObjectMapper();
    static {
        mapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
        mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
        mapper.setSerializationInclusion(Include.NON_NULL);
        mapperContainEmpty.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
        mapperContainEmpty.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
        mapperContainEmpty.setSerializerFactory(mapperContainEmpty.getSerializerFactory()
                .withSerializerModifier(new CustomizeBeanSerializerModifier()));
    }
    /**
     * 将对象转换为Json串
     */
    public static String toJson(Object o) {
        try {
            return mapper.writeValueAsString(o);
        } catch (IOException e) {
            logger.error("render object to json error: {}", e.getMessage(), e);
            throw new RuntimeException("render object to json error!", e);
        }
    }
    /**
     * 将对象转换为Json串,针对String 类型 null 转成""
     */
    public static String toJsonContainEmpty(Object o) {
        try {
            return mapperContainEmpty.writeValueAsString(o);
        } catch (IOException e) {
            logger.error("render object to json error: {}", e.getMessage(), e);
            throw new RuntimeException("render object to json error!", e);
        }
    }
    /**
     * 将Json串转换为对象
     */
    public static <T> T toObject(String json, Class<T> clazz) {
        try {
            return mapper.readValue(json, clazz);
        } catch (IOException e) {
            logger.error("render json to object error: {}", e.getMessage(), e);
            throw new RuntimeException("render json to object error!", e);
        }
    }
    /**
     * 将Json串转换为List
     */
    public static <T> List<T> toList(String json, Class<T> clazz) {
        try {
            JavaType javaType = mapper.getTypeFactory().constructParametricType(List.class, clazz);
            return mapper.readValue(json, javaType);
        } catch (IOException e) {
            logger.error("render json to List<T> error: {}", e.getMessage(), e);
            throw new RuntimeException("render json to List<T> error!", e);
        }
    }
    /**
     * 将Json串转换为Map
     */
    public static <K, V> Map<K, V> toMap(String json, Class<K> clazzKey, Class<V> clazzValue) {
        try {
            JavaType javaType = mapper.getTypeFactory().constructParametricType(Map.class, clazzKey, clazzValue);
            return mapper.readValue(json, javaType);
        } catch (IOException e) {
            logger.error("render json to Map<K, V> error: {}", e.getMessage(), e);
            throw new RuntimeException("render json to Map<K, V> error!", e);
        }
    }
}

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • java获取版本号及字节码编译版本方法示例

    java获取版本号及字节码编译版本方法示例

    这篇文章主要给大家介绍了关于java获得版本号及字节码编译版本的相关资料,文中通过示例代码介绍的非常详细,对大家学习或使用java具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧。
    2017-10-10
  • 如何利用grep-console插件使Intellij idea显示多颜色调试日志

    如何利用grep-console插件使Intellij idea显示多颜色调试日志

    这篇文章主要介绍了利用grep-console插件使Intellij idea显示多颜色调试日志,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-05-05
  • 正确结束Java线程的方法

    正确结束Java线程的方法

    线程的启动很简单,但用户可能随时取消任务,怎么样让跑起来的线程正确地结束,这是今天要讨论的话题。下面小编来和大家一起学习一下吧
    2019-05-05
  • 一文搞懂JAVA 枚举(enum)

    一文搞懂JAVA 枚举(enum)

    这篇文章主要介绍了JAVA 枚举(enum)的相关资料,文中讲解非常细致,代码帮助大家更好的理解和学习,感兴趣的朋友可以了解下
    2020-07-07
  • Java线程基本使用之如何实现Runnable接口

    Java线程基本使用之如何实现Runnable接口

    这篇文章主要介绍了Java线程基本使用之如何实现Runnable接口问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-01-01
  • Spring中的retry重试组件详解

    Spring中的retry重试组件详解

    这篇文章主要介绍了Spring中的retry重试组件详解,Retry重试组件是一个处理重试逻辑的工具,可以在出现异常或失败情况下自动进行重试操作,从而提高程序的稳定性和可靠性,需要的朋友可以参考下
    2023-10-10
  • SpringBoot如何读取配置文件中的数据到map和list

    SpringBoot如何读取配置文件中的数据到map和list

    这篇文章主要介绍了SpringBoot如何读取配置文件中的数据到map和list,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-02-02
  • Java语言实现非递归实现树的前中后序遍历总结

    Java语言实现非递归实现树的前中后序遍历总结

    今天小编就为大家分享一篇关于Java语言实现非递归实现树的前中后序遍历总结,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧
    2019-01-01
  • Java 详解循环屏障CyclicBarrier如何实现多线程分段等待执行完成

    Java 详解循环屏障CyclicBarrier如何实现多线程分段等待执行完成

    CyclicBarrier是一个同步工具类,可以翻译成循环屏障,也叫障碍器或同步屏障。CyclicBarrier内部有一个计数器count,调用障碍器的await方法会使计数器count的值减一,当计数器count的值为0时,表明调用了await方法线程已经达到了设置的数量
    2021-11-11
  • java实现对服务器的自动巡检邮件通知

    java实现对服务器的自动巡检邮件通知

    这篇文章主要为大家详细介绍了java实现对服务器的自动巡检邮件通知,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-05-05

最新评论