springboot @JsonSerialize的使用講解
@JsonSerialize的使用講解
解決前端顯示和后臺存儲數(shù)據(jù)單位不一致的問題。
在返回對象時(shí),進(jìn)行自定義數(shù)據(jù)格式轉(zhuǎn)換。
1.寫一個(gè)類繼承JsonSerializer 抽象類
實(shí)現(xiàn)其serialize()方法,然后在方法中寫入轉(zhuǎn)換規(guī)則即可
舉例是把Date時(shí)間戳從 毫秒 轉(zhuǎn)換成 秒 為單位
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: 時(shí)間轉(zhuǎn)換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.然后在傳輸?shù)膶?shí)體類中的屬性上
打上@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; /** 訂單狀態(tài),默認(rèn)為新下單. */ private Integer orderStatus = OrderStatusEnum.NEW.getCode(); /** 支付狀態(tài),默認(rèn)為0未支付. */ private Integer payStatus = PayStatusEnum.WAIT.getCode(); @JsonSerialize(using = Date2LongSerializer.class) private Date createTime; @JsonSerialize(using = Date2LongSerializer.class) private Date updateTime; }
3.附加:還有一個(gè)比較好用的注解
如果返回對象中變量存在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: 數(shù)據(jù)傳輸對象,傳給前端時(shí)忽略值為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的注解,還是有個(gè)問題
如果一個(gè)一個(gè)實(shí)體類配置的話,未免太過麻煩,所以可以在配置文件中直接配置,yml配置文件如下:
@JsonSerialize 相關(guān)使用(jsonUtil)
基礎(chǔ)注解使用
1、實(shí)現(xiàn)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 = "新建狀態(tài)"; break; } jsonGenerator.writeString(statusStr); } }
2、添加注解
注:@JsonSerialize注解,主要應(yīng)用于數(shù)據(jù)轉(zhuǎn)換,該注解作用在該屬性的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;
③用在空對象上可以轉(zhuǎn)化
@JsonSerialize public class XxxxxBody { // 該對象暫無字段,直接new了返回 }
框架層面的使用
jsonUtil工具類
實(shí)現(xiàn)json轉(zhuǎn)換時(shí)所有的null轉(zhuǎn)為“”
1、實(shí)現(xiàn)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、實(shí)現(xiàn)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、工具類調(diào)用
public class JsonUtil { //序列化時(shí)String 為null時(shí)變成"" 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())); } /** * 將對象轉(zhuǎn)換為Json串,針對String 類型 null 轉(zhuǎn)成"" */ 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串和對象之間相互轉(zhuǎn)換工具類 */ public class JsonUtil { private static Logger logger = LoggerFactory.getLogger(JsonUtil.class); private static ObjectMapper mapper = new ObjectMapper(); //序列化時(shí)String 為null時(shí)變成"" 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())); } /** * 將對象轉(zhuǎn)換為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); } } /** * 將對象轉(zhuǎn)換為Json串,針對String 類型 null 轉(zhuǎn)成"" */ 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串轉(zhuǎn)換為對象 */ 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串轉(zhuǎn)換為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串轉(zhuǎn)換為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); } } }
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
如何利用grep-console插件使Intellij idea顯示多顏色調(diào)試日志
這篇文章主要介紹了利用grep-console插件使Intellij idea顯示多顏色調(diào)試日志,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-05-05Java線程基本使用之如何實(shí)現(xiàn)Runnable接口
這篇文章主要介紹了Java線程基本使用之如何實(shí)現(xiàn)Runnable接口問題,具有很好的參考價(jià)值,希望對大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-01-01SpringBoot如何讀取配置文件中的數(shù)據(jù)到map和list
這篇文章主要介紹了SpringBoot如何讀取配置文件中的數(shù)據(jù)到map和list,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-02-02Java語言實(shí)現(xiàn)非遞歸實(shí)現(xiàn)樹的前中后序遍歷總結(jié)
今天小編就為大家分享一篇關(guān)于Java語言實(shí)現(xiàn)非遞歸實(shí)現(xiàn)樹的前中后序遍歷總結(jié),小編覺得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來看看吧2019-01-01Java 詳解循環(huán)屏障CyclicBarrier如何實(shí)現(xiàn)多線程分段等待執(zhí)行完成
CyclicBarrier是一個(gè)同步工具類,可以翻譯成循環(huán)屏障,也叫障礙器或同步屏障。CyclicBarrier內(nèi)部有一個(gè)計(jì)數(shù)器count,調(diào)用障礙器的await方法會使計(jì)數(shù)器count的值減一,當(dāng)計(jì)數(shù)器count的值為0時(shí),表明調(diào)用了await方法線程已經(jīng)達(dá)到了設(shè)置的數(shù)量2021-11-11java實(shí)現(xiàn)對服務(wù)器的自動(dòng)巡檢郵件通知
這篇文章主要為大家詳細(xì)介紹了java實(shí)現(xiàn)對服務(wù)器的自動(dòng)巡檢郵件通知,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-05-05