欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

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

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

問題發(fā)生

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

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

查詢的方法是Get方法:

前端是通過url加參數傳過來的,如果有一個參數值為空的時候,由于setEntity() 并不過濾空白,執(zhí)行sql的時候 會把""作為參數去當做查詢條件,查詢就出現(xiàn)了問題:

于是我就想把空白轉換為null來解決這個問題了。

初始解決

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

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

用到的工具類如下

/**
* 將對象屬性轉化為map結合
*/
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);
 }
}

問題解決了。

優(yōu)化

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

解決問題首先要考慮兩種情況,一種是前端通過Get請求,路徑上帶參數;另一種是Post請求,帶著Request報文。

Post請求報文體

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

創(chuàng)建一個針對于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)建一個MappingJackson2HttpMessageConverter Bean:

@Bean
@Primary
public MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter() {
 MappingJackson2HttpMessageConverter jsonConverter = new MappingJackson2HttpMessageConverter();
 //設置解析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());
  //注冊自定義的StringDescrializer
  //registerModules函數可以注冊多個Module
 objectMapper.registerModule(simpleModule);

  //忽略未知屬性 防止解析報錯
  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;
}

對于Post報文體來說,測試成功了。

Get路徑帶參數

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

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

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

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

想要全局controller共享這個Databinder:

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

對于Get路徑帶參數來說,測試也成功了

思考

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

只不過這個editor缺省沒有注冊,需要手工注冊。

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

注意,StringTrimmerEditor構造方法中有一個參數,如果傳入true,則會將空白轉換為null. 這樣前面寫的StringEditor就不用了,spring 已經幫我們寫好了。

對于「Post」報文體來說,實際上我只需要改變的是「Jackson ObjectMapper」,不需要自定義整個MappingJackson2HttpMessageConverter ,只需要自定義Jackson ObjectMapper.百度了一下,果然有同學已經有了解決方案:

@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 {
              // 重點在這兒:如果為空白則返回null
              String value = jsonParser.getValueAsString();
              if (value == null || "".equals(value.trim())) {
                return null;
              }
              return value;
            }
          });
    }
  };
}

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

后記

好多問題,其實spring 都已經提供了解決方案,但是spring體系目前太龐大了,所以好多API和功能都不為人知。所以碰上問題就記錄下來是個很好的習慣

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

相關文章

  • Java中枚舉類enum的values()方法舉例詳解

    Java中枚舉類enum的values()方法舉例詳解

    這篇文章主要給大家介紹了關于Java中枚舉類enum的values()方法舉例詳解,作為一種常用方法,可以在枚舉中對數組里的枚舉值進行遍歷,這就是values()方法的使用,需要的朋友可以參考下
    2023-11-11
  • 帶你了解Java數據結構和算法之棧

    帶你了解Java數據結構和算法之棧

    這篇文章主要為大家介紹了Java數據結構和算法之棧 ,具有一定的參考價值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助
    2022-01-01
  • 利用JAVA反射,讀取數據庫表名,自動生成對應實體類的操作

    利用JAVA反射,讀取數據庫表名,自動生成對應實體類的操作

    這篇文章主要介紹了利用JAVA反射,讀取數據庫表名,自動生成對應實體類的操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-08-08
  • Spring?Boot實現(xiàn)web.xml功能示例詳解

    Spring?Boot實現(xiàn)web.xml功能示例詳解

    這篇文章主要介紹了Spring?Boot實現(xiàn)web.xml功能,通過本文介紹我們了解到,在Spring Boot應用中,我們可以通過注解和編程兩種方式實現(xiàn)web.xml的功能,包括如何創(chuàng)建及注冊Servlet、Filter以及Listener等,需要的朋友可以參考下
    2023-09-09
  • JAVA中SpringBoot啟動流程分析

    JAVA中SpringBoot啟動流程分析

    這篇文章主要介紹了JAVA中SpringBoot啟動流程分析的相關資料,需要的朋友可以參考下
    2023-01-01
  • java基礎的詳細了解第一天

    java基礎的詳細了解第一天

    這篇文章對Java編程語言的基礎知識作了一個較為全面的匯總,在這里給大家分享一下。需要的朋友可以參考,希望能給你帶來幫助
    2021-08-08
  • SpringCloud gateway跨域配置的操作

    SpringCloud gateway跨域配置的操作

    這篇文章主要介紹了SpringCloud gateway跨域配置的操作,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-07-07
  • 關于springboot中nacos動態(tài)路由的配置

    關于springboot中nacos動態(tài)路由的配置

    這篇文章主要介紹了springboot中nacos動態(tài)路由的配置方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-09-09
  • 使用SpringBoot和JPA實現(xiàn)批量處理新增、修改

    使用SpringBoot和JPA實現(xiàn)批量處理新增、修改

    最近項目需要在JPA中使用ID進行批量更新,所以下面這篇文章主要給大家介紹了關于使用SpringBoot和JPA實現(xiàn)批量處理新增、修改的相關資料,文中通過實例代碼介紹的非常詳細,需要的朋友可以參考下
    2023-06-06
  • 解決idea 暫存文件或idea切換分支代碼丟失的問題

    解決idea 暫存文件或idea切換分支代碼丟失的問題

    這篇文章主要介紹了解決idea 暫存文件或idea切換分支代碼丟失的問題,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2021-02-02

最新評論