1、Bean Validation数据校验
检测实体封装类JavaBean中的数据。
框架搭建:
spring.xml
(1)、注解配置处添加validator="validator"属性
<mvc:annotation-driven validator="myvalidator"/>
(2)、配置校验器
<bean id="myvalidator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean">
<property name="providerClass" value="org.hibernate.validator.HibernateValidator" />
<!-- 指定校验使用的资源文件,在文件中配置校验的错误信息,如果不指定则默认使用classpath下的ValidationMessages.properties -->
<property name="validationMessageSource" ref="messageSource" />
</bean>
(3)、校验错误信息配置
<bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
<!-- 资源文件名-->
<property name="basenames">
<list>
<value>classpath:ProductValidationMessages</value>
</list>
</property>
<!-- 资源文件编码格式 -->
<property name="defaultEncoding" value="UTF-8"/>
<!-- 对资源文件内容缓存时间,单位秒 -->
<property name="cacheSeconds" value="120" />
</bean>
(4)由于validator还需要检测前台传来的日期、数字类型数据是否正确,所以在conversion-service属性中还配置了一个可以将字符串转换成Date类型或数字类型的JAVA类
<mvc:annotation-driven conversion-service="myconversionservice" validator="myvalidator"/>
<bean id="conversionService" class="org.springframework.format.support.FormattingConversionServiceFactoryBean"/>
需要校验的实体类,使用注解来进行校验
public class Fruits{
//校验name和producing_area属性
@Size(min=1,max=2,message="{fruits.name.length.error}")
private String name;
@NotEmpty(message="{fruits.producing_area.isEmpty}")
private String producing_area;
...
}
错误信息配置(properties文件)
fruits.name.length.error=请输入1-20个字符的商品名称
fruits.producing_area.isEmpty=生产地址不能为空
Controller类
package cn.com.mvc.controller;
import java.util.List;
import java.util.Map;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.validation.ObjectError;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.RequestMapping;
import cn.com.mvc.model.Fruits;
import cn.com.mvc.service.FruitsService2;
import cn.com.mvc.service.FruitsServiceImpl;
@Controller
@RequestMapping("query")
public class FindControllerTest {
private FruitsService2 fruitsService=new FruitsServiceImpl();
@RequestMapping("queryFruitsByCondition")
public String queryFruitsByCondition(Model model,@Validated Fruits fruits,
BindingResult bindingResult){
//Fruits fruits=request.getParameter("fruits");
List<ObjectError> allErrors = null;
//获取校验错误信息
if(bindingResult.hasErrors()){
allErrors=bindingResult.getAllErrors();
for(ObjectError objectError:allErrors){
//输出错误信息
System.out.println(objectError.getDefaultMessage());
}
}
List<Fruits> findList=null;
if(fruits==null||
(fruits.getName()==null&&fruits.getProducing_area()==null)){
//如果fruits或查询条件为空,默认查询所有
findList=fruitsService.queryFruitsList();
}else{
//如果fruits查询条件不为空,按条件查询
findList=fruitsService.queryFruitsByCondition(fruits);
}
//将model数据传到页面
model.addAttribute("fruitsList", findList);
//response.sendRedirect("home.action");
//将错误传到页面
if(allErrors!=null){
model.addAttribute("allErrors",allErrors);
}
return "/WEB-INF/jsp/fruits/findFruits.jsp";
}
}
说一个需要注意的地方,在实体类写注解校验的时候先写校验信息再声明属性,不然就会直接将该校验引用到临近的下一个属性了。