日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程语言 > asp.net >内容正文

asp.net

Java工具类——通过配置XML验证Map

發(fā)布時間:2023/12/10 asp.net 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Java工具类——通过配置XML验证Map 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

Java工具類——通過配置XML驗證Map

背景

在JavaWeb項目中,接收前端過來的參數(shù)時通常是使用我們的實體類進(jìn)行接收的。但是呢,我們不能去決定已經(jīng)搭建好的框架是怎么樣的,在我接觸的框架中有一種就是通過Map來接收前端過來的所有參數(shù),框架中沒有實體類的說法,從接收參數(shù),驗證參數(shù)到參數(shù)至持久層整個過程都是通過Map來傳遞數(shù)據(jù)。

而在開發(fā)的過程中,減少了實體類的存在,有時是感覺挺方便的,比如:一個系統(tǒng)中有100多個表,這里我們可以減少工作量(雖然對應(yīng)表的實體可以代碼生成),因為我們開發(fā)過程中是需要返回多個表關(guān)聯(lián)后的結(jié)果的,這里可能我們需要創(chuàng)建DTO,這些步驟確實是挺煩人的。但是,前端過來的參數(shù)我們需不需要驗證呢?客戶的輸入不管有意或者是無意,我認(rèn)為都應(yīng)該讓系統(tǒng)的容錯能力更強(qiáng)悍一些。所以,在驗證前端過來的參數(shù)時,使用了Map就著實讓人頭痛。每個需要強(qiáng)制驗證的參數(shù)都需要get,然后判斷類型,強(qiáng)制轉(zhuǎn)型,判斷參數(shù)符不符合期望值邊界等。

所以,我就考慮了,實體類可以通過Spring MVC中Hibernate的Validation使用注解的方式進(jìn)行參數(shù)校驗,那么,少了實體類,我是不是可以通過配置XML的方式來達(dá)到類似有實體類的效果。網(wǎng)上找了類似關(guān)鍵詞的工具類,發(fā)現(xiàn)沒有我所期望的,所以就動手來了一個。

大致的想法

在Web開發(fā)時,有許多if-else語句的出現(xiàn)都是在為了驗證前端參數(shù)合不合法真的是挺無奈的,而且有些代碼雖然長起來類似但是呢要去重構(gòu)成一個公用的方法好像有些困難,時常問自己,要怎么去搞,Java不是JavaScript,語句沒那么靈活。

于是想著通過XML配置試試,大致就是通過配置好的XML代替我們的實體類,并且有個入口將XML中的實體映射,并傳入待驗證的Map,驗證之后傳出一個數(shù)組,如果驗證通過數(shù)組為空,不通過則是我們XML中配置的對應(yīng)錯誤語句。

如何設(shè)計XML格式

動手在這之前,需要想好我們大致的XML結(jié)構(gòu)是怎么樣的。這里,我的想法是,在我們一般遇到的參數(shù)主要就是Integer,String,Double,Date,List了(這里居然沒有考慮Boolean,算了,之后再做補(bǔ)充也行)。所以基于以上,設(shè)計的結(jié)構(gòu)大致如下:

<?xml version="1.0" encoding="UTF-8"?> <map-verifyxmlns="https://www.lger.cn/verify"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="https://www.lger.cn/verify map-verify-util.xsd"><!--在長度的方面分別使用了lt; lte; gt; gte; eq;分別代表<; <=; >; >=; =--><Entity name="User01"><!--castErrMsg為當(dāng)驗證過程中類型解析錯誤時返回提示--><String name="username" castErrMsg="username必須為字符串類型"><length><lt errMsg="當(dāng)前值不能小于2">2</lt></length><notNull errMsg="當(dāng)前值不能為空"/><notBlank errMsg="當(dāng)前值不能為空(去掉首尾空格)"/><pattern><!--如果不匹配則發(fā)出錯誤--><value errMsg="號碼D[0-8]{4}">[0-8]{4}</value><value errMsg="號碼D[0-7]{4}">[0-7]{4}</value></pattern></String><Integer name="age" castErrMsg="必須為整型"><lt errMsg="歲數(shù)必須大于2">2</lt><gt>150</gt><notNull/></Integer><List name="details"><notEmpty/><size><gte>0</gte></size><!-- 遍歷List內(nèi)容,遍歷的Entity映射為name為User02的實體 --><forEach entity="User02" /></List><Date name="birthday"><lt>1900-07-21</lt><notNull/></Date><Double name="money"><lt>1</lt><gt>150</gt><notNull/></Double></Entity><Entity name="User02"><String name="username"><length><lt errMsg="當(dāng)前值不能小于2">2</lt><gt errMsg="當(dāng)前值不能大于10">10</gt></length><notBlank errMsg="當(dāng)前值不能為空(去掉空格)"/></String></Entity> </map-verify>

需要寫出一個具有一定格式的XML那么還需要寫出一個約束文件了驗證是否XML格式寫的正確。這里還小學(xué)了一下XSD,這里就不貼出代碼了。

以上的XML大致的說了下怎么使用其替代實體類。寫到了這里其實有時還覺得使用實體類可能更方便,何必使用Map呢?但是,別人框架已經(jīng)寫了,參數(shù)只能接收到Map那我只能屈服了。

類結(jié)構(gòu)設(shè)計

首先,每一個Entity就是一個實體對象,這里我認(rèn)為每個Entity都應(yīng)該包含有一個驗證方法和一個初始化方法,因為在進(jìn)行XML解析時就調(diào)用init,在進(jìn)行Map驗證時就調(diào)用verify方法這樣,那些String節(jié)點也是類似的,解析初始化時就把XML中配置的信息保存起來,等到驗證時就通過之前保存的信息進(jìn)行判斷即可,不必重新解析了。

這里以解析一個IntegerEntity為例,首先是其父類,不論是XML中哪個節(jié)點,都是實現(xiàn)VerifyEntity接口,代碼如下:

public interface VerifyEntity {/*** 一個實體初始化,當(dāng)實體被創(chuàng)建時將由創(chuàng)建方主動調(diào)用* @param currentEle 被創(chuàng)建的實體節(jié)點* @param factory 實體創(chuàng)建工廠,可以通過此工廠創(chuàng)建Entity*/void init(Element currentEle, EntityFactory factory);/*** 驗證當(dāng)前節(jié)點是否匹配XML的配置* @param value 需要驗證的值* @return 異常字符串集*/String[] verify(Object value);/*** 初始化完畢后調(diào)用,傳入包含所有Entity的Map* @param entityMap entityMap*/void finished(Map<String, VerifyEntity> entityMap);}

首先解析XML時當(dāng)獲取到Entity節(jié)點下的子節(jié)點將會通過一個工廠類創(chuàng)建子節(jié)點的對應(yīng)實現(xiàn)VerifyEntity,之后調(diào)用init方法對當(dāng)前的子節(jié)點進(jìn)行解析。這里先看下IntegerEntity的源碼:

public class IntegerEntity implements VerifyEntity {private AbstractEquation<Integer> integerEquation;private boolean notNull = false;private String notNullErrMsg;private String castErrMsg;@Overridepublic void init(Element currentEle, EntityFactory factory) {// 開始解析當(dāng)前節(jié)點<Integer/>String name = currentEle.attributeValue("name");// 獲取節(jié)點屬性castErrMsg,看是否存在castErrMsgthis.castErrMsg = currentEle.attributeValue("castErrMsg");if (Util.isEmpty(this.castErrMsg)) {this.castErrMsg = name + ": this is not integer type.";} else {this.castErrMsg = name + ": " + this.castErrMsg;}// 獲取子節(jié)點notNullElement element = currentEle.element("notNull");if (element != null) {this.notNull = true;this.notNullErrMsg = element.attributeValue("errMsg");if (Util.isEmpty(this.notNullErrMsg)) {this.notNullErrMsg = name + ": this is not null";} else {this.notNullErrMsg = name + ": " + this.notNullErrMsg;}}// 這里是新建一個抽象的Equation類,主要是因為lt和lte等等的這些節(jié)點在其他實體中也有,為了代碼復(fù)用所以使用了抽象類來定義//這里實現(xiàn)后與上面解析notNull代碼差異不大integerEquation = new AbstractEquation<Integer>(currentEle, name) {@OverrideInteger valueOf(String value) {try {return Integer.valueOf(value);}catch (NumberFormatException e) {throw new ConvertException(castErrMsg);}}@Overrideboolean lessThan(Integer value, Integer lt) {return value < lt;}@Overrideboolean greaterThan(Integer value, Integer gt) {return value > gt;}@Overrideboolean lessThanOrEquals(Integer value, Integer lte) {return value <= lte;}@Overrideboolean greaterThanOrEquals(Integer value, Integer gte) {return value <= gte;}@Overrideboolean equals(Integer value, Integer eq) {return value.equals(eq);}};}@Overridepublic String[] verify(Object value) {//正式驗證參數(shù)是否合法if (value == null) {//如果之前解析包含notNull,則這里為true,那么將返回解析的notNullErrMsgif (this.notNull) {return new String[]{this.notNullErrMsg};}return null;}try {//使用上面實現(xiàn)的抽象類進(jìn)行驗證return integerEquation.verify(Integer.valueOf(value.toString()));}catch (NumberFormatException e) {return new String[]{this.castErrMsg};}}@Overridepublic void finished(Map<String, VerifyEntity> entityMap) {//這里是在Entity解析完畢后調(diào)用,并將保存Entity的Map傳入}}

其實根據(jù)以上的代碼可以看出,就是XML的節(jié)點對應(yīng)著一個VerifyEntity實現(xiàn),每一個實現(xiàn)都保存著其中定義的<notNull/>等信息。

實現(xiàn)后運行效果

這里我們的測試代碼如下,其中demo.xml為設(shè)計XML所示的代碼:

//初始化MapVerify,將定義好xml以數(shù)組方式傳入final String[] xmls = {"demo.xml"};MapVerify.init(xmls);final Map<String, Object> map = new HashMap<>(5);map.put("username", "12312371237123778");map.put("age", 1);map.put("birthday", "2000-07-21");map.put("money", 149);List<Map<String, Object>> list = new ArrayList<>(2);Map<String, Object> map1 = new HashMap<>(1);map1.put("username", "abcab");Map<String, Object> map2 = new HashMap<>(1);map2.put("username", "cc");list.add(map1);list.add(map2);map.put("details", list);System.out.println(Arrays.toString(MapVerify.verifyByReturnArr("User01", map)));

運行的結(jié)果如下:

[age: 歲數(shù)必須大于2]

總結(jié)

此想法是半年前的了,現(xiàn)在利用了空余的時間實現(xiàn)了自己的想法,趁熱打鐵寫下博客,希望有這個需求的小伙伴能節(jié)省自己的時間(注:這里Boolean的判斷沒有實現(xiàn),如果有需要就需要自己動手了:-))。以后也希望自己如果有什么小想法盡量的抽時間去做,不論做的好不好。

源碼已經(jīng)上傳至 GitHub,包含demo。
jar包請點擊 此鏈接,使用jar包時需要多引入dom4j依賴包

轉(zhuǎn)載于:https://www.cnblogs.com/lger/p/10645453.html

總結(jié)

以上是生活随笔為你收集整理的Java工具类——通过配置XML验证Map的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 水蜜桃亚洲精品 | 黄色综合网 | 男女做网站 | 青青草午夜 | 亚洲人成一区 | 能看av的网址 | 伊人春色av| 国模二区 | 国产亚洲精品久久久久四川人 | 在线免费视频一区二区 | 第四色激情 | 国产在线激情 | 成人激情小视频 | 免费禁漫天堂a3d | 中国少妇无码专区 | 蜜桃色999| 久草免费新视频 | 成人影视网址 | 久久久成人精品一区二区三区 | 国产精品一区二区欧美 | 国产精品免费电影 | 黄色片欧美 | 日韩看片 | 欧美性生活一区二区三区 | 91搞搞| 日本在线第一页 | 日韩在线一区视频 | 欧美一级全黄 | 日批网站在线观看 | 天天摸天天干 | 日韩精品一区二 | 中文字幕资源站 | 久久久九九 | 成人在线观看免费网站 | 91精品综合久久久久久五月天 | 99在线精品视频 | 亚洲免费观看高清 | 自拍偷拍视频网站 | 国产精品丝袜黑色高跟鞋的设计特点 | 91视频毛片 | 12av在线| 午夜爱 | 精品国产91 | 成人影片网址 | 午夜在线一区 | 亚洲美女一级片 | 超碰碰碰 | 九七在线视频 | 黄色国产视频网站 | 亚洲欧洲国产日韩 | 亚洲精品乱码久久久久久蜜桃图片 | 在线午夜电影 | 天天做天天爱天天做 | 在线观看视频一区二区三区 | 自拍偷拍第二页 | 免费一二区 | 日韩视频在线观看免费视频 | 最新国产拍偷乱偷精品 | 久久久久久久穴 | 爱视频福利网 | 污污污www精品国产网站 | 精品人妻aV中文字幕乱码色欲 | 免费av在线网 | 91国内精品野花午夜精品 | 午夜不卡久久精品无码免费 | 成人免费黄色 | 欧美揉bbbbb揉bbbbb| 国产成人一级片 | 日韩欧美自拍偷拍 | 中文字幕福利 | 国产精品99久久久久久久久 | 日本网站黄色 | 久久天堂电影 | 一区二区三区四区视频在线观看 | 精品日韩一区二区 | 一女双乳被两男吸视频 | 五月婷网| 97成人免费视频 | 国产v亚洲v天堂无码久久久 | 黄色激情四射 | 亚洲在线激情 | 香蕉视频网站在线 | 成人短视频在线免费观看 | 僵尸叔叔在线观看国语高清免费观看 | 国产做爰全过程免费视频 | 亚洲欧美日韩视频一区 | 午夜影院久久久 | 99综合 | 91久久精品国产91久久性色tv | 精品视频入口 | 精品国精品国产自在久不卡 | 毛片aaaaaa| 成人小视频免费 | 欧美精品二区三区四区免费看视频 | 久久久久久久久免费 | 亚洲欧美综合一区二区 | 青青青在线免费观看 | 成人免费福利视频 | 九九福利视频 |