最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

jackson 實(shí)現(xiàn)null轉(zhuǎn)0 以及0轉(zhuǎn)null的示例代碼

 更新時(shí)間:2020年09月28日 09:20:29   作者:Justnow_  
這篇文章主要介紹了jackson 實(shí)現(xiàn)null轉(zhuǎn)0 以及0轉(zhuǎn)null的示例代碼,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來(lái)看看吧

需求背景

最近遇到一個(gè)需求,有個(gè)數(shù)值類型的字段,非必填,默認(rèn)為空,數(shù)據(jù)庫(kù)表針對(duì)該字段設(shè)計(jì)的是一個(gè)int類型, 由于dba推薦規(guī)范,默認(rèn)該值是not null。這個(gè)時(shí)候,問題就來(lái)了,數(shù)據(jù)庫(kù)默認(rèn)存的是0,前端展示時(shí),又不能顯示這個(gè)0(需要的是null)

解決方案

針對(duì)此類處理,通常的方案有以下2種:

前端做處理,統(tǒng)一對(duì)0和null做處理,0即是null,null即是0

后端做處理,針對(duì)要處理的字段,在序列化之前或者之后做處理,或者采取硬編碼的方式,針對(duì)要處理的字段,寫if else

方案分析

針對(duì)第一種,這里面有個(gè)比較尷尬的地方,前端所接收的字段中,有些0是有意義的,譬如是否有效,0可能代表有效,如果統(tǒng)一做了處理,那這個(gè)改為null了,那就出問題了。假如不統(tǒng)一處理,則需要區(qū)別對(duì)待,由于對(duì)前端不熟,不知道是否有類似注解或者帶標(biāo)志的全局方法來(lái)處理類似問題,聽前端說處理比較麻煩,so,只能后端來(lái)處理了。

針對(duì)第二種,后端處理的方式更靈活一些,想要簡(jiǎn)單可拓展,使用@JasonSerilize和@JsonDeserialize注解,寫自定義序列化和反序列化類。想要快速完成,走硬編碼。起初,因?yàn)閷?duì)jackson的序列化反序列化機(jī)制不太了解,寫的2個(gè)serializer和deserializer發(fā)布后也問題不斷,所以為了保證項(xiàng)目的進(jìn)展,采取了比較惡心的硬編碼的方式,寫了很多if else來(lái)做判斷

測(cè)試序列化

maven依賴:jackson版本2.9.7

 <dependency>
 <groupId>com.fasterxml.jackson.core</groupId>
 <artifactId>jackson-databind</artifactId>
 <version>${jackson.version}</version>
 </dependency>
 <dependency>
 <groupId>com.fasterxml.jackson.core</groupId>
 <artifactId>jackson-core</artifactId>
 <version>${jackson.version}</version>
 </dependency>
 <dependency>
 <groupId>com.fasterxml.jackson.core</groupId>
 <artifactId>jackson-annotations</artifactId>
 <version>${jackson.version}</version>
 </dependency>

序列化類:

 @JacksonStdImpl
public class ZeroToNullSerializer extends JsonSerializer implements ContextualSerializer {

 private Class<?> type;

 public ZeroToNullSerializer() {

 }

 public ZeroToNullSerializer(final JavaType type) {
  this.type = type == null ? Object.class : type.getRawClass();
 }

 @Override
 public void serialize(Object o, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {

  if (o instanceof Short) {
   if (((Short) o).compareTo((short)0) == 0) {
    jsonGenerator.writeNull();
   } else {
    jsonGenerator.writeNumber(((Short) o).shortValue());
   }
  }
  if (o instanceof Integer) {
   if (((Integer) o).intValue() == 0) {
    jsonGenerator.writeNull();
   } else {
    jsonGenerator.writeNumber(((Integer) o).intValue());
   }
  }
  if (o instanceof Float) {
   if (((Float) o).compareTo(0f) == 0) {
    jsonGenerator.writeNull();
   } else {
    jsonGenerator.writeNumber(((Float) o).floatValue());
   }
  }

  if (o instanceof Double) {
   if (((Double) o).compareTo(0D) == 0) {
    jsonGenerator.writeNull();
   } else {
    jsonGenerator.writeNumber(((Double) o).doubleValue());
   }
  }

  if (o instanceof Long) {
   if (((Long) o).compareTo(0L) == 0) {
    jsonGenerator.writeNull();
   } else {
    jsonGenerator.writeNumber(((Long) o).longValue());
   }
  }
  if (o instanceof BigDecimal) {
   if (((BigDecimal) o).compareTo(BigDecimal.ZERO) == 0) {
    jsonGenerator.writeNull();
   }else {
    jsonGenerator.writeNumber((BigDecimal) o);
   }
  }
 }

 @Override
 public JsonSerializer<?> createContextual(SerializerProvider prov, BeanProperty property) throws JsonMappingException {
  return new ZeroToNullSerializer(property.getType());
 }
}

測(cè)試序列化的bean:

@Data
public class TestSerializerBean {
 @JsonSerialize(using =ZeroToNullSerializer.class)
 private Integer number;
 private Integer age;
 private BigDecimal money;
}

序列化Test:

@Test
 public void testSerializer() throws JsonProcessingException {
 TestSerializerBean serializerBean = new TestSerializerBean();
 serializerBean.setNumber(0);
 serializerBean.setAge(0);
 serializerBean.setMoney(new BigDecimal(20));

 String string = mapper.writeValueAsString(serializerBean);

 System.out.println(string);
 }

測(cè)試結(jié)果:

1、待測(cè)字段帶0:

2、待測(cè)字段不帶0

@Test
 public void testSerializer() throws JsonProcessingException {
 TestSerializerBean serializerBean = new TestSerializerBean();
 serializerBean.setNumber(10);
 serializerBean.setAge(0);
 serializerBean.setMoney(new BigDecimal(20));

 String string = mapper.writeValueAsString(serializerBean);

 System.out.println(string);
 }

測(cè)試反序列化

反序列化類(僅貼出核心代碼, 完整代碼我會(huì)上傳至github, 地址見后文鏈接):

 @Override
 public Object deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JsonProcessingException {
  if (this.type == Integer.class) {
   return handleInteger(p, ctxt);
  }
  if (this.type == Long.class) {
   return handleLong(p, ctxt);
  }
  if (this.type == BigDecimal.class) {
   return handleBigDecimal(p, ctxt);
  }
  if (this.type == Double.class) {
   return handleDouble(p, ctxt);
  }
  if (this.type == Float.class) {
   return handleFloat(p, ctxt);
  }
  if (this.type == Short.class) {
   return handleShort(p, ctxt);
  }
  throw new RuntimeException("反序列化錯(cuò)誤,類型" + type.toString() + "+不支持?jǐn)?shù)值類型的反序列化");
 }

private Object handleBigDecimal(JsonParser p, DeserializationContext ctxt) throws IOException {
  switch (p.getCurrentTokenId()) {
   case JsonTokenId.ID_NUMBER_INT:
   case JsonTokenId.ID_NUMBER_FLOAT:
    return p.getDecimalValue();
   case JsonTokenId.ID_STRING:
    String text = p.getText().trim();
    // note: no need to call `coerce` as this is never primitive
    if (text == null || text.length() == 0) {
     return getNullValue(ctxt);
    }
    try {
     return new BigDecimal(text);
    } catch (IllegalArgumentException iae) {
    }
    return (BigDecimal) ctxt.handleWeirdStringValue(type, text,
      "not a valid representation");
   case JsonTokenId.ID_START_ARRAY:
    throw new RuntimeException("NullToZeroDeserializer handleBigDecimal error, encounter token " + JsonTokenId.ID_START_ARRAY);
  }
  // Otherwise, no can do:
  return (BigDecimal) ctxt.handleUnexpectedToken(type, p);
 }
 
  @Override
 public Object getNullValue(DeserializationContext ctxt) throws JsonMappingException {
  if (this.type == Integer.class) {
   return 0;
  }
  if (this.type == BigDecimal.class) {
   return BigDecimal.ZERO;
  }
  return 0;
 }

待反序列化的bean:

@Data
public class TestDeSerializerBean{
 private Integer number;
 @JsonDeserialize(using = NullToZeroDeserializer.class)
 private BigDecimal money;
 private BigDecimal balance;
}

反序列化Test:

@Test
 public void testDeSerializer() throws IOException {
 TestDeSerializerBean serializerBean = new TestDeSerializerBean();
 serializerBean.setNumber(5);
 serializerBean.setMoney(new BigDecimal(20));

 String string = mapper.writeValueAsString(serializerBean);

 String testStr = "{\n" +
 " \"number\": 5,\n" +
 " \"money\": \"20.0\"\n" +
 "}";

 TestDeSerializerBean deSerializerBean = mapper.readValue(testStr, TestDeSerializerBean.class);

 System.out.println(deSerializerBean);
 }

測(cè)試結(jié)果:

null類型:

@Test
 public void testDeSerializer() throws IOException {
 TestDeSerializerBean serializerBean = new TestDeSerializerBean();
 serializerBean.setNumber(5);
 serializerBean.setMoney(new BigDecimal(20));

 String string = mapper.writeValueAsString(serializerBean);

 String testStr = "{\n" +
 " \"number\": 5,\n" +
 " \"money\": \"\"\n" +
 "}";

 TestDeSerializerBean deSerializerBean = mapper.readValue(testStr, TestDeSerializerBean.class);

 System.out.println(deSerializerBean);
 }

2. 非null類型

反序列化的類序列化null值時(shí),注意要重寫 getNullValue方法

總結(jié)

以上只是針對(duì)null轉(zhuǎn)0 以及0轉(zhuǎn)null寫的代碼,當(dāng)需要自定義的序列化時(shí),往往可以參考已有的serializer 和deserializer類,譬如DateDeserializer和DateSerializer,BigDecimalDeserializer和BigDecimalSerializer。參考這些以后的序列化與反序列化類,我們可以寫出任意想要的自定義的序列化和反序列化的效果

代碼地址

以上這篇jackson 實(shí)現(xiàn)null轉(zhuǎn)0 以及0轉(zhuǎn)null的示例代碼就是小編分享給大家的全部?jī)?nèi)容了,希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • Java 關(guān)系運(yùn)算符詳情及案例(下)

    Java 關(guān)系運(yùn)算符詳情及案例(下)

    這篇文章主要介紹了Java 關(guān)系運(yùn)算符詳情及案例的實(shí)現(xiàn),主要續(xù)上篇文章,上一篇文章我們講到“等于”運(yùn)算符 (==)、“不等于”運(yùn)算符(!=)、“大于”運(yùn)算符(>) ,這篇文章繼續(xù)給大家講解相關(guān)知識(shí),需要的朋友可以參考一下
    2021-12-12
  • MyBatis insert標(biāo)簽及常用屬性詳解

    MyBatis insert標(biāo)簽及常用屬性詳解

    這篇文章主要介紹了MyBatis insert標(biāo)簽,insert 標(biāo)簽中沒有 resultType 屬性,只有查詢操作才需要對(duì)返回結(jié)果類型進(jìn)行相應(yīng)的指定,需要的朋友可以參考下
    2023-10-10
  • JAVA利用順序表實(shí)現(xiàn)“楊輝三角”的思路及代碼示例

    JAVA利用順序表實(shí)現(xiàn)“楊輝三角”的思路及代碼示例

    楊輝三角形是中國(guó)古代數(shù)學(xué)的杰出研究成果之一,是我國(guó)北宋數(shù)學(xué)家賈憲于1050年首先發(fā)現(xiàn)并使用的,這篇文章主要介紹了JAVA利用順序表實(shí)現(xiàn)楊輝三角的思路及代碼示例,需要的朋友可以參考下
    2025-01-01
  • Java JDBC連接數(shù)據(jù)庫(kù)常見操作總結(jié)

    Java JDBC連接數(shù)據(jù)庫(kù)常見操作總結(jié)

    這篇文章主要介紹了Java JDBC連接數(shù)據(jù)庫(kù)常見操作,結(jié)合實(shí)例形式總結(jié)分析了java基于jdbc連接mysql、Oracle數(shù)據(jù)庫(kù)及連接池相關(guān)操作技巧,需要的朋友可以參考下
    2019-03-03
  • eclipse輸出Hello World的實(shí)現(xiàn)方法

    eclipse輸出Hello World的實(shí)現(xiàn)方法

    這篇文章主要介紹了eclipse輸出Hello World的實(shí)現(xiàn)方法,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-11-11
  • Java Servlet線程中AsyncContext異步處理Http請(qǐng)求

    Java Servlet線程中AsyncContext異步處理Http請(qǐng)求

    這篇文章主要介紹了Java Servlet線程中AsyncContext異步處理Http請(qǐng)求及在業(yè)務(wù)中應(yīng)用,AsyncContext是Servlet 3.0使Servlet 線程不再需要一直阻塞,直到業(yè)務(wù)處理完畢才能再輸出響應(yīng),最后才結(jié)束該Servlet線程
    2023-03-03
  • 自己動(dòng)手寫的mybatis分頁(yè)插件(極其簡(jiǎn)單好用)

    自己動(dòng)手寫的mybatis分頁(yè)插件(極其簡(jiǎn)單好用)

    最近做了個(gè)項(xiàng)目,需要用到mybatis分頁(yè)功能,網(wǎng)上找了很多插件,都不太合適,于是就自己動(dòng)手寫了個(gè)mybatis分頁(yè)插件功能,非常不錯(cuò),代碼簡(jiǎn)單易懂,需要的朋友參考下吧
    2016-11-11
  • 詳解spring注解式參數(shù)校驗(yàn)

    詳解spring注解式參數(shù)校驗(yàn)

    本篇文章主要介紹了詳解spring注解式參數(shù)校驗(yàn),小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來(lái)看看吧
    2017-06-06
  • Java中SSM+Shiro系統(tǒng)登錄驗(yàn)證碼的實(shí)現(xiàn)方法

    Java中SSM+Shiro系統(tǒng)登錄驗(yàn)證碼的實(shí)現(xiàn)方法

    這篇文章主要介紹了 SSM+Shiro系統(tǒng)登錄驗(yàn)證碼的實(shí)現(xiàn)方法,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下
    2017-02-02
  • Java實(shí)現(xiàn)excel動(dòng)態(tài)列導(dǎo)出的示例代碼

    Java實(shí)現(xiàn)excel動(dòng)態(tài)列導(dǎo)出的示例代碼

    這篇文章主要為大家詳細(xì)介紹了如何使用Java實(shí)現(xiàn)excel動(dòng)態(tài)列導(dǎo)出,文中的示例代碼講解詳細(xì),具有一定的借鑒價(jià)值,感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2024-03-03

最新評(píng)論

宁安市| 彭水| 两当县| 府谷县| 维西| 电白县| 米脂县| 巴中市| 五常市| 北辰区| 嵩明县| 谢通门县| 仲巴县| 特克斯县| 太仆寺旗| 汉阴县| 景宁| 阿拉善右旗| 即墨市| 安西县| 大名县| 千阳县| 温州市| 钟山县| 昌平区| 阜平县| 大连市| 枣强县| 朔州市| 特克斯县| 固始县| 治县。| 永善县| 南投县| 济南市| 合作市| 噶尔县| 郸城县| 四子王旗| 嵊州市| 麦盖提县|