表单数据的检验是应用程序必不可少的组成部分,通常来讲,表单数据的校验分为前台校验和后台校验两部分,前台校验使用JS脚本在提交数据前进行校验,后台校验在数据提交后进行校验。
出于安全性的考虑,后台校验是必不可少的,当因为某种原因前台校验失效的情况下,由于有后台校验的存在,仍能保证提交数据的合法性和有效性。
后台校验有许多种方法,有基于配置文件的校验,有基于注释的校验等等,也有许多成熟的校验框架可以使用。本文向大家介绍一种基于Hibernate元数据的校验方法,笔者曾在多个项目中使用,效果非常好,在这里与大家分享。
应用本文提到的校验方法前应该满足以下几点:
- 该程序持久层使用Hibernate。
- 页面上的表单与数据库表有对应关系,且表单数据字段名与数据库字段名一致。
- 最好使用了Spring。
另外,使用基于Hibernate元数据的校验只能保证校验到字段是否为空、数据类型是否正确、字段长度是否符合三种规则。由于本文提到的方法是采用拦截器的方式在业务层前置进行校验,所以与其它的校验工具之间并不冲突,可以形成有效互补。
public class ValidationInterceptor extends HandlerInterceptorAdapter {
@Resource(name = "&sessionFactory")
private LocalSessionFactoryBean sessionFactory;
@Override
@SuppressWarnings("unchecked")
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
final String uri = request.getRequestURI();
//通过请求的URI找到对应的校验实体类,这个需要在外部进行配置
final String entityName = getValidation(uri);
//没有配置说明这个请求不需要校验
if (entityName == null)
return true;
//通过实体名返回Hibernate的PersistentClass
final PersistentClass clazz = sessionFactory.getConfiguration().getClassMapping(entityName);
//对应的表的元数据
final Table table = clazz.getTable();
final Iterator<Column> iterator = table.getColumnIterator();
final Map<String, String> errors = new HashMap<String, String>();
while (iterator.hasNext()) {
//对应的列的元数据
final Column column = iterator.next();
//列名
final String name = column.getName();
//这是数据库列映射到JAVA中的属性
final Property property = clazz.getProperty(name);
//这是前台表单提交上来的值
final String value = request.getParameter(name);
//如果值为空,跳过该字段的校验
if (value == null)
continue;
//校验非空
if (!column.isNullable() && "".equals(value.trim())) {
errors.put(name, "字段"+name+"的值不能为空!");
}
//校验字符串长度
else if (property.getType() instanceof StringType) {
if (value.length() > column.getLength()) {
errors.put(name, "字段"+name+"的值超长了!");
}
}
//校验日期类型
else if (property.getType() instanceof DateType) {
final SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
try {
format.parse(value);
} catch (Exception e){
errors.put(name, "字段"+name+"必须是日期类型!");
}
}
//校验数字类型,包括浮点数
else if (property.getType() instanceof BigDecimalType) {
int precision = column.getPrecision();
int scale = column.getScale();
int front = precision - scale;
String patten = "";
for (int i = 0; i < front; i++) {
patten += "#";
}
if (scale > 0) {
patten += ".";
for (int i = 0; i < scale; i++) {
patten += "#";
}
}
final NumberFormat format = new DecimalFormat(patten);
try {
format.parse(value);
} catch (Exception e) {
errors.put(name, "字段"+name+"必须是数字类型("+patten"+")!");
}
}
}
//如果没有错误,直接放行
if (errors.isEmpty())
return true;
//有错了,生成描述错误信息的JSON串,返回前台
response.setContentType("text/json;charset=UTF-8");
response.getWriter().write(JSONObject.fromObject(errors).toString());
response.getWriter().close();
return false;
}
}
每个URL需要映射一下校验数据使用的实体类,可以使用一个Propertes文件进行配置,上代码中的getValidation方法需要从这个配置文件中取信息。
/test/save_log.do=com.coolfancy.blog.entity.Log
/test/save_reply.do=com.coolfancy.blog.entity.Reply
使用这个方法后,基于数据库元数据的校验就不需要再在程序中写了,使用这个拦截器就全搞定了,如果有其它复杂的校验,可以在Action中使用原来的校验方法继续校验。
分享到:
相关推荐
基于hibernate_validator的异步表单校验框架依赖文件
包含hibernate-valdator等用于数据校验所需要的基本jar包。
springmvc 使用hibernate-validator校验框架所需的校验包
Hibernate Validator校验框架学习
Struts与Hibernate实用教程构建基于MVC模式的高效Java Web应用例子代码 (1),共10个例子
在Java SE中使用Hibernate处理数据
使用Hibernate缓存数据.ppt
hibernate后台数据校验所需要的三个完整jar包,三个jar包需要一起使用,版本号要对应。
Eclipse上使用Hibernate synanize Eclipse上使用Hibernate synanize Eclipse上使用Hibernate Eclipse上使用Hibernate
hibernate校验 jar包
Hibernate学习笔记,使用Hibernate做数据层非常方便
很多人都对Java在批量数据的处理方面是否是其合适的场所持有怀疑的念头,由此延伸,...下面以Hibernate为例来做为说明,假如我们真的不得不在Java中使用Hibernate来对数据进行批量处理的话。 向数据库插入100 000条数据
hibernate入门数据简单插入
Hibernate-Validate参数校验
主要介绍了SpringBoot 使用hibernate validator校验,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
Spring+MyBatis+Spring和MyBatis整合jar包+MySql驱动包+hibernate校验所须jar包
spring 集成hibernate实现多数据的动态切换功能,有详细的代码 可以参考 基于maven工程
springmvc的服务器表单校验所需要的jar包,分别为:classmate.jar、classmate.jar、hibernate-validator-annotation-processor-5、hibernate-validator-annotation-processor-5、validation-api-1.1.0.jar
自己做的struts2+hibernate整合实现登录注册功能,
Hibernate中数据类型,涵盖了所有数据库的字段类型与Java基本类型间的映射关系