Spring MVC+FastJson+hibernate-validator整合的完整實(shí)例教程
一:hibernate-validator 基礎(chǔ)
1. 簡(jiǎn)介:
通過使用注解Annotations 給類或者類的屬性加上約束(constraint),在運(yùn)行期檢查屬性值的合法性.
2. 作用:
在API接口開發(fā)中參數(shù)校驗(yàn)是非常重要的事情,因?yàn)榭蛻舳撕芸赡軙?huì)少傳參數(shù),或者值不合法,甚至參數(shù)值是惡意的,所以對(duì)客戶端傳來的參數(shù)的合法性就必須要校驗(yàn)了,其中將參數(shù)值的校驗(yàn)規(guī)則通過注解的形式注解到屬性上是一種比較優(yōu)雅的方式。
3. 常用的約束注解
- @Null 被注釋的元素必須為 null
- @NotNull 被注釋的元素必須不為 null
- @AssertTrue 被注釋的元素必須為 true
- @AssertFalse 被注釋的元素必須為 false
- @Min(value) 被注釋的元素必須是一個(gè)數(shù)字,其值必須大于等于指定的最小值
- @Max(value) 被注釋的元素必須是一個(gè)數(shù)字,其值必須小于等于指定的最大值
- @DecimalMin(value) 被注釋的元素必須是一個(gè)數(shù)字,其值必須大于等于指定的最小值
- @DecimalMax(value) 被注釋的元素必須是一個(gè)數(shù)字,其值必須小于等于指定的最大值
- @Size(max=, min=) 被注釋的元素的大小必須在指定的范圍內(nèi)
- @Digits (integer, fraction) 被注釋的元素必須是一個(gè)數(shù)字,其值必須在可接受的范圍內(nèi)
- @Past 被注釋的元素必須是一個(gè)過去的日期
- @Future 被注釋的元素必須是一個(gè)將來的日期
- @Pattern(regex=,flag=) 被注釋的元素必須符合指定的正則表達(dá)式
- Hibernate Validator 附加的 constraint
- @NotBlank(message =) 驗(yàn)證字符串非null,且長(zhǎng)度必須大于0
- @Email 被注釋的元素必須是電子郵箱地址
- @Length(min=,max=) 被注釋的字符串的大小必須在指定的范圍內(nèi)
- @NotEmpty 被注釋的字符串的必須非空
- @Range(min=,max=,message=) 被注釋的元素必須在合適的范圍內(nèi)
- @URL(protocol=,host=, port=, regexp=, flags=) 被注釋的字符串必須是一個(gè)有效的url
- @CreditCardNumber 被注釋的字符串必須通過Luhn校驗(yàn)算法,銀行卡,信用卡等號(hào)碼一般都用Luhn計(jì)算合法性
- @ScriptAssert(lang=, script=, alias=) 要有Java Scripting API 即JSR 223 (“Scripting for the JavaTM Platform”)的實(shí)現(xiàn)
- @SafeHtml(whitelistType=, additionalTags=) classpath中要有jsoup包
4. 初識(shí)hibernate-validator
public class Address { @NotNull private String line1; private String line2; private String zip; private String state; @Length(max = 20) @NotNull private String country; @Range(min = -2, max = 50, message = "Floor out of range") public int floor; // getter&&setter }
二:整合校驗(yàn) hibernate-validator
該示例是在SpringMVC+FastJson整合(http://chabaoo.cn/article/139094.htm)基礎(chǔ)上進(jìn)行集成的,可以先看一下這篇文章(有源碼供下載),在該文章的基礎(chǔ)上整合hibernate-validator
整合步驟:
1、在pom.xml中引入hibernate-validator依賴
<dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-validator</artifactId> <version>5.4.1.Final</version> </dependency>
2、在[xxx]-servlet.xml中配置驗(yàn)證器:HibernateValidator
<!-- <mvc:annotation-driven> 增加驗(yàn)證器屬性validator="validator" --> <mvc:annotation-driven validator="validator"> <mvc:message-converters register-defaults="true"> <!-- 配置Fastjson 替換原來的jackson支持 --> <bean class="com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter"> <property name="supportedMediaTypes"> <list> <value>text/html;charset=UTF-8</value> <value>application/json</value> </list> </property> <property name="features"> <list> <value>QuoteFieldNames</value> <value>WriteMapNullValue</value> </list> </property> </bean> </mvc:message-converters> </mvc:annotation-driven> <bean id="validator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean"> <property name="providerClass" value="org.hibernate.validator.HibernateValidator"/> <property name="validationMessageSource" ref="messageSource"/> </bean> <bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource"> <property name="basenames"> <list> <value>classpath:conf/settings/validation</value> <value>classpath:org/hibernate/validator/ValidationMessages</value> </list> </property> <property name="useCodeAsDefaultMessage" value="false"/> <property name="defaultEncoding" value="UTF-8"/> <property name="cacheSeconds" value="60"/> </bean>
3、在src/main/resources/conf/settings位置定義驗(yàn)證消息文件描述 validation.properties
validation.common.not.null=該字段不能為空 validation.common.not.range=長(zhǎng)度非法 validation.common.format.error=格式錯(cuò)誤 validation.param.age=年齡未滿18周歲 rep.error.unknown=未知錯(cuò)誤
4、新建實(shí)體類以供測(cè)試
UserEntity
package com.mengdee.manage.validator; import javax.validation.constraints.Min; import javax.validation.constraints.NotNull; import javax.validation.constraints.Null; import javax.validation.constraints.Pattern; import org.hibernate.validator.constraints.Email; import org.hibernate.validator.constraints.Length; import org.hibernate.validator.constraints.NotBlank; public class UserEntity { @Null(groups={GroupA.class}) @NotNull(groups={GroupB.class}) @Min(value = 1, message="id值必須大于0", groups={GroupB.class}) private Long id; @NotBlank(groups={GroupA.class, GroupB.class}) @Pattern(regexp="^(?![0-9]+$)(?![a-zA-Z]+$)[0-9A-Za-z]{6,20}$", message="由6-21字母和數(shù)字組成,不能是純數(shù)字或純英文", groups={GroupA.class, GroupB.class}) private String password; @NotBlank(groups={GroupA.class, GroupB.class}) @Pattern(regexp="^((13[0-9])|(15[^4,\\D])|(18[0,3-9]))\\d{8}$", message="手機(jī)號(hào)格式不正確") private String phone; @NotBlank(groups={GroupB.class}) @Length(min=6, max=12, message="昵稱長(zhǎng)度為6到12位") private String nickname; @Min(value=18, message="{validation.param.age}") private int age; @NotBlank(groups={GroupA.class}) @Email(message="{validation.common.format.error}") private String email; @NotBlank @Length(min=3, max=10, message="{validation.common.not.range}") private String username; public UserEntity() { } public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getNickname() { return nickname; } public void setNickname(String nickname) { this.nickname = nickname; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPhone() { return phone; } public void setPhone(String phone) { this.phone = phone; } }
UserModel
package com.mengdee.manage.validator; import javax.validation.constraints.Min; import javax.validation.constraints.Pattern; import org.hibernate.validator.constraints.Email; import org.hibernate.validator.constraints.Length; import org.hibernate.validator.constraints.NotBlank; public class UserModel { @Min(value = 1, message="id值必須大于0") private long id; @NotBlank @Length(min=6, max=12, message="昵稱長(zhǎng)度為6到12位") private String nickname; @Min(value=18, message="{validation.param.age}") private int age; @NotBlank @Email(message="{validation.common.format.error}") private String email; @NotBlank @Pattern(regexp="^(?![0-9]+$)(?![a-zA-Z]+$)[0-9A-Za-z]{6,20}$", message="由6-21字母和數(shù)字組成,不能是純數(shù)字或純英文") private String password; @NotBlank @Length(min=3, max=10, message="{validation.common.not.range}") private String username; @NotBlank @Pattern(regexp="^((13[0-9])|(15[^4,\\D])|(18[0,3-9]))\\d{8}$", message="手機(jī)號(hào)格式不正確") private String phone; public UserModel() { } public long getId() { return id; } public void setId(long id) { this.id = id; } public String getNickname() { return nickname; } public void setNickname(String nickname) { this.nickname = nickname; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPhone() { return phone; } public void setPhone(String phone) { this.phone = phone; } }
UserDetail :
package com.mengdee.manage.validator; import org.hibernate.validator.constraints.NotBlank; public class UserDetail { private Long id; @NotBlank private String address; @NotBlank private String company; public UserDetail() { } public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getAddress() { return address; } public void setAddress(String address) { this.address = address; } public String getCompany() { return company; } public void setCompany(String company) { this.company = company; } }
使用ValidController 進(jìn)行測(cè)試
package com.mengdee.manage.controller; import javax.servlet.http.HttpServletRequest; import javax.validation.Valid; import org.springframework.stereotype.Controller; import org.springframework.validation.BindingResult; import org.springframework.validation.FieldError; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.ResponseBody; import com.mengdee.manage.validator.UserModel; @Controller @RequestMapping("/Valid") public class ValidController extends BaseController { // http://localhost:8081/platform-springmvc-webapp/Valid/test?age=18&nickname=mengdee&id=1&email=123@qq.com&password=root123&username=123&phone=18321758957 @RequestMapping(value = "/test", method = RequestMethod.GET) public @ResponseBody Object validation(HttpServletRequest request, @Valid UserModel user, BindingResult bindingResult){ if (bindingResult.hasErrors()) { FieldError fieldError = bindingResult.getFieldError(); return super.ResponseJsonError(fieldError); } return "ok"; } // 一個(gè)方法同時(shí)校驗(yàn)多個(gè)對(duì)象需要綁定多個(gè)結(jié)果BindingResult,出現(xiàn)一個(gè)@Valid就對(duì)應(yīng)后面聲明的一個(gè)BindingResult @RequestMapping(value = "/test2", method = RequestMethod.GET) public @ResponseBody Object validationMore(HttpServletRequest request, @Valid UserModel user, BindingResult bindingResult, @Valid UserDetail userDetail, BindingResult bindingResult2){ if (bindingResult.hasErrors()) { FieldError fieldError = bindingResult.getFieldError(); return super.ResponseJsonError(fieldError); } if (bindingResult2.hasErrors()) { FieldError fieldError = bindingResult2.getFieldError(); return super.ResponseJsonError(fieldError); } return "ok"; } }
使用注意:
1、對(duì)于多個(gè)字段,系統(tǒng)驗(yàn)證的順序好像和字段聲明的順序是不一樣的,好像是無須的
2、對(duì)于每個(gè)驗(yàn)證如果沒有message屬性,系統(tǒng)會(huì)使用默認(rèn)的,如對(duì)應(yīng)@NotBlank相當(dāng)于@NotBlank(message=”不能為空”)
3、對(duì)于引用類型如String等類型,一定要結(jié)合@NotNull、@NotEmpty或者@NotBlank來配合使用,如果不寫空的約束,經(jīng)測(cè)試,該字段是不參與校驗(yàn)的,如單獨(dú)使用@Pattern、@Length、@Email等是不會(huì)進(jìn)行驗(yàn)證的,必須要使用空的約束來限制
@Min:用于基本數(shù)據(jù)類型,如int、long等
@NotNull: 任何對(duì)象的value不能為null
@NotEmpty:集合對(duì)象的元素不為0,即集合不為空,也可以用于字符串不為null
@NotBlank:只能用于字符串不為null,并且字符串trim()以后length要大于0
三:分組校驗(yàn)@Validated
- @Valid是屬于javax.validation.Valid里的。
- @Validated是@Valid 的一次封裝,是spring提供的校驗(yàn)機(jī)制使用(org.springframework.validation.annotation.Validated) ,@Valid不提供分組功能
1. 分組的作用(使用場(chǎng)景):
每個(gè)校驗(yàn)的注解約束都有一個(gè)groups屬性,用于指定該約束是屬于哪個(gè)組的,這樣在同一個(gè)字段上就可以配置多套約束,在使用的時(shí)候只需要指定使用那套約束即可,例如對(duì)于注冊(cè)用戶和修改用戶信息時(shí),注冊(cè)時(shí)id必須為空,修改用戶信息時(shí)id必須不能為空,在使用的時(shí)候只需要將這兩種約束分配到不同的組中即可,如添加時(shí)使用組A的約束,更新時(shí)使用組B的約束
2. 分組就是一個(gè)空接口interface
GroupA 和 GroupB
package com.mengdee.manage.validator; public interface GroupA { } package com.mengdee.manage.validator; public interface GroupB { }
在使用時(shí)指定具體使用那套分組的約束@Validated({GroupA.class})
3. 組序列@GroupSequence
默認(rèn)情況下,不同組別的約束驗(yàn)證是無序的,組序列就是按照分組的前后順序依次驗(yàn)證,如先驗(yàn)證GroupA組的約束,再驗(yàn)證GroupB組的約束。如果對(duì)組的校驗(yàn)順序有要求,例如必須先校驗(yàn)A組再校驗(yàn)B組,可以使用@GroupSequence來定義每個(gè)組的順序
使用場(chǎng)景:
(1)第二個(gè)組中的約束驗(yàn)證依賴于一個(gè)穩(wěn)定狀態(tài)來運(yùn)行,而這個(gè)穩(wěn)定狀態(tài)是由第一個(gè)組來進(jìn)行驗(yàn)證的。
(2)某個(gè)組的驗(yàn)證比較耗時(shí),CPU 和內(nèi)存的使用率相對(duì)比較大,最優(yōu)的選擇是將其放在最后進(jìn)行驗(yàn)證。因此,在進(jìn)行組驗(yàn)證的時(shí)候尚需提供一種有序的驗(yàn)證方式,這就提出了組序列的概念。
一個(gè)組可以定義為其他組的序列,使用它進(jìn)行驗(yàn)證的時(shí)候必須符合該序列規(guī)定的順序。在使用組序列驗(yàn)證的時(shí)候,如果序列前邊的組驗(yàn)證失敗,則后面的組將不再給予驗(yàn)證。
使用注解GroupSequence定義組序列:GroupAB
package com.mengdee.manage.validator; import javax.validation.GroupSequence; @GroupSequence({GroupA.class, GroupB.class}) public interface GroupAB {
ValidationController
package com.mengdee.manage.controller; import javax.servlet.http.HttpServletRequest; import org.springframework.stereotype.Controller; import org.springframework.validation.BindingResult; import org.springframework.validation.FieldError; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.ResponseBody; import com.mengdee.manage.validator.GroupA; import com.mengdee.manage.validator.GroupAB; import com.mengdee.manage.validator.GroupB; import com.mengdee.manage.validator.UserEntity; @Controller @RequestMapping("/validated") public class ValidationController extends BaseController { // 校驗(yàn)時(shí)指定了GroupA,那么只校驗(yàn)約束中包含GroupA的約束,沒有包含就不校驗(yàn),例如對(duì)于phone, @NotBlank指定的分組,而@Pattern沒有指定分組,那么只校驗(yàn)空著一個(gè)約束,不校驗(yàn)手機(jī)號(hào)格式 // http://localhost:8081/platform-springmvc-webapp/validated/groupA?password=root123&phone=123 @RequestMapping(value = "/groupA", method = RequestMethod.GET) public @ResponseBody Object groupA(HttpServletRequest request, @Validated({GroupA.class}) UserEntity user, BindingResult bindingResult){ if (bindingResult.hasErrors()) { FieldError fieldError = bindingResult.getFieldError(); return this.ResponseJsonError(fieldError); } return "ok"; } // http://localhost:8081/platform-springmvc-webapp/validated/groupB?phone=123&password=root123&id=1 @RequestMapping(value = "/groupB", method = RequestMethod.GET) public @ResponseBody Object groupB(HttpServletRequest request, @Validated({GroupB.class}) UserEntity user, BindingResult bindingResult){ if (bindingResult.hasErrors()) { FieldError fieldError = bindingResult.getFieldError(); return this.ResponseJsonError(fieldError); } return "ok"; } // groupAB // http://localhost:8081/platform-springmvc-webapp/validated/groupAB?phone=111&password=root123&nickname=123&email=xxx@qq.com // @Validated({GroupA.class, GroupB.class}):GroupA和GroupB的關(guān)系是或的關(guān)系,就像數(shù)據(jù)庫中的OR一樣,只要滿足一個(gè)條件就會(huì)對(duì)該約束進(jìn)行校驗(yàn),同時(shí)使用多個(gè)組注意多個(gè)組之間沒有先后屬性之說,并不是先校驗(yàn)組A,然后再校驗(yàn)組B // 因?yàn)閕d的為空和不為空的約束都會(huì)進(jìn)行檢查,所以先注釋掉該屬性 @RequestMapping(value = "/groupAB", method = RequestMethod.GET) public @ResponseBody Object groupAB(HttpServletRequest request, @Validated({GroupA.class, GroupB.class}) UserEntity user, BindingResult bindingResult){ if (bindingResult.hasErrors()) { FieldError fieldError = bindingResult.getFieldError(); return this.ResponseJsonError(fieldError); } return "ok"; } // default // http://localhost:8081/platform-springmvc-webapp/default?email=xxx@163.com&age=18 // @Validated 如果沒有指定groups則驗(yàn)證沒有分組的屬性(此時(shí)和@Valid功能一樣),如果一個(gè)字段上有多個(gè)約束,都必須沒有指定組,如果部分約束指定的組,部分約束沒有指定約束,那么在使用@Validated時(shí)不進(jìn)行檢查的 @RequestMapping(value = "/default", method = RequestMethod.GET) public @ResponseBody Object defaultGroup(HttpServletRequest request, @Validated UserEntity user, BindingResult bindingResult){ if (bindingResult.hasErrors()) { FieldError fieldError = bindingResult.getFieldError(); return this.ResponseJsonError(fieldError); } return "ok"; } //localhost:8081/platform-springmvc-webapp/validated/sequence?phone=123&password=root123&email=123&nickname=123 // 對(duì)于一個(gè)屬性上有多個(gè)約束,并且多個(gè)約束不都在同一個(gè)組,那么在檢查的時(shí)候順序是根據(jù)GroupSequence定義的先后順序來檢查的 @RequestMapping(value = "/sequence", method = RequestMethod.GET) public @ResponseBody Object sequence(HttpServletRequest request, @Validated({GroupAB.class}) UserEntity user, BindingResult bindingResult){ if (bindingResult.hasErrors()) { FieldError fieldError = bindingResult.getFieldError(); return this.ResponseJsonError(fieldError); } return "ok"; } }
四:自定義hibernate validation注解
當(dāng)hibernate validation提供的注解不能滿足需求時(shí),可以自定義校驗(yàn)約束。
自定義注解約束步驟:
- 創(chuàng)建注解
- 創(chuàng)建注解對(duì)應(yīng)的約束驗(yàn)證類
- 使用注解
- 測(cè)試注解
創(chuàng)建注解 @Phone
package com.mengdee.manage.validator; import java.lang.annotation.Target; import javax.validation.Constraint; import javax.validation.Payload; import static java.lang.annotation.ElementType.ANNOTATION_TYPE; import static java.lang.annotation.ElementType.CONSTRUCTOR; import static java.lang.annotation.ElementType.FIELD; import static java.lang.annotation.ElementType.METHOD; import static java.lang.annotation.ElementType.PARAMETER; import static java.lang.annotation.RetentionPolicy.RUNTIME; import java.lang.annotation.Documented; import java.lang.annotation.Retention; @Target({METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER }) @Retention(RUNTIME) @Documented @Constraint(validatedBy = {PhoneConstraint.class}) public @interface Phone { String message() default "手機(jī)號(hào)格式錯(cuò)誤"; String regexp() default "^((13[0-9])|(15[^4,\\D])|(18[0,3-9]))\\d{8}$"; Class<?>[] groups() default {}; Class<? extends Payload>[] payload() default { }; @Target({ METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER }) @Retention(RUNTIME) @Documented public @interface List { Phone[] value(); } }
創(chuàng)建手機(jī)號(hào)注解對(duì)應(yīng)的約束驗(yàn)證類PhoneConstraint
package com.mengdee.manage.validator; import javax.validation.ConstraintValidator; import javax.validation.ConstraintValidatorContext; public class PhoneConstraint implements ConstraintValidator<Phone, String> { private String regexp; @Override public void initialize(Phone phoneAnnotation) { this.regexp = phoneAnnotation.regexp(); } @Override public boolean isValid(String value, ConstraintValidatorContext context) { if (value == null) { return true; // HV000028: Unexpected exception during isValid call } if (value.matches(regexp)) { return true; } return false; } }
在屬性上使用注解@Phone
package com.mengdee.manage.validator; import org.hibernate.validator.constraints.NotBlank; public class UserDetail { @NotBlank @Phone private String phone; public UserDetail() { } public String getPhone() { return phone; } public void setPhone(String phone) { this.phone = phone; } }
測(cè)試注解
// http://localhost:8081/platform-springmvc-webapp/Valid/test3?address=123&company=456&phone=123 @RequestMapping(value = "/test3", method = RequestMethod.GET) public @ResponseBody Object validationCustomAnnotation(HttpServletRequest request, @Valid UserDetail userDetail, BindingResult bindingResult){ if (bindingResult.hasErrors()) { FieldError fieldError = bindingResult.getFieldError(); return super.ResponseJsonError(fieldError); } return "ok"; }
完整代碼下載:http://xiazai.jb51.net/201804/yuanma/platform-springmvc-webapp(jb51.net).rar
總結(jié)
以上就是這篇文章的全部?jī)?nèi)容了,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,如果有疑問大家可以留言交流,謝謝大家對(duì)腳本之家的支持。
參考文章:
- hibernate validation文檔:http://docs.jboss.org/hibernate/validator/5.2/reference/en-US/html_single/#validator-customconstraints:
- 自定義注解:http://chabaoo.cn/article/139111.htm
- 深入理解Java:注解(Annotation)自定義注解入門:http://chabaoo.cn/article/35949.htm
- 使用SpringMVC的@Validated注解驗(yàn)證的實(shí)現(xiàn)
- springMVC引入Validation的具體步驟詳解
- JSP中springmvc配置validator的注意事項(xiàng)
- springmvc的validator數(shù)據(jù)校驗(yàn)的實(shí)現(xiàn)示例代碼
- SpringMVC 使用JSR-303進(jìn)行校驗(yàn) @Valid示例
- 詳解SpringMVC驗(yàn)證框架Validation特殊用法
- SpringMVC使用@Valid注解進(jìn)行數(shù)據(jù)驗(yàn)證的方法
- SpringMVC Validator驗(yàn)證示例
- SpringMvc @Valid如何拋出攔截異常
相關(guān)文章
IDEA中編寫并運(yùn)行shell腳本的實(shí)現(xiàn)
這篇文章主要介紹了IDEA中編寫并運(yùn)行shell腳本的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-08-08【Java】BigDecimal實(shí)現(xiàn)加減乘除運(yùn)算代碼
本篇文章主要介紹了【Java】BigDecimal實(shí)現(xiàn)加減乘除運(yùn)算代碼,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2017-02-02Java Swing編寫一個(gè)簡(jiǎn)單的計(jì)算器軟件
大家好,本篇文章主要講的是Java Swing編寫一個(gè)簡(jiǎn)單的計(jì)算器軟件,感興趣的同學(xué)趕快來看一看吧,對(duì)你有幫助的話記得收藏一下,方便下次瀏覽2021-12-12SpringBoot?替換?if?的參數(shù)校驗(yàn)示例代碼
Spring?Validation是對(duì)hibernate?validation的二次封裝,用于支持spring?mvc參數(shù)自動(dòng)校驗(yàn),接下來,我們以spring-boot項(xiàng)目為例,介紹Spring?Validation的使用,需要的朋友可以參考下2022-12-12IDEA創(chuàng)建yml文件不顯示小樹葉創(chuàng)建失敗問題的解決方法
這篇文章主要介紹了IDEA創(chuàng)建yml文件不顯示小樹葉創(chuàng)建失敗問題的解決方法,需要的朋友可以參考下2020-07-07SpringMVC中Model與Session的區(qū)別說明
這篇文章主要介紹了SpringMVC中Model與Session的區(qū)別說明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-12-12