激情久久久_欧美视频区_成人av免费_不卡视频一二三区_欧美精品在欧美一区二区少妇_欧美一区二区三区的

服務(wù)器之家:專注于服務(wù)器技術(shù)及軟件下載分享
分類導(dǎo)航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術(shù)|正則表達(dá)式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務(wù)器之家 - 編程語言 - Java教程 - springMVC引入Validation的具體步驟詳解

springMVC引入Validation的具體步驟詳解

2021-04-30 15:12倒騎的驢 Java教程

本文簡(jiǎn)單介紹如何引入validation的步驟,如何通過自定義validation減少代碼量,提高生產(chǎn)力,非常具有實(shí)用價(jià)值,需要的朋友可以參考下

本文簡(jiǎn)單介紹如何引入validation的步驟,如何通過自定義validation減少代碼量,提高生產(chǎn)力。特別提及:非基本類型屬性的valid,get方法的處理,validation錯(cuò)誤信息的統(tǒng)一resolve。

本文中validation的實(shí)際實(shí)現(xiàn)委托給hibernate validation處理

基本配置

pom引入maven依賴

?
1
2
3
4
5
6
7
8
9
10
11
12
<!-- validation begin -->
<dependency>
  <groupid>javax.validation</groupid>
  <artifactid>validation-api</artifactid>
  <version>1.1.0.final</version>
</dependency>
<dependency>
  <groupid>org.hibernate</groupid>
  <artifactid>hibernate-validator</artifactid>
  <version>5.4.0.final</version>
</dependency>
<!-- validation end -->

增加validation配置

在spring-mvc-servlet.xml中增加如下配置:

?
1
2
3
4
5
6
7
<mvc:annotation-driven validator="validator">
 
<bean id="validator" class="org.springframework.validation.beanvalidation.localvalidatorfactorybean">
  <property name="providerclass" value="org.hibernate.validator.hibernatevalidator" />
  <property name="validationmessagesource" ref="messagesource"/>
</bean>
//messagesource 為i18n資源管理bean,見applicationcontext.xml配置

自定義exceptionhandler

個(gè)性化處理validation錯(cuò)誤信息,返回給調(diào)用方的信息更加友好, 在applicationcontext.xml中增加如下配置:

?
1
2
3
4
5
6
7
8
9
10
11
<!-- 加載i18n消息資源文件 -->
<bean id="messagesource" class="org.springframework.context.support.resourcebundlemessagesource">
  <property name="basenames">
    <list>
      <value>errormsg</value>
      <value>validation_error</value>
    </list>
  </property>
</bean>
 
<bean id="validationexceptionresolver" class="com.*.exception.validationexceptionresovler"/>

在項(xiàng)目類路徑上增加:validation_error_zh_cn.properties資源文件:

?
1
2
3
4
5
6
#the error msg for input validation
#common
field.can.not.be.null={field}不能為空
field.can.not.be.empty={field}不能為空或者空字符串
field.must.be.greater.than.min={field}不能小于{value}
field.must.be.letter.than.max={field}不能大于{value}

validationexceptionresovler實(shí)現(xiàn):

validationexceptionresovler.java

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
@slf4j
public class validationexceptionresovler extends abstracthandlerexceptionresolver {
  public validationexceptionresovler() {
    // 設(shè)置order,在defaulthandlerexceptionresolver之前執(zhí)行
    this.setorder(0);
  }
  /**
   * handle the case where an argument annotated with {@code @valid} such as
   * an {@link } or {@link } argument fails validation.
   * <p>
   * 自定義validationexception 異常處理器
   * 獲取到具體的validation 錯(cuò)誤信息,并組裝commonresponse,返回給調(diào)用方。
   *
   * @param request current http request
   * @param response current http response
   * @param handler the executed handler
   * @return an empty modelandview indicating the exception was handled
   * @throws ioexception potentially thrown from response.senderror()
   */
  @responsebody
  protected modelandview handlemethodargumentnotvalidexception(bindingresult bindingresult,
                                 httpservletrequest request,
                                 httpservletresponse response,
                                 object handler)
      throws ioexception {
 
    list<objecterror> errors = bindingresult.getallerrors();
    stringbuffer errmsgbf = new stringbuffer();
    for (objecterror error : errors) {
      string massage = error.getdefaultmessage();
      errmsgbf.append(massage);
      errmsgbf.append("||");
    }
    string errmsgstring = errmsgbf.tostring();
    errmsgstring = errmsgstring.length() > 2 ? errmsgstring.substring(0, errmsgstring.length() - 2) : errmsgstring;
    log.error("validation failed! {} ", errmsgstring);
 
    map<string, object> map = new treemap<string, object>();
    map.put("success", false);
    map.put("errorcode", "9999");
    map.put("errormsg", errmsgstring);
 
    modelandview mav = new modelandview();
    mappingjackson2jsonview view = new mappingjackson2jsonview();
    view.setattributesmap(map);
    mav.setview(view);
 
    return mav;
  }
 
  @override
  protected modelandview doresolveexception(httpservletrequest request,
                       httpservletresponse response, object handler,
                       exception ex) {
    bindingresult bindingresult = null;
    if (ex instanceof methodargumentnotvalidexception) {
      bindingresult = ((methodargumentnotvalidexception) ex).getbindingresult();
    } else if(ex instanceof bindexception) {
      bindingresult = ((bindexception) ex).getbindingresult();
    } else {
      //other exception , ignore
    }
 
    if(bindingresult != null) {
      try {
        return handlemethodargumentnotvalidexception(bindingresult, request, response, handler);
      } catch (ioexception e) {
        log.error("doresolveexception: ", e);
      }
    }
    return null;
  }
}

在controller中增加@valid 

?
1
2
3
4
5
@requestmapping("/buy")
@responsebody
public baseresponse buy(@requestbody @valid buyflowerrequest request) throws exception {
 //......
}

在request bean上為需要validation的屬性增加validation注解

?
1
2
3
4
5
6
7
@setter
@getter
public class buyflowerrequest {
 
@notempty(message = "{name.can.not.be.null}")
private string name;
}

二級(jí)對(duì)象的validation

上面的寫法,只能對(duì)buyflowerrequest在基本類型屬性上做校驗(yàn),但是沒有辦法對(duì)對(duì)象屬性的屬性進(jìn)行validation,如果需要對(duì)二級(jí)對(duì)象的屬性進(jìn)行validation,則需要在二級(jí)對(duì)象及二級(jí)對(duì)象屬性上同時(shí)添加@valid 和 具體的validation注解.

如下寫法:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
@setter
@getter
public class buyflowerrequest {
  @notempty(field = "花名")
  private string name;
 
  @min(field = "價(jià)格", value = 1)
  private int price;
 
  @notnull
  private list<paytype> paytypelist;
 
}
 
@setter
@getter
public class paytype {
 
  @valid
  @min(value = 1)
  private int paytype;
 
  @valid
  @min(value = 1)
  private int payamount;
}

進(jìn)一步減少編碼量

為了減少編碼工作量,通過自定義validation注解,嘗試將validation作用的filed名稱傳遞到 錯(cuò)誤信息的資源文件中,從而避免為每個(gè)域編寫不同的message模版.

下面以重寫的@notnull為例講解:

1、定義validation注解,注意相比原生注解增加了field(),用于傳遞被validated的filed名字

notnull.java

?
1
2
3
4
5
6
7
8
9
@target( { elementtype.method, elementtype.field, elementtype.annotation_type, elementtype.constructor, elementtype.parameter })
@constraint(validatedby = { notnullvalidator.class })
@retention(retentionpolicy.runtime)
public @interface notnull {
  string field() default "";
  string message() default "{field.can.not.be.null}";
  class<?>[] groups() default {};
  class<? extends payload>[] payload() default {};
}

2、定義validator,所有的validator均實(shí)現(xiàn)constraintvalidator接口:

notnullvalidator.java

?
1
2
3
4
5
6
7
8
9
10
11
12
public class notnullvalidator implements constraintvalidator<notnull, object> {
 
  @override
  public void initialize(notnull annotation) {
 
  }
 
  @override
  public boolean isvalid(object str, constraintvalidatorcontext constraintvalidatorcontext) {
    return str != null;
  }
}

3、在filed上加入validation注解,注意指定filed值,message如果沒有個(gè)性化需求,可以不用指明,validation組件會(huì)自行填充default message。

buyflowerrequest.java

?
1
2
3
4
5
6
7
8
9
10
@setter
@getter
public class buyflowerrequest {
 
  @notempty(field = "花名")
  private string name;
 
  @min(field = "價(jià)格", value = 1)
  private int price;
}

注:@notnull注解已經(jīng)支持對(duì)list的特殊校驗(yàn),對(duì)于list類型節(jié)點(diǎn),如果list==null || list.size() == 0都會(huì)返回false,validation失敗。目前已按照此思路自定義實(shí)現(xiàn)了@notnull、@notempty、@min、@max注解,在goods工程中可以找到.

支持get請(qǐng)求

上面的示例都是post請(qǐng)求,@requestbody可以 resolve post請(qǐng)求,但是不支持get請(qǐng)求,閱讀spring的文檔和源碼,發(fā)現(xiàn)@modelattribute可以將get請(qǐng)求resolve成bean,且支持validation。具體可以翻閱spring源碼:modelattributemethodprocessor.resolveargument()方法。

使用示例:

?
1
2
3
4
5
6
7
8
9
@requestmapping(value = "/buy", method = requestmethod.get)
@responsebody
public baseresponse detail(@valid @modelattribute detailflowerrequest request) throws exception {
 
  detailflowerresponse response = new detailflowerresponse();
  response.setname(request.getname());
 
  return resultfactory.success(response, baseresponse.class);
}

todo

1、根據(jù)業(yè)務(wù)場(chǎng)景擴(kuò)展validation,如:日期格式、金額等

2、支持多個(gè)field關(guān)系校驗(yàn)的validation

 附:spring validation實(shí)現(xiàn)關(guān)鍵代碼

@requestbody

實(shí)現(xiàn)類:requestresponsebodymethodprocessor.java

?
1
2
3
4
5
6
7
8
9
10
11
12
13
public object resolveargument(methodparameter parameter, modelandviewcontainer mavcontainer, nativewebrequest webrequest, webdatabinderfactory binderfactory) throws exception {
 object arg = this.readwithmessageconverters(webrequest, parameter, parameter.getgenericparametertype());
 string name = conventions.getvariablenameforparameter(parameter);
 webdatabinder binder = binderfactory.createbinder(webrequest, arg, name);
 if (arg != null) {
 this.validateifapplicable(binder, parameter);
 if (binder.getbindingresult().haserrors() && this.isbindexceptionrequired(binder, parameter)) {
  throw new methodargumentnotvalidexception(parameter, binder.getbindingresult());
 }
 }
 mavcontainer.addattribute(bindingresult.model_key_prefix + name, binder.getbindingresult());
 return arg;
}

@modelattibute

實(shí)現(xiàn)類:modelattributemethodprocessor.java

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
public final object resolveargument(methodparameter parameter, modelandviewcontainer mavcontainer, nativewebrequest webrequest, webdatabinderfactory binderfactory) throws exception {
 string name = modelfactory.getnameforparameter(parameter);
 object attribute = mavcontainer.containsattribute(name) ? mavcontainer.getmodel().get(name) : this.createattribute(name, parameter, binderfactory, webrequest);
 if (!mavcontainer.isbindingdisabled(name)) {
 modelattribute ann = (modelattribute)parameter.getparameterannotation(modelattribute.class);
 if (ann != null && !ann.binding()) {
  mavcontainer.setbindingdisabled(name);
 }
 }
 webdatabinder binder = binderfactory.createbinder(webrequest, attribute, name);
 if (binder.gettarget() != null) {
 if (!mavcontainer.isbindingdisabled(name)) {
  this.bindrequestparameters(binder, webrequest);
 }
 this.validateifapplicable(binder, parameter);
 if (binder.getbindingresult().haserrors() && this.isbindexceptionrequired(binder, parameter)) {
  throw new bindexception(binder.getbindingresult());
 }
 }
 map<string, object> bindingresultmodel = binder.getbindingresult().getmodel();
 mavcontainer.removeattributes(bindingresultmodel);
 mavcontainer.addallattributes(bindingresultmodel);
 return binder.convertifnecessary(binder.gettarget(), parameter.getparametertype(), parameter);
}

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持服務(wù)器之家。

原文鏈接:http://www.cnblogs.com/daoqidelv/p/9061862.html

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 久久蜜桃精品一区二区三区综合网 | 美国av在线免费观看 | 色七七网站 | 久草视频2| 国产免费观看电影网站 | 在线观看日韩中文字幕 | 一级片久久免费 | 国产成人在线免费看 | 国产无限资源在线观看 | av在线免费不卡 | 国产一级毛片视频在线! | 色天使中文字幕 | 午夜国产在线 | 欧美黑人一级 | 欧美一区二区三区成人 | 日韩美香港a一级毛片免费 欧美一级淫片007 | 久久精品中文字幕一区二区三区 | 亚洲男人天堂 | 国产精品久久久久久久久久尿 | 国产91小视频在线观看 | 中国hdxxxx护士爽在线观看 | 国产精品www | 日操操夜操操 | 日本精品黄色 | 国内精品久久久久久久久久 | 国产精品一区在线看 | 成人在线观看一区二区三区 | 国产一级毛片高清视频 | 5a级毛片 | 福利在线播放 | 精品在线视频播放 | 亚洲精品免费播放 | 一级黄色免费大片 | 龙床上的呻吟高h | 毛片网站视频 | 黄污网站在线观看 | 色播av在线 | 午夜视频在线免费播放 | av免费在线观看av | 操碰视频在线观看 | 国产成人77亚洲精品www |