<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      SpringBoot序列化、反序列化空字符串為null的三種方式

      一、需求:接收前端傳入的""空字符串參數(shù),有時候我們需要把它轉(zhuǎn)為null

      • SpringBoot項目
      • 方式:①Jackson(推薦)、②切面+反射、③注解+切面+反射
      • 后兩種方式,未做返回值的處理。

      二、三種方式

      1、Jackson正反序列化(推薦)

      • StdConverter 和 JsonSerializer的區(qū)別
      兩種方式都可以實現(xiàn)將空字符串修改為 null 值的邏輯,但它們之間有一些區(qū)別:
      
      1. **繼承的類不同**:
         - 使用 `StdConverter` 方式時,`StringToNullSerializer` 類繼承自 `StdConverter<String, String>`,并實現(xiàn)了 `convert` 方法。
         - 使用 `JsonSerializer` 方式時,`StringToNullSerializer` 類直接繼承自 `JsonSerializer<String>`,并實現(xiàn)了 `serialize` 方法。
      
      2. **接口和方法不同**:
         - `StdConverter` 是 Jackson 庫中提供的用于定義轉(zhuǎn)換器的類,其中的 `convert` 方法用于將一個類型轉(zhuǎn)換為另一個類型。
         - `JsonSerializer` 是 Jackson 庫中用于定制序列化邏輯的接口,其中的 `serialize` 方法用于將 Java 對象序列化為 JSON 數(shù)據(jù)。
      
      3. **對于序列化過程的處理不同**:
         - 在 `StdConverter` 方式中,你需要實現(xiàn) `convert` 方法來定義如何將空字符串轉(zhuǎn)換為 null 值。
         - 在 `JsonSerializer` 方式中,你需要實現(xiàn) `serialize` 方法來定義如何將字段序列化為 JSON 數(shù)據(jù),并在其中進行空字符串轉(zhuǎn)換為 null 值的處理。
      
      綜上所述,兩種方式都可以實現(xiàn)相同的功能,選擇哪一種方式取決于個人偏好以及代碼的整體結(jié)構(gòu)和風格。通常來說,如果只需要定制序列化邏輯而不需要轉(zhuǎn)換其他類型,直接實現(xiàn) `JsonSerializer` 接口可能會更清晰和簡潔。
      
      • ENTITY
      package com.cc.jxtd.entity;
      
      import com.cc.jxtd.serializer.ConverterEmptyStringToNull;
      import com.cc.jxtd.serializer.EmptyStringToNullDeserializer;
      import com.cc.jxtd.serializer.ConverterEmptyStringToInteger0;
      import com.cc.jxtd.serializer.EmptyStringToNullSerializer;
      import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
      import com.fasterxml.jackson.databind.annotation.JsonSerialize;
      import lombok.Data;
      
      import javax.naming.Name;
      
      /**
       * <p>請求,返回都用這個</p>
       *
       * @author --
       * @since 2024/4/19
       */
      @Data
      public class UserCs {
      
          private Long id;
      
          //反序列化(前端請求):空字符串為null
          @JsonDeserialize(using = EmptyStringToNullDeserializer.class)
          private String name;
      
          //反序列化(前端請求):轉(zhuǎn)換:為其他類型的值(轉(zhuǎn)換為int的0)
          @JsonDeserialize(converter = ConverterEmptyStringToInteger0.class)
          private Integer descConverter0;
      
          //序列化(后端返回):空字符串為null
          @JsonSerialize(using = EmptyStringToNullSerializer.class)
          private String descSerialize;
      
          //序列化(后端返回):轉(zhuǎn)換:空字符串轉(zhuǎn)為null
          @JsonSerialize(converter = ConverterEmptyStringToNull.class)
          private String descConverterNull;
          
      }
      
      
      • 序列化處理類
      package com.cc.jxtd.serializer;
      
      import com.fasterxml.jackson.core.JsonGenerator;
      import com.fasterxml.jackson.databind.JsonSerializer;
      import com.fasterxml.jackson.databind.SerializerProvider;
      
      import java.io.IOException;
      
      /** 序列化:String的空轉(zhuǎn)為null
       * @author --
       * @since 2024/4/18
       **/
      public class EmptyStringToNullSerializer extends JsonSerializer<String> {
      
          /**
           * 序列化為null
           */
          @Override
          public void serialize(String value, JsonGenerator gen, SerializerProvider serializerProvider) throws IOException {
              if (value == null || value.trim().isEmpty()) {
                  gen.writeNull();
              }else {
                  gen.writeString(value);
              }
          }
      }
      
      • 反序列化處理類
      package com.cc.jxtd.serializer;
      
      import com.fasterxml.jackson.core.JsonParser;
      import com.fasterxml.jackson.databind.DeserializationContext;
      import com.fasterxml.jackson.databind.JsonDeserializer;
      
      import java.io.IOException;
      
      /** 反序列化:空字符串轉(zhuǎn)換為null
       * @author --
       * @since 2024/4/18
       **/
      public class EmptyStringToNullDeserializer extends JsonDeserializer<String> {
      
          /**
           * 反序列化為null
           */
          @Override
          public String deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
              String value = p.getValueAsString();
              if (value == null || value.trim().isEmpty()) {
                  return null;
              }
              return value;
          }
      
      }
      
      • 序列化-轉(zhuǎn)換1
      package com.cc.jxtd.serializer;
      
      import com.fasterxml.jackson.databind.util.StdConverter;
      
      /** 序列化-轉(zhuǎn)換:將string的空轉(zhuǎn)為null
       * @author --
       * @since 2024/4/18
       **/
      public class ConverterEmptyStringToNull extends StdConverter<String, String> {
      
          @Override
          public String convert(String value) {
              //把空的string轉(zhuǎn)為int的0
              if (value == null || value.trim().isEmpty()) {
                  return null;
              }
              return value;
          }
      
      }
      
      • 序列化-轉(zhuǎn)換2
      package com.cc.jxtd.serializer;
      
      import com.fasterxml.jackson.annotation.JsonPropertyOrder;
      import com.fasterxml.jackson.databind.util.StdConverter;
      
      /** 序列化:1將string轉(zhuǎn)為int。
       *         2轉(zhuǎn)換String的空或null -》 轉(zhuǎn)為Integer的0
       * @author --
       * @since 2024/4/18
       **/
      public class ConverterEmptyStringToInteger0 extends StdConverter<String, Integer> {
      
          @Override
          public Integer convert(String value) {
              //把空的string轉(zhuǎn)為int的0
              if (value == null || value.trim().isEmpty()) {
                  return 0;
              }
              return Integer.valueOf(value);
          }
      
      }
      
      • Controller
      package com.cc.jxtd.web.controller;
      
      import com.cc.jxtd.entity.UserCs;
      import org.springframework.web.bind.annotation.PostMapping;
      import org.springframework.web.bind.annotation.RequestBody;
      import org.springframework.web.bind.annotation.RequestMapping;
      import org.springframework.web.bind.annotation.RestController;
      
      /**
       * <p></p>
       *
       * @author --
       * @since 2024/4/19
       */
      @RestController
      @RequestMapping("/userCs")
      public class UserController {
      
          @PostMapping
          public UserCs get(@RequestBody UserCs req){
              System.out.println("請求參數(shù)-id:"   + req.getId());
              System.out.println("請求參數(shù)-name:" + req.getName());
              System.out.println("請求參數(shù)-desc1:" + req.getDescSerialize());
              System.out.println("請求參數(shù)-desc2:" + req.getDescConverterNull());
              System.out.println("請求參數(shù)-desc3:" + req.getDescConverter0());
      
              //返回:序列化
              return req;
          }
      }
      
      • 測試
        image

      2、切面+反射/3、注解+切面+反射

      • 區(qū)別
      2、切面+反射:所有空字符串的字段都轉(zhuǎn)為null
      3、注解+切面+反射:只有打了@EmptyToNull的字段才會轉(zhuǎn)換
      
      • 導入包
      		<!--spring-boot-starter-aop-->
              <dependency>
                  <groupId>org.springframework.boot</groupId>
                  <artifactId>spring-boot-starter-aop</artifactId>
              </dependency>
      
      • 切面
      package com.cc.jxtd.aspect;
      
      import com.cc.jxtd.annotation.EmptyToNull;
      import org.aspectj.lang.ProceedingJoinPoint;
      import org.aspectj.lang.annotation.Around;
      import org.aspectj.lang.annotation.Aspect;
      import org.aspectj.lang.annotation.Pointcut;
      import org.slf4j.Logger;
      import org.slf4j.LoggerFactory;
      import org.springframework.stereotype.Component;
      
      import java.lang.reflect.Field;
      import java.util.Objects;
      
      /** 切面
       * @author --
       */
      @Aspect
      @Component
      public class UpdateAspect {
      
          private static final Logger logger = LoggerFactory.getLogger(UpdateAspect.class);
      
          //切入點
          @Pointcut("@annotation(com.cc.jxtd.annotation.OptConverter)")
          public void validPointCut() {
          }
      
          /**
           * 環(huán)繞修改參數(shù)
           */
          @Around("validPointCut()")
          public Object around(ProceedingJoinPoint point) throws Throwable {
              Object[] args = point.getArgs();
              Object arg = args[0];
              //2、切面+反射:全部轉(zhuǎn)換
              this.allEmptyToNull(arg);
              //3、注解+切面+反射:部分轉(zhuǎn)換
      //        this.assignEmptyToNull(arg);
      
              return point.proceed();
          }
      
          /**
           * 設置請求參數(shù)中 所有字段的空值(如:String的空字符串)為null
           * @param arg arg
           */
          public void allEmptyToNull(Object arg) {
              if (Objects.isNull(arg)) {
                  return;
              }
              Field[] fields = arg.getClass().getDeclaredFields();
              for (Field field : fields) {
                  // 設置字段可訪問
                  field.setAccessible(true);
                  // 如果字段是 String 類型且值為空字符串,則設置為 null
                  if (field.getType() == String.class) {
                      try {
                          String value = (String) field.get(arg);
                          if (value != null && value.isEmpty()) {
                              field.set(arg, null);
                          }
                      } catch (IllegalAccessException e) {
                          e.printStackTrace();
                      }
                  }
                  // 可以擴展其他類型的參數(shù)……
      
              }
          }
      
          /** 指定空轉(zhuǎn)null
           * @param arg arg
           * @since 2024/4/18
           **/
          private void assignEmptyToNull(Object arg) {
              if (Objects.isNull(arg)) {
                  return;
              }
              Field[] fields = arg.getClass().getDeclaredFields();
              for (Field field : fields) {
                  if (field.isAnnotationPresent(EmptyToNull.class)) {
                      // 設置字段可訪問
                      field.setAccessible(true);
                      // 如果字段是 String 類型且值為空字符串,則設置為 null
                      if (field.getType() == String.class) {
                          try {
                              String value = (String) field.get(arg);
                              if (value != null && value.isEmpty()) {
                                  field.set(arg, null);
                              }
                          } catch (IllegalAccessException e) {
                              e.printStackTrace();
                          }
                      }
                      // 可以擴展其他類型的參數(shù)……
      
                  }
      
              }
          }
      }
      
      • 注解
      package com.cc.jxtd.annotation;
      
      import java.lang.annotation.ElementType;
      import java.lang.annotation.Retention;
      import java.lang.annotation.RetentionPolicy;
      import java.lang.annotation.Target;
      
      /**
       * 轉(zhuǎn)換
       * @author --
       */
      @Target(ElementType.METHOD)
      @Retention(RetentionPolicy.RUNTIME)
      public @interface OptConverter {
          
      }
      
      • 注解2
      package com.cc.jxtd.annotation;
      
      import java.lang.annotation.ElementType;
      import java.lang.annotation.Retention;
      import java.lang.annotation.RetentionPolicy;
      import java.lang.annotation.Target;
      
      /** 轉(zhuǎn)化空為null
       * @author --
       * @since 2024/4/18
       **/
      @Target(ElementType.FIELD)
      @Retention(RetentionPolicy.RUNTIME)
      public @interface EmptyToNull {
      
      }
      
      • entity
      package com.cc.jxtd.entity;
      
      import com.cc.jxtd.serializer.ConverterEmptyStringToInteger0;
      import com.cc.jxtd.serializer.ConverterEmptyStringToNull;
      import com.cc.jxtd.serializer.EmptyStringToNullDeserializer;
      import com.cc.jxtd.serializer.EmptyStringToNullSerializer;
      import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
      import com.fasterxml.jackson.databind.annotation.JsonSerialize;
      import lombok.Data;
      
      /**
       * <p>請求,返回都用這個</p>
       *
       * @author --
       * @since 2024/4/19
       */
      @Data
      public class UserCs2 {
      
          private Long id;
      
          private String name;
      
          private String desc;
      
      }
      
      • controller
      package com.cc.jxtd.web.controller;
      
      import com.cc.jxtd.annotation.OptConverter;
      import com.cc.jxtd.entity.UserCs;
      import com.cc.jxtd.entity.UserCs2;
      import org.springframework.web.bind.annotation.PostMapping;
      import org.springframework.web.bind.annotation.RequestBody;
      import org.springframework.web.bind.annotation.RequestMapping;
      import org.springframework.web.bind.annotation.RestController;
      
      /**
       * <p></p>
       *
       * @author --
       * @since 2024/4/19
       */
      @RestController
      @RequestMapping("/userCs")
      public class UserController {
      
      //    @PostMapping
      //    public UserCs get(@RequestBody UserCs req){
      //        System.out.println("請求參數(shù)-id:"   + req.getId());
      //        System.out.println("請求參數(shù)-name:" + req.getName());
      //        System.out.println("請求參數(shù)-DescSerialize:" + req.getDescSerialize());
      //        System.out.println("請求參數(shù)-DescConverterNull:" + req.getDescConverterNull());
      //        System.out.println("請求參數(shù)-DescConverter0:" + req.getDescConverter0());
      //
      //        //返回:序列化
      //        return req;
      //    }
      
          @OptConverter
          @PostMapping
          public UserCs2 get(@RequestBody UserCs2 req){
              System.out.println("請求參數(shù)-id:"   + req.getId());
              System.out.println("請求參數(shù)-name:" + req.getName());
              System.out.println("請求參數(shù)-desc:" + req.getDesc());
      
              //返回:序列化
              return req;
          }
      
      }
      
      • 測試2
        image

      • 測試3
        image
        image
        image

      posted on 2024-04-19 15:37  C_C_菜園  閱讀(1742)  評論(0)    收藏  舉報

      導航

      主站蜘蛛池模板: 高清dvd碟片 生活片| av无码精品一区二区乱子| 精品国产女同疯狂摩擦2| 高清无码午夜福利视频| 欧洲码亚洲码的区别入口| 万州区| 亚洲一区二区三区十八禁| 亚洲最大成人免费av| 久久精品免视看国产成人| 一卡2卡三卡4卡免费网站| 丰满无码人妻热妇无码区| 欧美成人精品手机在线| 樱桃熟了a级毛片| 国产成人精品一区二区三| 摸丰满大乳奶水www免费| 日韩不卡二区三区三区四区| 色狠狠色婷婷丁香五月| 久草热8精品视频在线观看| 国产人妻精品午夜福利免费| 国产卡一卡二卡三免费入口| 亚洲综合中文字幕第一页| 久久午夜无码免费| 成人免费A级毛片无码片2022| 久久精品国产99久久6| 国产精品无码无卡在线观看久| 国产一二三四区中| 亚洲熟妇久久精品| 亚洲美女厕所偷拍美女尿尿| 日韩精品无码区免费专区| 小嫩批日出水无码视频免费| 亚洲春色在线视频| 伊人久久大香线蕉av色婷婷色| 中文字幕乱码人妻综合二区三区| 岚皋县| 亚洲精品中文av在线| 色猫咪av在线观看| 欧美午夜理伦三级在线观看 | 中文字幕亚洲综合久久蜜桃| 亚洲中文字幕无码永久在线| 99人中文字幕亚洲区三| 丁香五月亚洲综合在线国内自拍|