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

SpringBoot項(xiàng)目如何把接口參數(shù)中的空白值替換為null值(推薦)

 更新時(shí)間:2021年01月14日 11:41:47   作者:Java知音號(hào)  
這篇文章主要介紹了SpringBoot項(xiàng)目如何把接口參數(shù)中的空白值替換為null值(推薦),本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下

問(wèn)題發(fā)生

我們公司代碼生成的時(shí)候,查詢列表統(tǒng)一都是使用了setEntity() ,查詢寫法如下:

public List<BasReservoirArea> selectList(BasReservoirArea basReservoirArea) {
  QueryWrapper<BasReservoirArea> where = new QueryWrapper<>();
  where.setEntity(basReservoirArea);
  return baseMapper.selectList(where);
}

查詢的方法是Get方法:

前端是通過(guò)url加參數(shù)傳過(guò)來(lái)的,如果有一個(gè)參數(shù)值為空的時(shí)候,由于setEntity() 并不過(guò)濾空白,執(zhí)行sql的時(shí)候 會(huì)把""作為參數(shù)去當(dāng)做查詢條件,查詢就出現(xiàn)了問(wèn)題:

于是我就想把空白轉(zhuǎn)換為null來(lái)解決這個(gè)問(wèn)題了。

初始解決

一開(kāi)始自然而然想到在setEntity之前先判斷, 如果BasReservoirArea這個(gè)實(shí)例有字段的值是空白就設(shè)置為null

//1.對(duì)象轉(zhuǎn)map
Map<Object, Object> map = MapUtil.beanToMap(test);
//2.移除空值
MapUtil.removeNullValue(map);
//3.map轉(zhuǎn)回對(duì)象
Test entity = JSON.parseObject(JSON.toJSONString(map), Test.class);

用到的工具類如下

/**
* 將對(duì)象屬性轉(zhuǎn)化為map結(jié)合
*/
public static <T> Map<Object, Object> beanToMap(T bean) {
 Map<Object, Object> map = new HashMap<>();
 if (bean != null) {
 BeanMap beanMap = BeanMap.create(bean);
 for (Object key : beanMap.keySet()) {
  map.put(key, beanMap.get(key));
 }
 }
 return map;
}
/**
* 移除map中的value空值
*
* @param map
* @return
*/
public static void removeNullValue(Map map) {
 Set set = map.keySet();
 for (Iterator iterator = set.iterator(); iterator.hasNext(); ) {
 Object obj = (Object) iterator.next();
 Object value = (Object) map.get(obj);
 remove(value, iterator);
 }
}

問(wèn)題解決了。

優(yōu)化

由于感覺(jué)上面的解決方案不夠?qū)I(yè),不夠優(yōu)雅,所以先尋找更好的解決辦法,在后端接收參數(shù)值的時(shí)候,如果接收的是空白,直接設(shè)置為null, 這樣就不需要再次轉(zhuǎn)換了。

解決問(wèn)題首先要考慮兩種情況,一種是前端通過(guò)Get請(qǐng)求,路徑上帶參數(shù);另一種是Post請(qǐng)求,帶著Request報(bào)文。

Post請(qǐng)求報(bào)文體

由于筆者熟悉Post中報(bào)文體的轉(zhuǎn)換,知道是MappingJackson2HttpMessageConverter結(jié)合Jackson實(shí)現(xiàn)報(bào)文體轉(zhuǎn)換為實(shí)例的,而且也研究過(guò)Jackson, 所以解決辦法如下

創(chuàng)建一個(gè)針對(duì)于String.class的Jackson的反序列類:

public class StringDescrializer extends JsonDeserializer<String> {
  @Override
  public String deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JsonProcessingException {
    String value = jsonParser.getValueAsString();
    if (value == null || "".equals(value.trim())) {
      return null;
    }
    return value;
  }
}

創(chuàng)建一個(gè)MappingJackson2HttpMessageConverter Bean:

@Bean
@Primary
public MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter() {
 MappingJackson2HttpMessageConverter jsonConverter = new MappingJackson2HttpMessageConverter();
 //設(shè)置解析JSON工具類
 ObjectMapper objectMapper = new ObjectMapper();
 objectMapper.getSerializerProvider().setNullValueSerializer(
 new JsonSerializer<Object>() {
  @Override
  public void serialize(Object value, JsonGenerator jsonGenerator, SerializerProvider    serializerProvider) throws IOException {
   jsonGenerator.writeString("");
  }
 }
 );
 
 SimpleModule simpleModule = new SimpleModule();
 simpleModule.addDeserializer(String.class, new StringDescrializer());
  //注冊(cè)自定義的StringDescrializer
  //registerModules函數(shù)可以注冊(cè)多個(gè)Module
 objectMapper.registerModule(simpleModule);

  //忽略未知屬性 防止解析報(bào)錯(cuò)
  objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);

  jsonConverter.setObjectMapper(objectMapper);
  List<MediaType> list = new ArrayList<>();
  list.add(MediaType.APPLICATION_JSON_UTF8);
  jsonConverter.setSupportedMediaTypes(list);
  return jsonConverter;
}

對(duì)于Post報(bào)文體來(lái)說(shuō),測(cè)試成功了。

Get路徑帶參數(shù)

上面的解決方法不適用于Get方法路徑帶參數(shù)的情況,所以需要另外想辦法了。

由于我使用過(guò)@InitBinder注解,知道可以注入自定義的PropertyEditor, 在Editor里面可以自定義格式或者返回值,于是,自定義一個(gè)StringEditor來(lái)處理空白的問(wèn)題:、

public class StringEditor extends PropertyEditorSupport {
  //setAsText完成字符串到具體對(duì)象類型的轉(zhuǎn)換,
  @Override
  public void setAsText(String text) throws IllegalArgumentException {
    if (text == null || "".equals(text.trim())) {
      text = null;
    }
    setValue(text);
  }

  //getAsText完成具體對(duì)象類型到字符串的轉(zhuǎn)換。
  @Override
  public String getAsText() {
    if (getValue() != null) {
      return getValue().toString();
    }
    return null;
  }
}

想要全局controller共享這個(gè)Databinder:

@ControllerAdvice
public class GlobalControllerAdiviceController {
  //WebDataBinder是用來(lái)綁定請(qǐng)求參數(shù)到指定的屬性編輯器,可以繼承WebBindingInitializer
  //來(lái)實(shí)現(xiàn)一個(gè)全部controller共享的dataBiner 
  @InitBinder
  public void dataBind(WebDataBinder binder) {
    ///給指定類型注冊(cè)類型轉(zhuǎn)換器操作
    binder.registerCustomEditor(String.class, new StringEditor());
  }
}

對(duì)于Get路徑帶參數(shù)來(lái)說(shuō),測(cè)試也成功了

思考

解決完問(wèn)題后,還是覺(jué)得不夠優(yōu)雅,覺(jué)得spring 應(yīng)該會(huì)考慮到這種情況,終于在spring 的文檔中查閱到StringTrimmerEditor(https://docs.spring.io/spring-framework/docs/current/reference/html/core.html#beans-beans) 可以實(shí)現(xiàn)「Get」方法時(shí)參數(shù)去除空格:

只不過(guò)這個(gè)editor缺省沒(méi)有注冊(cè),需要手工注冊(cè)。

@ControllerAdvice
public class GlobalControllerAdiviceController {
  //WebDataBinder是用來(lái)綁定請(qǐng)求參數(shù)到指定的屬性編輯器,可以繼承WebBindingInitializer
  //來(lái)實(shí)現(xiàn)一個(gè)全部controller共享的dataBiner Java代碼
  @InitBinder
  public void dataBind(WebDataBinder binder) {
    ///注冊(cè)
    binder.registerCustomEditor(String.class, new StringTrimmerEditor(true));
  }
}

注意,StringTrimmerEditor構(gòu)造方法中有一個(gè)參數(shù),如果傳入true,則會(huì)將空白轉(zhuǎn)換為null. 這樣前面寫的StringEditor就不用了,spring 已經(jīng)幫我們寫好了。

對(duì)于「Post」報(bào)文體來(lái)說(shuō),實(shí)際上我只需要改變的是「Jackson ObjectMapper」,不需要自定義整個(gè)MappingJackson2HttpMessageConverter ,只需要自定義Jackson ObjectMapper.百度了一下,果然有同學(xué)已經(jīng)有了解決方案:

@Bean
public Jackson2ObjectMapperBuilderCustomizer jackson2ObjectMapperBuilderCustomizer() {
  return new Jackson2ObjectMapperBuilderCustomizer() {
    @Override
    public void customize(Jackson2ObjectMapperBuilder jacksonObjectMapperBuilder) {
      jacksonObjectMapperBuilder
          .deserializerByType(String.class, new StdScalarDeserializer<String>(String.class) {
            @Override
            public String deserialize(JsonParser jsonParser, DeserializationContext ctx)
                throws IOException {
              // 重點(diǎn)在這兒:如果為空白則返回null
              String value = jsonParser.getValueAsString();
              if (value == null || "".equals(value.trim())) {
                return null;
              }
              return value;
            }
          });
    }
  };
}

把上面的自定義StringDescrializer和MappingJackson2HttpMessageConverter去掉, 只保留上面的就行。

后記

好多問(wèn)題,其實(shí)spring 都已經(jīng)提供了解決方案,但是spring體系目前太龐大了,所以好多API和功能都不為人知。所以碰上問(wèn)題就記錄下來(lái)是個(gè)很好的習(xí)慣

到此這篇關(guān)于SpringBoot項(xiàng)目如何優(yōu)雅的把接口參數(shù)中的空白值替換為null值的文章就介紹到這了,更多相關(guān)SpringBoot空白值替換為null值內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • SpringBoot?整合RabbitMq?自定義消息監(jiān)聽(tīng)容器來(lái)實(shí)現(xiàn)消息批量處理

    SpringBoot?整合RabbitMq?自定義消息監(jiān)聽(tīng)容器來(lái)實(shí)現(xiàn)消息批量處理

    Spring Boot中提供了默認(rèn)的監(jiān)聽(tīng)器容器,但是有時(shí)候我們需要自定義監(jiān)聽(tīng)器容器,來(lái)滿足一些特殊的需求,比如批量獲取數(shù)據(jù),這篇文章主要介紹了SpringBoot?整合RabbitMq?自定義消息監(jiān)聽(tīng)容器來(lái)實(shí)現(xiàn)消息批量處理,需要的朋友可以參考下
    2023-04-04
  • Java內(nèi)存模型(JMM)及happens-before原理

    Java內(nèi)存模型(JMM)及happens-before原理

    這篇文章主要介紹了java內(nèi)存模型(JMM)及happens-before原理,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-04-04
  • SpringBoot如何集成Kafka低版本和高版本

    SpringBoot如何集成Kafka低版本和高版本

    這篇文章主要介紹了SpringBoot如何集成Kafka低版本和高版本問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-03-03
  • 深入理解java中的重載和覆蓋

    深入理解java中的重載和覆蓋

    下面小編就為大家?guī)?lái)一篇深入理解java中的重載和覆蓋。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2016-06-06
  • SpringBoot生成二維碼的實(shí)現(xiàn)

    SpringBoot生成二維碼的實(shí)現(xiàn)

    這篇文章主要介紹了SpringBoot生成二維碼的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-12-12
  • mybatis教程之動(dòng)態(tài)sql語(yǔ)句_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理

    mybatis教程之動(dòng)態(tài)sql語(yǔ)句_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理

    這篇文章主要介紹了mybatis教程之動(dòng)態(tài)sql語(yǔ)句,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-09-09
  • Java使用itext生成復(fù)雜數(shù)據(jù)的pdf的示例代碼

    Java使用itext生成復(fù)雜數(shù)據(jù)的pdf的示例代碼

    Apache iText 是一個(gè)開(kāi)源 Java 庫(kù),支持 PDF 文檔的開(kāi)發(fā)和轉(zhuǎn)換,在本教程中,我們將學(xué)習(xí)如何使用 iText 開(kāi)發(fā)可以創(chuàng)建、轉(zhuǎn)換和操作 PDF 文檔的 Java 程序,感興趣的小伙伴跟著小編一起來(lái)看看吧
    2024-12-12
  • SpringMVC使用@Valid注解實(shí)現(xiàn)數(shù)據(jù)驗(yàn)證的代碼示例

    SpringMVC使用@Valid注解實(shí)現(xiàn)數(shù)據(jù)驗(yàn)證的代碼示例

    在 Web 開(kāi)發(fā)中,數(shù)據(jù)驗(yàn)證是一個(gè)非常重要的環(huán)節(jié),它可以確保數(shù)據(jù)的合法性和正確性,保護(hù)系統(tǒng)不受到惡意攻擊或用戶誤操作的影響,在 SpringMVC 中,我們可以使用 @Valid 注解來(lái)實(shí)現(xiàn)數(shù)據(jù)驗(yàn)證,所以本文就給大家介紹具體的使用方法,需要的朋友可以參考下
    2023-07-07
  • 詳解Sentinel流量控制限流框架的原理與使用

    詳解Sentinel流量控制限流框架的原理與使用

    Sentinel 是一個(gè)高可用、高擴(kuò)展、高穩(wěn)定性的開(kāi)源流量控制和熔斷降級(jí)框架,可以在分布式系統(tǒng)中實(shí)現(xiàn)實(shí)時(shí)的流量控制,下面就來(lái)和大家聊聊是具體如何操作的吧
    2023-05-05
  • SpringBoot實(shí)現(xiàn)發(fā)送郵件功能

    SpringBoot實(shí)現(xiàn)發(fā)送郵件功能

    這篇文章主要介紹了SpringBoot 發(fā)送郵件功能實(shí)現(xiàn),本文以163郵箱為例通過(guò)這個(gè)小案例給大家介紹,需要的朋友可以參考下
    2019-12-12

最新評(píng)論

绥德县| 通江县| 道孚县| 延安市| 阳朔县| 禄劝| 滦南县| 邛崃市| 广宗县| 仙居县| 千阳县| 云和县| 嘉鱼县| 义马市| 桦川县| 无锡市| 阜新| 原平市| 广西| 新巴尔虎右旗| 金昌市| 尚志市| 曲周县| 清涧县| 若羌县| 罗甸县| 共和县| 独山县| 闻喜县| 新沂市| 邵阳县| 宁城县| 米易县| 仙游县| 咸阳市| 河西区| 宜丰县| 如皋市| 定襄县| 丹阳市| 肥城市|