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

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

Java Validation Api實(shí)現(xiàn)原理解析

瀏覽:18日期:2022-08-25 13:32:18

前言:

涉及知識點(diǎn):AOP、攔截器相關(guān)

功能主要實(shí)現(xiàn)類:因?yàn)閎ean validation只提供了接口并未實(shí)現(xiàn),使用時需要加上一個provider的包,例如hibernate-validator

范圍: 注解:@Valid @RequestBudy

主要實(shí)現(xiàn)類:RequestResponseBodyMethodProcessor

處理器:HandlerMethodArgumentResolver

注解說明:

@Valid:標(biāo)準(zhǔn)JSR-303規(guī)范的標(biāo)記型注解,用來標(biāo)記驗(yàn)證屬性和方法返回值,進(jìn)行級聯(lián)和遞歸校驗(yàn),@Valid可用于方法、字段、構(gòu)造器和參數(shù)上 @RequestBudy 請求的Body體,只能被讀取一次

RequestResponseBodyMethodProcessor 類說明:

// @since 3.1public class RequestResponseBodyMethodProcessor extends AbstractMessageConverterMethodProcessor { @Override public boolean supportsParameter(MethodParameter parameter) { return parameter.hasParameterAnnotation(RequestBody.class); } // 類上或者方法上標(biāo)注了@ResponseBody注解都行 @Override public boolean supportsReturnType(MethodParameter returnType) { return (AnnotatedElementUtils.hasAnnotation(returnType.getContainingClass(), ResponseBody.class) || returnType.hasMethodAnnotation(ResponseBody.class)); } // 這是處理入?yún)⒎庋b校驗(yàn)的入口,也是本文關(guān)注的焦點(diǎn) @Override public Object resolveArgument(MethodParameter parameter, @Nullable ModelAndViewContainer mavContainer, NativeWebRequest webRequest, @Nullable WebDataBinderFactory binderFactory) throws Exception { // 它是支持`Optional`容器的 parameter = parameter.nestedIfOptional(); // 使用消息轉(zhuǎn)換器HttpInputMessage把request請求轉(zhuǎn)換出來,拿到值~~~ // 此處注意:比如本例入?yún)⑹荘erson類,所以經(jīng)過這里處理會生成一個空的Person對象出來(反射) Object arg = readWithMessageConverters(webRequest, parameter, parameter.getNestedGenericParameterType()); // 獲取到入?yún)⒌拿Q,其實(shí)不叫形參名字,應(yīng)該叫objectName給校驗(yàn)時用的 // 請注意:這里的名稱是類名首字母小寫,并不是你方法里寫的名字。比如本利若形參名寫為personAAA,但是name的值還是person // 但是注意:`parameter.getParameterName()`的值可是personAAA String name = Conventions.getVariableNameForParameter(parameter); // 只有存在binderFactory才會去完成自動的綁定、校驗(yàn)~ // 此處web環(huán)境為:ServletRequestDataBinderFactory if (binderFactory != null) { WebDataBinder binder = binderFactory.createBinder(webRequest, arg, name); // 顯然傳了參數(shù)才需要去綁定校驗(yàn)嘛 if (arg != null) {// 這里完成數(shù)據(jù)綁定+數(shù)據(jù)校驗(yàn)~~~~~(綁定的錯誤和校驗(yàn)的錯誤都會放進(jìn)Errors里)// Applicable:適合validateIfApplicable(binder, parameter);// 若有錯誤消息hasErrors(),并且僅跟著的一個參數(shù)不是Errors類型,Spring MVC會主動給你拋出MethodArgumentNotValidException異常// 否則,調(diào)用者自行處理if (binder.getBindingResult().hasErrors() && isBindExceptionRequired(binder, parameter)) { throw new MethodArgumentNotValidException(parameter, binder.getBindingResult());} } // 把錯誤消息放進(jìn)去 證明已經(jīng)校驗(yàn)出錯誤了~~~ // 后續(xù)邏輯會判斷MODEL_KEY_PREFIX這個key的~~~~ if (mavContainer != null) {mavContainer.addAttribute(BindingResult.MODEL_KEY_PREFIX + name, binder.getBindingResult()); } } return adaptArgumentIfNecessary(arg, parameter); } // 校驗(yàn),如果合適的話。使用WebDataBinder,失敗信息最終也都是放在它身上~ 本方法是本文關(guān)注的焦點(diǎn) // 入?yún)ⅲ篗ethodParameter parameter protected void validateIfApplicable(WebDataBinder binder, MethodParameter parameter) { // 拿到標(biāo)注在此參數(shù)上的所有注解們(比如此處有@Valid和@RequestBody兩個注解) Annotation[] annotations = parameter.getParameterAnnotations(); for (Annotation ann : annotations) { // 先看看有木有@Validated Validated validatedAnn = AnnotationUtils.getAnnotation(ann, Validated.class); // 這個里的判斷是關(guān)鍵:可以看到標(biāo)注了@Validated注解 或者注解名是以Valid打頭的 都會有效哦 //注意:這里可沒說必須是@Valid注解。實(shí)際上你自定義注解,名稱只要一Valid開頭都成~~~~~ if (validatedAnn != null || ann.annotationType().getSimpleName().startsWith('Valid')) {// 拿到分組group后,調(diào)用binder的validate()進(jìn)行校驗(yàn)~~~~// 可以看到:拿到一個合適的注解后,立馬就break了~~~// 所以若你兩個主機(jī)都標(biāo)注@Validated和@Valid,效果是一樣滴~Object hints = (validatedAnn != null ? validatedAnn.value() : AnnotationUtils.getValue(ann));Object[] validationHints = (hints instanceof Object[] ? (Object[]) hints : new Object[] {hints});binder.validate(validationHints);break; } } } ...}

可以看得,這個類應(yīng)該是陌生的,它能夠處理@ResponseBody注解返回值;它還有另一個能力是:它能夠處理請求參數(shù)(當(dāng)然也是標(biāo)注了@RequestBody的JavaBean)所以它既是個處理返回值的HandlerMethodReturnValueHandler,又是一個處理入?yún)⒌腍andlerMethodArgumentResolver。所以它命名為Processor而不是Resolver/Handler。

這是使用@RequestBody結(jié)合@Valid完成數(shù)據(jù)校驗(yàn)的基本原理。其實(shí)當(dāng)Spring MVC在處理@RequestPart注解入?yún)?shù)據(jù)時,也會執(zhí)行綁定、校驗(yàn)的相關(guān)邏輯。對應(yīng)處理器是RequestPartMethodArgumentResolver,原理大體上和這相似,它主要處理Multipart相關(guān),本文忽略~

以上就是dui’y對于@Valid標(biāo)注的@RequestBody的JavaBean的原理說明,敬請指點(diǎn)。

以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持好吧啦網(wǎng)。

標(biāo)簽: Java
相關(guān)文章:
主站蜘蛛池模板: 紧急切断阀_气动切断阀_不锈钢阀门_截止阀_球阀_蝶阀_闸阀-上海上兆阀门制造有限公司 | 色谱柱-淋洗液罐-巴罗克试剂槽-巴氏吸管-5ml样品瓶-SBS液氮冻存管-上海希言科学仪器有限公司 | 电气控制系统集成商-PLC控制柜变频控制柜-非标自动化定制-电气控制柜成套-NIDEC CT变频器-威肯自动化控制 | 发电机价格|发电机组价格|柴油发电机价格|柴油发电机组价格网 | LED太阳能中国结|发光红灯笼|灯杆造型灯|节日灯|太阳能灯笼|LED路灯杆装饰造型灯-北京中海轩光电 | 食品无尘净化车间,食品罐装净化车间,净化车间配套风淋室-青岛旭恒洁净技术有限公司 | 大倾角皮带机-皮带输送机-螺旋输送机-矿用皮带输送机价格厂家-河南坤威机械 | 管家婆-管家婆软件-管家婆辉煌-管家婆进销存-管家婆工贸ERP | 分轨 | 上传文件,即刻分离人声和伴奏| 千斤顶,液压千斤顶-力良企业,专业的液压千斤顶制造商,shliliang.com | 水平垂直燃烧试验仪-灼热丝试验仪-漏电起痕试验仪-针焰试验仪-塑料材料燃烧检测设备-IP防水试验机 | 岩棉切条机厂家_玻璃棉裁条机_水泥基保温板设备-廊坊鹏恒机械 | 胜为光纤光缆_光纤跳线_单模尾纤_光纤收发器_ODF光纤配线架厂家直销_北京睿创胜为科技有限公司 - 北京睿创胜为科技有限公司 | 上海深蓝_缠绕机_缠膜机-上海深蓝机械装备有限公司 | 旅游规划_旅游策划_乡村旅游规划_景区规划设计_旅游规划设计公司-北京绿道联合旅游规划设计有限公司 | 【北京写字楼出租_写字楼租赁_办公室出租网/出售】-远行地产官网 | 超声波破碎仪-均质乳化机(供应杭州,上海,北京,广州,深圳,成都等地)-上海沪析实业有限公司 | 100_150_200_250_300_350_400公斤压力空气压缩机-舰艇航天配套厂家 | 扬子叉车厂家_升降平台_电动搬运车|堆高车-扬子仓储叉车官网 | 包装盒厂家_纸盒印刷_礼品盒定制-济南恒印包装有限公司 | 山东螺杆空压机,烟台空压机,烟台开山空压机-烟台开山机电设备有限公司 | 施工围挡-施工PVC围挡-工程围挡-深圳市旭东钢构技术开发有限公司 | 下水道疏通_管道疏通_马桶疏通_附近疏通电话- 立刻通 | (中山|佛山|江门)环氧地坪漆,停车场地板漆,车库地板漆,聚氨酯地板漆-中山永旺地坪漆厂家 | 注浆压力变送器-高温熔体传感器-矿用压力传感器|ZHYQ朝辉 | 隔离变压器-伺服变压器--输入输出电抗器-深圳市德而沃电气有限公司 | 100_150_200_250_300_350_400公斤压力空气压缩机-舰艇航天配套厂家 | 辐射仪|辐射检测仪|辐射巡测仪|个人剂量报警仪|表面污染检测仪|辐射报警仪|辐射防护网 | 游泳池设备安装工程_恒温泳池设备_儿童游泳池设备厂家_游泳池水处理设备-东莞市君达泳池设备有限公司 | 洁净棚-洁净工作棚-无菌室-净化工程公司_北京卫护科技有限公司 | 环比机械| 合金耐磨锤头_破碎机锤头_郑州市德勤建材有限公司 | 99文库_实习生实用的范文资料文库站 | WTB5光栅尺-JIE WILL磁栅尺-B60数显表-常州中崴机电科技有限公司 | 卫生人才网-中国专业的医疗卫生医学人才网招聘网站! | 智能汉显全自动量热仪_微机全自动胶质层指数测定仪-鹤壁市科达仪器仪表有限公司 | 精准猎取科技资讯,高效阅读科技新闻_科技猎 | 韦伯电梯有限公司| SOUNDWELL 编码器|电位器|旋转编码器|可调电位器|编码开关厂家-广东升威电子制品有限公司 | 生物除臭剂-除味剂-植物-污水除臭剂厂家-携葵环保有限公司 | 高通量组织研磨仪-多样品组织研磨仪-全自动组织研磨仪-研磨者科技(广州)有限公司 |