springMVC如何对输入数据校验实现代码

前言

数据的校验是交互式网站一个不可或缺的功能,数据验证分为客户端验证和服务器端验证。前端的js校验可以涵盖大部分的校验职责,如用户名唯一性,生日格式,邮箱格式校验等等常用的校验;但是为了避免用户绕过浏览器,使用http工具直接向后端请求一些违法数据,服务端的数据校验也是必要的,可以防止脏数据落到数据库中,如果数据库中出现一个非法的邮箱格式,也会让运维人员头疼不已,服务器端验证是整个应用阻止非法数据的最后防线,通过在应用中编程实现。
客户端验证在大多数情况下,使用 JavaScript 进行客户端验证的步骤如下:

  • 编写验证函数。
  • 在提交表单的事件中调用验证函数。
  • 根据验证函数来判断是否进行表单提交。

服务器端验证对于系统的安全性、完整性、健壮性起到了至关重要的作用。服务器端验证Spring MVC 的 Converter 和 Formatter 在进行类型转换时是将输入数据转换成领域对象的属性值(一种 Java 类型),一旦成功,服务器端验证器就会介入。也就是说,在 Spring MVC 框架中先进行数据类型转换,再进行服务器端验证。在 Spring MVC 框架中可以利用 Spring 自带的验证框架验证数据,也可以利用 JSR 303 实现数据验证。

JSR303/JSR-349,hibernate validation,spring validation之间的关系

JSR303是一项标准,JSR-349是其的升级版本,添加了一些新特性,他们规定一些校验规范即校验注解,如@Null,@NotNull,@Pattern,他们位于javax.validation.constraints包下,只提供规范不提供实现。而hibernate validation是对这个规范的实践(不要将hibernate和数据库orm框架联系在一起),他提供了相应的实现,并增加了一些其他校验注解,如@Email,@Length,@Range等等,他们位于org.hibernate.validator.constraints包下。而万能的spring为了给开发者提供便捷,对hibernate validation进行了二次封装,显示校验validated bean时,你可以使用spring validation或者hibernate validation,而spring validation另一个特性,便是其在springmvc模块中添加了自动校验,并将校验信息封装进了特定的类中。这无疑便捷了我们的web开发。本文主要介绍在springmvc中自动校验的机制。

springMVC输入数据校验实现

首先在maven项目中引入相关jar包

<!-- https://mvnrepository.com/artifact/org.hibernate/hibernate-validator -->
<dependency>
 <groupId>org.hibernate.validator</groupId>
 <artifactId>hibernate-validator</artifactId>
 <version>6.0.13.Final</version>
</dependency>
<dependency>
 <groupId>javax.validation</groupId>
 <artifactId>validation-api</artifactId>
 <version>2.0.1.Final</version>
</dependency>
<dependency>
 <groupId>javax.el</groupId>
 <artifactId>javax.el-api</artifactId>
 <version>3.0.0</version>
</dependency>

开启spring的Valid功能

<mvc:annotation-driven />

创建需要被校验的实体类

import org.hibernate.validator.constraints.Length;
import javax.validation.constraints.Email;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.Pattern;

//与数据库中users对应
public class UserInfo {
  private int id;
  @Pattern(regexp = Constants.USERNAMR, message = Constants.USERNAMRERROR)
  private String username;
  @NotBlank(message = Constants.NAMEERROR)
  private String name;
  @Email(message = Constants.EMAILERROR)
  private String email;
  @Length(min = 6, max = 16, message = Constants.PASSWORDERROR)
  private String password;
  @Pattern(regexp = Constants.PHONE, message = Constants.PHONEERROR)
  private String phoneNum;
  //...get/set方法
}

这些注解还是比较浅显易懂的,字段上的注解名称即可推断出校验内容,每一个注解都包含了message字段,用于校验失败时作为提示信息,特殊的校验注解,如Pattern(正则校验),还可以自己添加正则表达式。

JSR提供的校验注解:
@Null  被注释的元素必须为 null
@NotNull  被注释的元素必须不为 null
@AssertTrue   被注释的元素必须为 true
@AssertFalse  被注释的元素必须为 false
@Min(value)   被注释的元素必须是一个数字,其值必须大于等于指定的最小值
@Max(value)   被注释的元素必须是一个数字,其值必须小于等于指定的最大值
@DecimalMin(value) 被注释的元素必须是一个数字,其值必须大于等于指定的最小值
@DecimalMax(value) 被注释的元素必须是一个数字,其值必须小于等于指定的最大值
@Size(max=, min=)  被注释的元素的大小必须在指定的范围内
@Digits (integer, fraction)   被注释的元素必须是一个数字,其值必须在可接受的范围内
@Past  被注释的元素必须是一个过去的日期
@Future   被注释的元素必须是一个将来的日期
@Pattern(regex=,flag=) 被注释的元素必须符合指定的正则表达式  

Hibernate Validator提供的校验注解:
@NotBlank(message =)  验证字符串非null,且长度必须大于0
@Email 被注释的元素必须是电子邮箱地址
@Length(min=,max=) 被注释的字符串的大小必须在指定的范围内
@NotEmpty  被注释的字符串的必须非空
@Range(min=,max=,message=) 被注释的元素必须在合适的范围内

我们将message错误信息放在一个Constants类中

public class Constants {
  public static final String PHONE = "^1[3|4|5|7|8][0-9]{9}$";
  public static final String USERNAMR = "^NH[0-9]{7}$";

  public static final String NAMEERROR = "用户名不能为空";
  public static final String PHONEERROR = "请输入一个正确的电话号码";
  public static final String EMAILERROR= "请输入一个正确的邮箱地址";
  public static final String USERNAMRERROR = "请输入一个正确的用户编号";
  public static final String PASSWORDERROR = "密码的长度为6~16位";
  public static final String DATENOTNULL = "日期非空";
}

在@Controller中校验数据

@Valid 和 BindingResult 是一一对应的,如果有多个@Valid,那么每个@Valid后面跟着的BindingResult就是这个@Valid的验证结果,顺序不能乱

//用户添加
@RequestMapping("/save.do")
//@PreAuthorize("authentication.principal.username == 'NH1905001'")
@PreAuthorize("hasRole('ROLE_ADMIN')")
public String save(@Valid @ModelAttribute(value="userInfo") UserInfo userInfo, BindingResult result) throws Exception {
  if(result.hasErrors()){
    List<FieldError> errors = result.getFieldErrors();
    for (FieldError fieldError : errors) {

      System.out.println("错误消息提示:" + fieldError.getDefaultMessage());
      System.out.println("错误的字段是?" + fieldError.getField());
      System.out.println(fieldError);
      System.out.println("------------------------");
    }
    return "user-add";
  }else {
    userService.save(userInfo);
    return "redirect:findAll.do";
  }
}

错误对象的代表者是 Errors 接口,存储和暴露关于数据绑定错误和验证错误相关信息的接口,提供了相关存储和获取错误消息的方法,具有如下几个实现类:

  • BindingResult:代表数据绑定的结果,继承了 Errors 接口;
  • BindException:代表数据绑定的异常,它继承 Exception,并实现了BindingResult,这是内部使用的错误对象;

Errors接口中的方法

void addAllErrors(Errors var1);

boolean hasErrors();

int getErrorCount();

List<ObjectError> getAllErrors();

boolean hasGlobalErrors();

int getGlobalErrorCount();

List<ObjectError> getGlobalErrors();

@Nullable
ObjectError getGlobalError();

boolean hasFieldErrors();

int getFieldErrorCount();

List<FieldError> getFieldErrors();

@Nullable
FieldError getFieldError();

boolean hasFieldErrors(String var1);

int getFieldErrorCount(String var1);

List<FieldError> getFieldErrors(String var1);

@Nullable
FieldError getFieldError(String var1);

@Nullable
Object getFieldValue(String var1);

@Nullable
Class<?> getFieldType(String var1);

根据方法名字就可以知道方法的作用

输出的校验信息

错误消息提示:用户名不能为空
错误的字段是?name
Field error in object 'userInfo' on field 'name': rejected value []; codes [NotBlank.userInfo.name,NotBlank.name,NotBlank.java.lang.String,NotBlank]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [userInfo.name,name]; arguments []; default message [name]]; default message [用户名不能为空]
------------------------
错误消息提示:请输入一个正确的邮箱地址
错误的字段是?email
Field error in object 'userInfo' on field 'email': rejected value [111]; codes [Email.userInfo.email,Email.email,Email.java.lang.String,Email]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [userInfo.email,email]; arguments []; default message [email],[Ljavax.validation.constraints.Pattern$Flag;@462d227d,org.springframework.validation.beanvalidation.SpringValidatorAdapter$ResolvableAttribute@2a8eb300]; default message [请输入一个正确的邮箱地址]
------------------------
错误消息提示:请输入一个正确的用户编号
错误的字段是?username
Field error in object 'userInfo' on field 'username': rejected value []; codes [Pattern.userInfo.username,Pattern.username,Pattern.java.lang.String,Pattern]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [userInfo.username,username]; arguments []; default message [username],[Ljavax.validation.constraints.Pattern$Flag;@63f401ef,org.springframework.validation.beanvalidation.SpringValidatorAdapter$ResolvableAttribute@72436888]; default message [请输入一个正确的用户编号]
------------------------
错误消息提示:请输入一个正确的电话号码
错误的字段是?phoneNum
Field error in object 'userInfo' on field 'phoneNum': rejected value []; codes [Pattern.userInfo.phoneNum,Pattern.phoneNum,Pattern.java.lang.String,Pattern]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [userInfo.phoneNum,phoneNum]; arguments []; default message [phoneNum],[Ljavax.validation.constraints.Pattern$Flag;@63f401ef,org.springframework.validation.beanvalidation.SpringValidatorAdapter$ResolvableAttribute@5d528277]; default message [请输入一个正确的电话号码]
------------------------
错误消息提示:密码的长度为6~16位
错误的字段是?password
Field error in object 'userInfo' on field 'password': rejected value []; codes [Length.userInfo.password,Length.password,Length.java.lang.String,Length]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [userInfo.password,password]; arguments []; default message [password],16,6]; default message [密码的长度为6~16位]
------------------------

数据校验错误信息回显

controller处理方法的形参pojo定义的对象与此类型同名 ,首字母小写,此时spring能自动将该对象名为key,此对象作为value,保存到request中。当然,也可以通过@Valid @ModelAttribute(value=“userInfo”) UserInfo userInfo自定义名称。
modelAttribute="userInfo"中userInfo与controller方法的形参pojo定义的对象同名 。
注意页面需要引入

<%@ taglib uri="http://www.springframework.org/tags/form" prefix="form" %>
<form:form modelAttribute="userInfo" action="${pageContext.request.contextPath}/user/save.do"
  method="post">
  <!-- 正文区域 -->
  <section class="content"> <!--产品信息-->

  <div class="panel panel-default">
   <div class="panel-heading">用户信息</div>
   <div class="row data-type">

     <div class="col-md-2 title">用户名称</div>
     <div class="col-md-4 data">
      <input type="text" class="form-control" name="username"
        placeholder="用户名称" value="">
     </div>
     <div class="col-md-6 data">
      <form:errors path="username" cssStyle="color:red"/>
     </div>
     <div class="col-md-2 title">姓名</div>
     <div class="col-md-4 data">
      <input type="text" class="form-control" name="name"
         placeholder="姓名" value="">
     </div>
     <div class="col-md-6 data">
      <form:errors path="name" cssStyle="color:red"/>
     </div>
     <div class="col-md-2 title">密码</div>
     <div class="col-md-4 data">
      <input type="password" class="form-control" name="password"
        placeholder="密码" value="">
     </div>
     <div class="col-md-6 data">
      <form:errors path="password" cssStyle="color:red"/>
     </div>
     <div class="col-md-2 title">邮箱</div>
     <div class="col-md-4 data">
      <input type="text" class="form-control" name="email"
        placeholder="邮箱" value="">
     </div>
     <div class="col-md-6 data">
      <form:errors path="email" cssStyle="color:red"/>
     </div>
     <div class="col-md-2 title">联系电话</div>
     <div class="col-md-4 data">
      <input type="text" class="form-control" name="phoneNum"
        placeholder="联系电话" value="">
     </div>
     <div class="col-md-6 data">
      <form:errors path="phoneNum" cssStyle="color:red"/>
     </div>
     <div class="col-md-2 title">用户状态</div>
     <div class="col-md-4 data">
      <select class="form-control select2" style="width: 100%"
        name="status">
        <option value="0" selected="selected">关闭</option>
        <option value="1">开启</option>
      </select>
     </div>

   </div>
  </div>
  <!--订单信息/--> <!--工具栏-->
  <div class="box-tools text-center">
   <button type="submit" class="btn bg-maroon">保存</button>
   <button type="button" class="btn bg-default"
     onclick="history.back(-1);">返回</button>
  </div>
  <!--工具栏/--> </section>
  <!-- 正文区域 /-->
</form:form>

数据校验错误信息回显方法2

通过model方式在request中存储指定key与value,如下:

//改变客户到公海
@RequestMapping("/transformClients.do")
public String transformClientsById(@Valid @ModelAttribute("publicSea") PublicSea publicSea, BindingResult result, Model model) throws Exception {
  if(result.hasErrors()){
  	model.addAttribute("failueError",failueError.getDefaultMessage());
    model.addAttribute("failueDesc",publicSea.getFailueDesc());
    model.addAttribute("cNumber",publicSea.getcNumber());
    return "publicSea-change";
  }else {
    return "redirect:findAll.do";
  }
}

客户端代码

<form action="${pageContext.request.contextPath}/clients/transformClients.do"
   method="post">
  <!-- 正文区域 -->
  <section class="content"> <!--产品信息-->

   <div class="panel panel-default">
     <div class="panel-heading">跟踪失败原因</div>
     <div class="row data-type">
      <input type="text" style="display:none" name="cNumber"
         placeholder="线索Id" value="${cNumber}">
      <div class="col-md-2 title rowHeight2x">跟踪失败描述</div>
      <div class="col-md-10 data rowHeight2x">
        <textarea class="form-control" rows="3" placeholder="跟踪失败描述"
            name="failueDesc">${failueDesc}</textarea>
      </div>
      <div class="col-md-12 data rowHeight2x">
        <label>${failueError}</label>
      </div>

     </div>
   </div>
   <!--订单信息/--> <!--工具栏-->
   <div class="box-tools text-center">
     <button type="submit" class="btn bg-maroon">保存</button>
     <button type="button" class="btn bg-default"
        onclick="history.back(-1);">返回</button>
   </div>
   <!--工具栏/--> </section>
  <!-- 正文区域 /-->
</form>

分组校验

自定义校验

手动校验

基于方法校验

到此这篇关于springMVC如何对输入数据校验的文章就介绍到这了,更多相关springMVC数据校验内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • SpringMVC 数据校验方法(必看篇)

    数据校验在web应用里是非常重要的功能,尤其是在表单输入中.在这里采用Hibernate-Vapdator进行校验,该方法实现了JSR-303验证框架支持注解风格的验证. 一.导入jar包 若要实现数据校验功能,需要导入必要的jar包,主要包括以下几个: classmate-1.3.1.jar hibernate-vapdator-5.4.1.Final.jar hibernate-vapdator-annotation-processor-5.4.1.Final.jar hibernate-v

  • springmvc使用JSR-303进行数据校验实例

    项目中,通常使用较多的是前端的校验,比如页面中js校验以及form表单使用bootstrap校验.然而对于安全要求较高点建议在服务端进行校验. 服务端校验: 控制层controller:校验页面请求的参数的合法性.在服务端控制层controller校验,不区分客户端类型. 业务层service(使用较多):主要校验关键业务参数,仅限于service接口中使用的参数. 持久层dao:一般是不校验的. 环境集成 1.添加jar包: 此处使用hibernate-validator实现(版本:hiber

  • springmvc的validator数据校验的实现示例代码

    一.什么是数据校验? 这个比较好理解,就是用来验证客户输入的数据是否合法,比如客户登录时,用户名不能为空,或者不能超出指定长度等要求,这就叫做数据校验. 数据校验分为客户端校验和服务端校验 客户端校验:js校验 服务端校验:springmvc使用validation校验,struts2使用validation校验.都有自己的一套校验规则. 二.springmvc的validation校验 Springmvc本身没有校验功能,它使用hibernate的校验框架,hibernate的校验框架和orm

  • SpringMVC 数据校验实例解析

    这篇文章主要介绍了SpringMVC 数据校验实例解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 一.注解方式 二.示例 Spring MVC本身没有数据校验的功能,它使用Hibernate的校验框架来完成. 1.导入pom节点 <!-- https://mvnrepository.com/artifact/org.hibernate/hibernate-validator --> <dependency> <group

  • springMVC如何对输入数据校验实现代码

    前言 数据的校验是交互式网站一个不可或缺的功能,数据验证分为客户端验证和服务器端验证.前端的js校验可以涵盖大部分的校验职责,如用户名唯一性,生日格式,邮箱格式校验等等常用的校验:但是为了避免用户绕过浏览器,使用http工具直接向后端请求一些违法数据,服务端的数据校验也是必要的,可以防止脏数据落到数据库中,如果数据库中出现一个非法的邮箱格式,也会让运维人员头疼不已,服务器端验证是整个应用阻止非法数据的最后防线,通过在应用中编程实现. 客户端验证在大多数情况下,使用 JavaScript 进行客户

  • spring boot输入数据校验(validation)的实现过程

    项目内容 实现一个简单的用户注册接口,演示怎样进行数据校验. 要求 JDK1.8或更新版本 Eclipse开发环境 如没有开发环境,可参考 [spring boot 开发环境搭建(Eclipse)]. 项目创建 创建spring boot项目 打开Eclipse,创建spring boot的spring starter project项目,选择菜单:File > New > Project ...,弹出对话框,选择:Spring Boot > Spring Starter Project

  • Struts2的输入校验实例代码

    在我们项目实际开发中在数据校验时,分为两种,一种是前端校验,一种是服务器校验:   客户端校验:主要是通过jsp写js脚本,它的优点很明显,就是输入错误的话提醒比较及时,能够减轻服务器的负担,但是客户端校验并不是安全的,简单来讲就是防君子防不了小人.    服务器端校验:最大特点就是数据安全,但是如果只有服务器端校验,会大大增加服务器端的负担. 所以一般在我们开发中,是客户端和服务器端校验相结合作用的. 那这篇文章,我只讲服务器端校验,在Struts2支持两种校验方式: 代码校验 :在服务器通过

  • springmvc Rest风格介绍及实现代码示例

    简介 REST 即 Representational State Transfer.(资源)表现层状态转化.是目前最流行的一种互联网软件架构.它结构清晰.符合标准.易于理解.扩展方便,所以正得到越来越多网站的采用,POST, DELETE, PUT, GET 分别对应 CRUD.Spring3.0 开始支持 REST 风格的请求,是通过 org.springframework.web.filter.HiddenHttpMethodFilter 把 POST 请求转化为 PUT 和 DELETE

  • springmvc+shiro自定义过滤器的实现代码

    实现需求: 1.用户未登录,跳转到登录页,登录完成后会跳到初始访问页. 2.用户自定义处理(如需要激活),跳转到激活页面,激活完成后会跳到初始访问页. 使用到的框架 springmvc 的拦截器 shiro 自定义过滤器 实现: 1.编写拦截器通过session保存初始访问的页面地址,便于后面回跳这个页面做准备. import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.web.serv

  • vue+springmvc导出excel数据的实现代码

    vue端处理 this.$http.get(this.service + '/user/excel',{responseType: 'blob'}).then(({data})=> { console.info(typeof data) var a = document.createElement('a'); var url = window.URL.createObjectURL(data); a.href = url; a.download = '用户统计信息.xls'; a.click()

  • JS实现时间校验的代码

    常用于活动时间结束弹窗提示 注意: 1.只是JS校验时间提示,并不安全 2.前台页面的时间校验不影响后台,所以,当用户修改本地计算机时间时,可能存在不安全因素 1.直接看代码 var mydate = new Date(); var date = myDate(); function activeData(){ if(!isDateBetween(date,'2018/01/30','2018/03/31')){ //在有效时间,对应处理逻辑 }else{ //不在有效时间,对应处理逻辑 } }

  • SpringMVC中常用参数校验类注解使用示例教程

    目录 一.环境准备 二.常用的校验注解及示例 三.校验类方法中的普通参数 四.校验类方法中的自定义对象 五.关于@Valid和@Validated的区别联系 六.分组校验 七.自定义校验注解 一.环境准备 在项目中添加以下依赖 gradle org.hibernate:hibernate-validator:5.3.5.Final maven <dependency> <groupId>org.hibernate</groupId> <artifactId>

  • SpringMVC Restful api接口实现的代码

    [前言] 面向资源的 Restful 风格的 api 接口本着简洁,资源,便于扩展,便于理解等等各项优势,在如今的系统服务中越来越受欢迎. .net平台有WebAPi项目是专门用来实现Restful api的,其良好的系统封装,简洁优雅的代码实现,深受.net平台开发人员所青睐,在后台服务api接口中,已经逐步取代了辉煌一时MVC Controller,更准确地说,合适的项目使用更加合适的工具,开发效率将会更加高效. python平台有tornado框架,也是原生支持了Restful api,在

随机推荐