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);
        }
    }
}

以上為個人經驗,希望能給大傢一個參考,也希望大傢多多支持WalkonNet。

推薦閱讀: