Spring MVC Annotation验证的方法
简介说明
使用spring mvc的annotation验证可以直接对view model的简单数据验证,注意,这里是简单的,如果model的数据验证需要有一些比较复杂的业务逻辑性在里头,只是使用annotation做验证是比较难的。
以下是使用spring mvc自带的annotation验证,加上自定义的一个@tel的annotation验证例子,此例子具有:
1、支持多语言(国际化)
2、对默认数据先进行转化,比如int、date类型如果传入空值时,会抛异常,默认给定值
先看配置:
1、web.xml
<?xml version="1.0" encoding="utf-8"?> <web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/xmlschema-instance" xsi:schemalocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"> <display-name>test spring mvc - 1</display-name> <context-param> <param-name>contextconfiglocation</param-name> <param-value>classpath:spring.xml</param-value> </context-param> <servlet> <servlet-name>dispatcher</servlet-name> <servlet-class>org.springframework.web.servlet.dispatcherservlet</servlet-class> <init-param> <param-name>contextconfiglocation</param-name> <param-value></param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>dispatcher</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping> <listener> <listener-class>org.springframework.web.context.contextloaderlistener</listener-class> </listener> <welcome-file-list> <welcome-file>index.jsp</welcome-file> </welcome-file-list> </web-app>
这里没什么好说的,只是把spring.xml配置加入到contextconfiglocation中
2、spring.xml
<?xml version="1.0" encoding="utf-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/xmlschema-instance" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:context="http://www.springframework.org/schema/context" xmlns:mvc="http://www.springframework.org/schema/mvc" xsi:schemalocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd"> <!--注解说明 --> <context:annotation-config /> <!-- 默认的注解映射的支持 --> <mvc:annotation-driven validator="validator" conversion-service="conversionservice" /> <!-- 把标记了@controller注解的类转换为bean --> <context:component-scan base-package="com.my" /> <!-- 视图解释类 --> <bean class="org.springframework.web.servlet.view.internalresourceviewresolver"> <property name="prefix" value="/web-inf/views/"/> <property name="suffix" value=".jsp"/><!--可为空,方便实现自已的依据扩展名来选择视图解释类的逻辑 --> <property name="viewclass" value="org.springframework.web.servlet.view.jstlview" /> </bean> <!-- 资源文件:messages.properties --> <bean id="messagesource" class="org.springframework.context.support.resourcebundlemessagesource"> <property name="basenames"> <list> <value>messages</value> </list> </property> </bean> <!-- 验证器 --> <bean id="validator" class="org.springframework.validation.beanvalidation.localvalidatorfactorybean"> <property name="validationmessagesource" ref="messagesource"/> </bean> <!-- 自定义数据类型转换器 --> <bean id="conversionservice" class="org.springframework.format.support.formattingconversionservicefactorybean"> <property name="converters"> <list> <bean class="com.my.controller.converter.intconverter" /> <bean class="com.my.controller.converter.dateconverter" /> </list> </property> </bean> </beans>
在<mvc:annotation-driven/>中加入conversion-service,然后在conversion-service中加入系统默认的转换器,如上有intconverter和dateconverter,当然,也可以是自定的别的类型,这是全局的。
在validator验证器中加入了支持多语言的properties,当然,spring的多语言是基于http header的accept-language。
3、controller
package com.my.controller; import java.util.list; 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.modelattribute; import org.springframework.web.bind.annotation.requestmapping; import org.springframework.web.bind.annotation.requestmethod; import org.springframework.web.servlet.modelandview; import com.my.controller.bean.user4; @controller @requestmapping(value="av") public class testannotationvalidcontroller { @requestmapping public modelandview index() { modelandview view = new modelandview("/testannotationvalid/index", "user4", new user4()); return view; } @requestmapping(value="/add", method=requestmethod.post) public modelandview add(@modelattribute @valid user4 user, bindingresult result) { modelandview view = new modelandview("/testannotationvalid/index"); view.addobject("user4", user); if(result.haserrors()) { list<fielderror> errors = result.getfielderrors(); for(fielderror err : errors) { system.out.println("objectname:" + err.getobjectname() + "\tfieldname:" + err.getfield() + "\tfieldvalue:" + err.getrejectedvalue() + "\tmessage:" + err.getdefaultmessage() + "\tcode:"); } } return view; } }
这是一个简单的controller,在add中,有一个@valid的annotation,这是必需的,不加这个,annotation验证将不起作用
4、user4.java model实体类
package com.my.controller.bean; import java.util.date; import javax.validation.constraints.max; import javax.validation.constraints.min; import javax.validation.constraints.notnull; import javax.validation.constraints.past; import javax.validation.constraints.pattern; import javax.validation.constraints.size; import org.hibernate.validator.constraints.email; import org.hibernate.validator.constraints.length; import org.hibernate.validator.constraints.notblank; public class user4 { private long id; @notblank(message="{valid.name}") private string name; @length(min=4, max=20, message="{valid.password}") private string password; @notblank(message="{valid.required}") @email(message="{valid.email}") private string email; @notnull(message="{valid.required}") private boolean married; @min(value=18, message="{valid.agemin}") @max(value=100, message="{valid.agemax}") private int age; @notnull(message="{valid.required}") @past(message="{valid.birthday}") private date birthday; @pattern(regexp="^[a-za-z]{2,}$", message="{valid.address}") private string address; @size(min=1, message="{valid.likesmin}") private string[] likes; @com.my.controller.validator.tel(message="{valid.tel}", min=3) private string tel; public long getid() { return id; } public void setid(long id) { this.id = id; } public string getname() { return name; } public void setname(string name) { this.name = name; } public string getpassword() { return password; } public void setpassword(string password) { this.password = password; } public string getemail() { return email; } public void setemail(string email) { this.email = email; } public boolean ismarried() { return married; } public void setmarried(boolean married) { this.married = married; } public int getage() { return age; } public void setage(int age) { this.age = age; } public date getbirthday() { return birthday; } public void setbirthday(date birthday) { this.birthday = birthday; } public string getaddress() { return address; } public void setaddress(string address) { this.address = address; } public string[] getlikes() { return likes; } public void setlikes(string[] likes) { this.likes = likes; } public string gettel() { return tel; } public void settel(string tel) { this.tel = tel; } }
除了@tel之外,其它都是spring自带的annotation,当然还有别的,自行搜索下
5、message.properties
valid.required=字段值不能为空 valid.name=用户名不能为空 valid.password=密码最小4位 valid.agemin=年龄不能小于{1}岁 valid.agemax=年龄不能大于{1}岁 valid.email=邮箱格式不正确 valid.address=联系地址不正确 valid.birthday=生日不能大于今天 valid.likesmin=喜好最小不能小于1个 valid.tel=手机号码不能小于{min}位
对应的是user4 model的annotation的message值。如果需要国际化的多语言,只需要加入多一个messages_en_us.properties这样名字的文件即可。
6、@tel
package com.my.controller.validator; import java.lang.annotation.elementtype; import java.lang.annotation.retention; import java.lang.annotation.retentionpolicy; import java.lang.annotation.target; import javax.validation.constraint; import javax.validation.payload; @target({elementtype.field, elementtype.method}) @retention(retentionpolicy.runtime) @constraint(validatedby=telvalidator.class) public @interface tel { int min() default 0; string message(); class<?>[] groups() default {}; class<? extends payload>[] payload() default {}; }
新建一个interface,注意,annotation的interface java是这样写的:@interface
telvalidator:
package com.my.controller.validator; import javax.annotation.resource; import javax.validation.constraintvalidator; import javax.validation.constraintvalidatorcontext; import org.springframework.context.support.resourcebundlemessagesource; public class telvalidator implements constraintvalidator<tel, string> { @resource private resourcebundlemessagesource messagesource; private tel tel; @override public void initialize(tel tel) { this.tel = tel; } @override public boolean isvalid(string value, constraintvalidatorcontext constraintcontext) { boolean isvalid; if(value != null && value.length() >= tel.min()) { isvalid = true; } else { isvalid = false; } if(!isvalid) { constraintcontext.disabledefaultconstraintviolation(); constraintcontext.buildconstraintviolationwithtemplate(tel.message()).addconstraintviolation(); } return isvalid; } }
这是@tel的验证实现方法。
7、converter
package com.my.controller.converter; import org.springframework.core.convert.converter.converter; public class intconverter implements converter<string, integer> { @override public integer convert(string text) { if (text == null || "".equals(text)) { return 0; } else { try { integer value = integer.parseint(text); return value; } catch (exception e) { return 0; } } } }
package com.my.controller.converter; import java.text.parseexception; import java.text.simpledateformat; import java.util.date; import org.springframework.core.convert.converter.converter; public class dateconverter implements converter<string, date> { @override public date convert(string text) { simpledateformat dateformat = new simpledateformat("yyyy-mm-dd"); dateformat.setlenient(false); try { return dateformat.parse(text); } catch (parseexception e) { e.printstacktrace(); } return null; } }
这两个是全局的类型默认转换器。
8、测试jsp
<%@ page language="java" contenttype="text/html; charset=utf-8" pageencoding="utf-8"%> <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> <%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt"%> <%@ taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn" %> <%@ taglib prefix="st" uri="http://www.springframework.org/tags" %> <%@ taglib prefix="sf" uri="http://www.springframework.org/tags/form"%> <!doctype html public "-//w3c//dtd html 4.01 transitional//en" "http://www.w3.org/tr/html4/loose.dtd"> <html> <head> <meta http-equiv="content-type" content="text/html; charset=utf-8"> <title>index</title> </head> <body> <sf:form action="${pagecontext.request.contextpath}/av/add" method="post" modelattribute="user4"> user name:<sf:input path="name"/><sf:errors path="name" /><br/> password:<sf:input path="password"/><sf:errors path="password" /><br/> e-mail:<sf:input path="email"/><sf:errors path="email" /><br/> age:<sf:input path="age"/><sf:errors path="age" /><br/> birthday:<sf:input path="birthday"/><sf:errors path="birthday" /><br/> address:<sf:input path="address"/><sf:errors path="address" /><br/> married: <sf:radiobutton path="married" label="yes" value="true"/> <sf:radiobutton path="married" label="no" value="false"/> <sf:errors path="married" /><br/> likes: <sf:checkbox path="likes" label="football" value="football"/> <sf:checkbox path="likes" label="badminton" value="badminton"/> <sf:checkbox path="likes" label="pingpong" value="pingpong"/> <sf:errors path="likes" /><br/> tel:<sf:input path="tel"/><sf:errors path="tel" /><br/> <input type="submit" value="add" /> <hr/> errors:<br/><sf:errors path="*"></sf:errors> <hr/> likes:<c:foreach items="${user4.likes}" var="item">${item},</c:foreach> </sf:form> </body> </html>
注意,在form中的modelattribute属性值,它对应的是user4类名,小写开头,否则会出错
9、页面ui结果:
点击add button后:
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。