电脑知识|欧美黑人一区二区三区|软件|欧美黑人一级爽快片淫片高清|系统|欧美黑人狂野猛交老妇|数据库|服务器|编程开发|网络运营|知识问答|技术教程文章 - 好吧啦网

您的位置:首頁(yè)技術(shù)文章
文章詳情頁(yè)

Spring:如何使用枚舉參數(shù)

瀏覽:58日期:2023-06-25 18:48:34
目錄 枚舉參數(shù)確認(rèn)需求定義枚舉Converter 和 ConverterFactory加載配置測(cè)試總結(jié) 枚舉參數(shù)

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

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

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

在場(chǎng)景不復(fù)雜的場(chǎng)景中,枚舉可以輕松勝任。

于是,迅速實(shí)現(xiàn)邏輯,準(zhǔn)備提測(cè)。這個(gè)時(shí)候需求變了,不允許選擇未知性別,只能選男或女,就沒(méi)有 0 值。這樣,因?yàn)槿≈凳菑?1 開(kāi)始,而枚舉的序號(hào)是從 0 開(kāi)始,就會(huì)產(chǎn)生沖突。

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

需求合不合理暫且不論,我們要保存對(duì)技術(shù)的探索精神。

確認(rèn)需求

首先確認(rèn)需求。我們期望定義一個(gè)枚舉類作為參數(shù),接口訪問(wèn)的時(shí)候,可以是 int 類型的 id,id 取值不限于枚舉的序號(hào);也可以是 String 類型的 code,code 取值不限于枚舉的 name。換句話說(shuō),這個(gè)枚舉有個(gè) id 和 code,隨意定義,只要接口傳過(guò)來(lái)匹配上,就能夠自動(dòng)轉(zhuǎn)成枚舉類型。

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

public interface IdBaseEnum { Integer getId();}public interface CodeBaseEnum { String getCode();}public interface IdCodeBaseEnum extends IdBaseEnum, CodeBaseEnum {}

接下來(lái)就該定義我們的主角了。

定義枚舉

前面定義了三個(gè)接口,分別是單獨(dú) id、單獨(dú) code,和有 id 和 code 的。這樣,我們就可以定義三種枚舉,分別對(duì)應(yīng)三個(gè)接口。三種方式類似,所以就不在文中重復(fù)列舉了。感興趣的可以關(guān)注公眾號(hào)「看山的小屋」回復(fù) spring 獲取源碼。

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

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; }}

這里需要注意一點(diǎn),id 和 code 不能重復(fù)。

1.id 與 id、code 與 code 不能重復(fù),比如 MAIL 定義 id 是 1,F(xiàn)AMLE 就不能定義 id 是 1 了。

2.id 與 code 之間也不能重復(fù),比如,MALE 定義 id 是 1001,F(xiàn)EMALE 定義 code 是 1001。

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

Converter 和 ConverterFactory

根據(jù)規(guī)范,接下來(lái)定義一下 Converter 和 ConverterFactory。這些是 Spring 留給我們的擴(kuò)展口,按照規(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 uncheckedConverter<String, T> converter = CONVERTERS.get(targetType);if (converter == null) { converter = new IdCodeToEnumConverter<>(targetType); CONVERTERS.put(targetType, converter);}return converter; }}

這兩個(gè)就是轉(zhuǎn)換的核心了,我們只要將他們裝配到 Spring 的類型轉(zhuǎn)換器中,就能夠?qū)崿F(xiàn)枚舉類型的自動(dòng)轉(zhuǎn)化了。

加載配置

將我們定義的 Converter 和 ConverterFactory 注冊(cè)到 Spring 的類型轉(zhuǎn)換器中。

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

至此,核心定義全部結(jié)束。

測(cè)試

寫(xiě)一個(gè) Controller 作為測(cè)試入口:

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

準(zhǔn)備測(cè)試用例測(cè)試:

@SpringBootTest(classes = SpringEnumParamApplication.class)@AutoConfigureMockMvcclass 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); }}總結(jié)

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

本文是應(yīng)用,下篇說(shuō)一下原理。以及 http body 形式請(qǐng)求的枚舉轉(zhuǎn)換邏輯。

本篇文章就到這里了,希望能給你帶來(lái)幫助,也希望您能夠多多關(guān)注好吧啦網(wǎng)的更多內(nèi)容!

標(biāo)簽: Spring
相關(guān)文章:
主站蜘蛛池模板: 耐火浇注料-喷涂料-浇注料生产厂家_郑州市元领耐火材料有限公司 耐力板-PC阳光板-PC板-PC耐力板 - 嘉兴赢创实业有限公司 | 杭州公司变更法人-代理记账收费价格-公司注销代办_杭州福道财务管理咨询有限公司 | 滑板场地施工_极限运动场地设计_滑板公园建造_盐城天人极限运动场地建设有限公司 | 安平县鑫川金属丝网制品有限公司,声屏障,高速声屏障,百叶孔声屏障,大弧形声屏障,凹凸穿孔声屏障,铁路声屏障,顶部弧形声屏障,玻璃钢吸音板 | HDPE储罐_厂家-山东九州阿丽贝防腐设备 | 南方珠江-南方一线电缆-南方珠江科技电缆-南方珠江科技有限公司 南汇8424西瓜_南汇玉菇甜瓜-南汇水蜜桃价格 | X光检测仪_食品金属异物检测机_X射线检测设备_微现检测 | 玉米深加工设备|玉米加工机械|玉米加工设备|玉米深加工机械-河南成立粮油机械有限公司 | 全钢实验台,实验室工作台厂家-无锡市辰之航装饰材料有限公司 | 脑钠肽-白介素4|白介素8试剂盒-研域(上海)化学试剂有限公司 | 迪威娱乐|迪威娱乐客服|18183620002| 瓶盖扭矩测试仪-瓶盖扭力仪-全自动扭矩仪-济南三泉中石单品站 | 带压开孔_带压堵漏_带压封堵-菏泽金升管道工程有限公司 | 多米诺-多米诺世界纪录团队-多米诺世界-多米诺团队培训-多米诺公关活动-多米诺创意广告-多米诺大型表演-多米诺专业赛事 | 乙炔气体报警装置|固定式氯化氢检测仪|河南驰诚电气百科 | sus630/303cu不锈钢棒,440C/430F/17-4ph不锈钢研磨棒-江苏德镍金属科技有限公司 | 厦门ISO认证|厦门ISO9001认证|厦门ISO14001认证|厦门ISO45001认证-艾索咨询专注ISO认证行业 | 不锈钢搅拌罐_高速搅拌罐厂家-无锡市凡格德化工装备科技有限公司 | 厌氧反应器,IC厌氧反应器,厌氧三相分离器-山东创博环保科技有限公司 | 钢格板_钢格栅_格栅板_钢格栅板 - 安平县鑫拓钢格栅板厂家 | 篷房|仓储篷房|铝合金篷房|体育篷房|篷房厂家-华烨建筑科技官网 知名电动蝶阀,电动球阀,气动蝶阀,气动球阀生产厂家|价格透明-【固菲阀门官网】 | 南溪在线-南溪招聘找工作、找房子、找对象,南溪综合生活信息门户! | 荣事达手推洗地机_洗地机厂家_驾驶式扫地机_工业清洁设备 | 衬氟止回阀_衬氟闸阀_衬氟三通球阀_衬四氟阀门_衬氟阀门厂-浙江利尔多阀门有限公司 | 家用净水器代理批发加盟_净水机招商代理_全屋净水器定制品牌_【劳伦斯官网】 | 气动|电动调节阀|球阀|蝶阀-自力式调节阀-上海渠工阀门管道工程有限公司 | 对夹式止回阀_对夹式蝶形止回阀_对夹式软密封止回阀_超薄型止回阀_不锈钢底阀-温州上炬阀门科技有限公司 | 无菌检查集菌仪,微生物限度仪器-苏州长留仪器百科 | 多物理场仿真软件_电磁仿真软件_EDA多物理场仿真软件 - 裕兴木兰 | 实验室pH计|电导率仪|溶解氧测定仪|离子浓度计|多参数水质分析仪|pH电极-上海般特仪器有限公司 | COD分析仪|氨氮分析仪|总磷分析仪|总氮分析仪-圣湖Greatlake | 世纪豪门官网 世纪豪门集成吊顶加盟电话 世纪豪门售后电话 | 山东限矩型液力偶合器_液力耦合器易熔塞厂家-淄博市汇川源机械厂 | 钢木实验台-全钢实验台-化验室通风柜-实验室装修厂家-杭州博扬实验设备 | 公交驾校-北京公交驾校欢迎您! 工作心得_读书心得_学习心得_找心得体会范文就上学道文库 | 臭氧灭菌箱-油桶加热箱-原料桶加热融化烘箱-南京腾阳干燥设备厂 臭氧发生器_臭氧消毒机 - 【同林品牌 实力厂家】 | 防爆电机-高压防爆电机-ybx4电动机厂家-河南省南洋防爆电机有限公司 | 防爆鼓风机-全风-宏丰鼓风机-上海梁瑾机电设备有限公司 | 等离子空气净化器_医用空气消毒机_空气净化消毒机_中央家用新风系统厂家_利安达官网 | 全自动在线分板机_铣刀式在线分板机_曲线分板机_PCB分板机-东莞市亿协自动化设备有限公司 | 亿立分板机_曲线_锯片式_走刀_在线式全自动_铣刀_在线V槽分板机-杭州亿协智能装备有限公司 |