使用Hibernate元数据构建表单校验功能

来源:互联网 发布:二端口阻抗参数 编辑:程序博客网 时间:2024/06/05 04:20

      表单数据的检验是应用程序必不可少的组成部分,通常来讲,表单数据的校验分为前台校验和后台校验两部分,前台校验使用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的PersistentClassfinal 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中使用原来的校验方法继续校验。

      更多精彩原创文章请关注笔者的原创博客:http://www.coolfancy.com



原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 百度网盘上传文件数量有限制怎么办 腾讯视频上传文件过限制大小怎么办 三星s7打网页又卡又慢怎么办 路由器的上网账号和口令忘了怎么办 小米笔记本移动热点连接不上怎么办 移动宽带密码重置后认证失败怎么办 移动光纤不记得账号和密码怎么办? 宽带为什么交了钱还是不能用怎么办 小孩被虎牙直播诱导支付了款怎么办 房间里4g网络信号差怎么办 移动4g网络信号不满格怎么办 大风号无法上传视频暂停服务怎么办 过了竞牌保证金交付时间怎么办 亚马逊产品上架后货物没到怎么办 工行企业网银证书过期了怎么办 海淘转运地址国家填错了怎么办 集装箱实重与申报重量不一样怎么办 微博复制的淘口令找不到了怎么办 买了移动手机不能用联通卡怎么办 移动手机用联通卡网速慢怎么办 移动手机插联通卡没反应怎么办 移动手机办了联通大王卡怎么办 qq被冻结但是有至尊宝怎么办 qq被冻结了有至尊宝怎么办 移动电话卡注销了里面的钱怎么办 罗麦的oa上经理喜报没截图怎么办 工行融e联登录密码忘了怎么办 融e借有额度秒拒怎么办 工行银行柜台办理融e借怎么办 地球末日生存破解版金币没了怎么办 手机被别人骗走了里面的微信怎么办 在微信里面被做微商的骗了钱怎么办 在qq上骗了人50怎么办 被3m多酶清洗液滴到皮肤怎么办 做3m赔了9万怎么办 在携程网上订的酒店发票怎么办 滴滴滴取消订单电话打不通怎么办 百度云容量2068g满了怎么办 淘宝电脑端描述图片间隔大怎么办 手机上下载游戏自动扣费怎么办 苹果手机下载游戏自动扣费怎么办