亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

SpringBoot之使用枚舉參數(shù)案例詳解

 更新時間:2021年09月03日 11:23:43   作者:沉潛飛動  
這篇文章主要介紹了SpringBoot之使用枚舉參數(shù)案例詳解,本篇文章通過簡要的案例,講解了該項技術的了解與使用,以下就是詳細內容,需要的朋友可以參考下

接口開發(fā)過程中不免有表示類型的參數(shù),比如 0 表示未知,1 表示男,2 表示女。通常有兩種做法,一種是用數(shù)字表示,另一種是使用枚舉實現(xiàn)。

使用數(shù)字表示就是通過契約形式,約定每個數(shù)字表示的含義,接口接收到參數(shù),就按照約定對類型進行判斷,接口維護成本比較大。

在 Spring 體系中,使用枚舉表示,是借助 Spring 的 Converter 機制,可以將數(shù)字或字符串對應到枚舉的序號或者 name,然后將前端的輸入轉換為枚舉類型。

在場景不復雜的場景中,枚舉可以輕松勝任。

于是,迅速實現(xiàn)邏輯,準備提測。這個時候需求變了,不允許選擇未知性別,只能選男或女,就沒有 0 值。這樣,因為取值是從 1 開始,而枚舉的序號是從 0 開始,就會產生沖突。

還有一些不太多的場景,就是前端不期望類型都是用數(shù)字,可能期望用一些有意義的字符串表示。但是按照前端規(guī)范,需要用小寫或者駝峰命名。但是后端的規(guī)范中,枚舉必須是大寫,又是沖突。

需求合不合理暫且不論,我們要保存對技術的探索精神。

確認需求

首先確認需求。我們期望定義一個枚舉類作為參數(shù),接口訪問的時候,可以是 int 類型的 id,id 取值不限于枚舉的序號;也可以是 String 類型的 code,code 取值不限于枚舉的 name。換句話說,這個枚舉有個 id 和 code,隨意定義,只要接口傳過來匹配上,就能夠自動轉成枚舉類型。

既然這樣,我們就規(guī)范下 id 和 code 取值。為了擴展,定義三個接口:IdBaseEnum、CodeBaseEnum 以及 IdCodeBaseEnum。

public interface IdBaseEnum {
    Integer getId();
}

public interface CodeBaseEnum {
    String getCode();
}

public interface IdCodeBaseEnum extends IdBaseEnum, CodeBaseEnum {
}

接下來就該定義我們的主角了。

定義枚舉

前面定義了三個接口,分別是單獨 id、單獨 code,和有 id 和 code 的。這樣,我們就可以定義三種枚舉,分別對應三個接口。三種方式類似,所以就不在文中重復列舉了。感興趣的可以關注公眾號「看山的小屋」回復 spring 獲取源碼。

我們定義一個性別枚舉,枚舉包含 id 和 code 兩個屬性。

public enum GenderIdCodeEnum implements IdCodeBaseEnum {
    MALE(1, "male"),
    FEMALE(2, "female");

    private final Integer id;
    private final String code;

    GenderIdCodeEnum(Integer id, String code) {
        this.id = id;
        this.code = code;
    }

    @Override
    public String getCode() {
        return code;
    }

    @Override
    public Integer getId() {
        return id;
    }
}

這里需要注意一點,id 和 code 不能重復。

  1. id 與 id、code 與 code 不能重復,比如 MAIL 定義 id 是 1,F(xiàn)AMLE 就不能定義 id 是 1 了。
  2. id 與 code 之間也不能重復,比如,MALE 定義 id 是 1001,F(xiàn)EMALE 定義 code 是 1001。

這是由于 Spring 在轉換參數(shù)的時候,將輸入參數(shù)全部視為 String 類型。雖然我們定義 id 和 code 類型不同,但是在匹配的時候,都是按照字符串匹配的。如果存在相同值,就會產生歧義。

Converter 和 ConverterFactory

根據(jù)規(guī)范,接下來定義一下 Converter 和 ConverterFactory。這些是 Spring 留給我們的擴展口,按照規(guī)范定義即可。

Converter 類:

public class IdCodeToEnumConverter<T extends IdCodeBaseEnum> implements Converter<String, T> {
    private final Map<String, T> idEnumMap = Maps.newHashMap();
    private final Map<String, T> codeEnumMap = Maps.newHashMap();

    public IdCodeToEnumConverter(Class<T> enumType) {
        Arrays.stream(enumType.getEnumConstants())
                .forEach(x -> {
                    idEnumMap.put(x.getId().toString(), x);
                    codeEnumMap.put(x.getCode(), x);
                });
    }

    @Override
    public T convert(String source) {
        return Optional.of(source)
                .map(codeEnumMap::get)
                .orElseGet(() -> Optional.of(source)
                        .map(idEnumMap::get)
                        .orElseThrow(() -> new CodeBaseException(ErrorResponseEnum.PARAMS_ENUM_NOT_MATCH)));
    }
}

ConverterFactory 類:

public class IdCodeToEnumConverterFactory implements ConverterFactory<String, IdCodeBaseEnum> {
    @SuppressWarnings("rawtypes")
    private static final Map<Class, Converter> CONVERTERS = Maps.newHashMap();

    @Override
    public <T extends IdCodeBaseEnum> Converter<String, T> getConverter(Class<T> targetType) {
        //noinspection unchecked
        Converter<String, T> converter = CONVERTERS.get(targetType);
        if (converter == null) {
            converter = new IdCodeToEnumConverter<>(targetType);
            CONVERTERS.put(targetType, converter);
        }
        return converter;
    }
}

這兩個就是轉換的核心了,我們只要將他們裝配到 Spring 的類型轉換器中,就能夠實現(xiàn)枚舉類型的自動轉化了。

加載配置

將我們定義的 Converter 和 ConverterFactory 注冊到 Spring 的類型轉換器中。

@Configuration
public class WebConfig implements WebMvcConfigurer {
    @Override
    public void addFormatters(FormatterRegistry registry) {
        registry.addConverterFactory(new IdCodeToEnumConverterFactory());
        registry.addConverterFactory(new CodeToEnumConverterFactory());
        registry.addConverterFactory(new IdToEnumConverterFactory());
    }
}

至此,核心定義全部結束。

測試

寫一個 Controller 作為測試入口:

@RestController
@RequestMapping("echo")
public class EchoController {
    @GetMapping("gender-id-code")
    public String genderIdCode(@RequestParam("gender") GenderIdCodeEnum gender) {
        return gender.name();
    }
}

準備測試用例測試:

@SpringBootTest(classes = SpringEnumParamApplication.class)
@AutoConfigureMockMvc
class EchoControllerTest {
    @Autowired
    private MockMvc mockMvc;

    @ParameterizedTest
    @ValueSource(strings = {"MALE", "male", "1"})
    void genderIdCode(String gender) throws Exception {
        final String result = mockMvc.perform(
                MockMvcRequestBuilders.get("/echo/gender-id-code")
                        .param("gender", gender)
        )
                .andExpect(MockMvcResultMatchers.status().isOk())
                .andDo(MockMvcResultHandlers.print())
                .andReturn()
                .getResponse()
                .getContentAsString();

        Assertions.assertEquals("MALE", result);
    }
}

文末總結

實現(xiàn)枚舉參數(shù)并不難,只要按照 Spring 的擴展規(guī)范實現(xiàn)即可。需要注意的是,注意枚舉類中唯一的 id 和 code。

本文是應用,下篇說一下原理。以及 http body 形式請求的枚舉轉換邏輯。

推薦閱讀

到此這篇關于SpringBoot之使用枚舉參數(shù)案例詳解的文章就介紹到這了,更多相關SpringBoot之使用枚舉參數(shù)內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • Java基礎之finally語句與return語句詳解

    Java基礎之finally語句與return語句詳解

    這篇文章主要介紹了Java基礎之finally語句與return語句詳解,文中有非常詳細的代碼示例,對正在學習java基礎的小伙伴們有非常好的幫助,需要的朋友可以參考下
    2021-04-04
  • 基于SpringBoot整合oauth2實現(xiàn)token認證

    基于SpringBoot整合oauth2實現(xiàn)token認證

    這篇文章主要介紹了基于SpringBoot整合oauth2實現(xiàn)token 認證,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2020-01-01
  • 深入解析java HashMap實現(xiàn)原理

    深入解析java HashMap實現(xiàn)原理

    這篇文章主要介紹了深入解析java HashMap實現(xiàn)原理的相關資料,需要的朋友可以參考下
    2015-09-09
  • 深入理解Java中的EnumMap和EnumSet

    深入理解Java中的EnumMap和EnumSet

    這篇文章主要介紹了深入理解Java中的EnumMap和EnumSet,一般來說我們會選擇使用HashMap來存儲key-value格式的數(shù)據(jù),考慮這樣的特殊情況,一個HashMap的key都來自于一個Enum類,這樣的情況則可以考慮使用本文要講的EnumMap,需要的朋友可以參考下
    2023-11-11
  • 如何從request中獲取body的數(shù)據(jù)

    如何從request中獲取body的數(shù)據(jù)

    這篇文章主要介紹了如何從request中獲取body的數(shù)據(jù)問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2023-11-11
  • springboot使用maven實現(xiàn)多環(huán)境運行和打包問題

    springboot使用maven實現(xiàn)多環(huán)境運行和打包問題

    這篇文章主要介紹了springboot使用maven實現(xiàn)多環(huán)境運行和打包問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-07-07
  • springboot啟動時如何指定spring.profiles.active

    springboot啟動時如何指定spring.profiles.active

    這篇文章主要介紹了springboot啟動時如何指定spring.profiles.active問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-04-04
  • 深入理解Java中的接口

    深入理解Java中的接口

    下面小編就為大家?guī)硪黄钊肜斫釰ava中的接口。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2016-05-05
  • Java 對稱加密幾種算法分別實現(xiàn)

    Java 對稱加密幾種算法分別實現(xiàn)

    這篇文章主要介紹了Java 對稱加密使用DES / 3DES / AES 這三種算法分別實現(xiàn)的相關資料,這里提供了實例代碼,需要的朋友可以參考下
    2017-01-01
  • 實例講解使用Spring通過JPA連接到Db2

    實例講解使用Spring通過JPA連接到Db2

    這篇文章主要介紹了通過實例講解使用Spring通過JPA連接到Db2,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,下面我們來一起學習一下吧
    2019-06-06

最新評論