对于Spring后台的表单验证中,我们可以通过注解的方式来完成,这种方式需要依赖于Hibernate的
hibernate-validator
包,验证方法有两种1、传统的页面跳转方式,2、Ajax的方式。Ajax的方式,现在用得是更多的
添加hibernate的检验包
这个虽然依赖的是hibernate包,但是没有用到hibernate的框架,
<!-- 表单验证 -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>4.3.1.Final</version>
</dependency>
传统方式
验证的实体类
package com.yellowcong.entity;
import javax.validation.constraints.Size;
import org.hibernate.validator.constraints.Email;
import org.hibernate.validator.constraints.NotEmpty;
/**
* 验证用户对象
* @author yellowcong
*
*/
public class User {
private String username;
private String password;
private String email;
@NotEmpty(message = "用户名不能为空")
@Size(max = 32, message = "密码最长不能超过32个字符")
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
@NotEmpty(message = "密码不能为空")
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
@Email(message = "邮箱格式不对")
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
}
后台
通过@Validated 标签,来标示User这个类的参数需要验证。BindingResult
可以获取到参数绑定的结果,同时可以获取到里面的错误信息,我们传统的直接界面跳转验证的方式,不需要获取里面的错误信息,因为框架已经将错误信息帮我们放入到了RequestContext
里面了,可以直接通过Spring的表单标签<sf:errors path="password" cssStyle="color:red"/>
来获取每个字段对应的错误信息。
package com.yellowcong.controller;
import java.util.List;
import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.validation.ObjectError;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import com.yellowcong.entity.User;
@Controller
@RequestMapping("/validate")
public class ValidateDemo {
@RequestMapping(value="/demo",method=RequestMethod.GET)
public String demoInput(@ModelAttribute("user") User user){
return "demo/validate";
}
@RequestMapping(value="/demo",method=RequestMethod.POST)
public String demo(@Validated User user,BindingResult br ){
//当数据绑定失败
if(br.hasErrors()){
//直接跳转到输入的页面
return "demo/validate";
}
//成功后,跳转到其他的页面
return "demo/test";
}
}
前台
通过Spring的表单标签<sf:errors path="password" cssStyle="color:red"/>
可以直接在界面中,获取到哪一个字段验证失败的问题。
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib uri="http://www.springframework.org/tags/form" prefix="sf"%>
<html>
<head>
<title>xx文章</title>
</head>
<body>
<!-- ${user.username} 这个访问了 用户model里面的属性 -->
<h2>${user.username} --${user.password} -${user.email}</h2>
<sf:form method="post" modelAttribute="user" action="${pageContext.servletContext.contextPath}/validate/demo">
用户名:<sf:input path="username"/><sf:errors path="username" cssStyle="color:red"/><br/>
密码:<sf:input path="password"/><sf:errors path="password" cssStyle="color:red"/><br/>
邮箱:<sf:input path="email"/><sf:errors path="email" cssStyle="color:red"/><br/>
<input type="submit" value="提交用户"/>
</sf:form>
</body>
</html>
测试结果
ajax方式
后台
后台需要注意,如何将获取到错误信息和字段,然后如何将错误信息发送到前台
package com.yellowcong.controller;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.servlet.http.HttpServletResponse;
import org.codehaus.jackson.map.ObjectMapper;
import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.validation.annotation.Validated;
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.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import com.yellowcong.entity.User;
@Controller
@RequestMapping("/validate")
public class ValidateDemo {
@RequestMapping(value="/demo",method=RequestMethod.GET)
public String demoInput(@ModelAttribute("user") User user){
return "demo/validate";
}
@RequestMapping(value="/demo",method=RequestMethod.POST)
public String demo(@Validated User user,BindingResult br ){
if(br.hasErrors()){
//获取所有字段的错误信息
List<FieldError> errors = br.getFieldErrors();
//遍历错误信息
for(FieldError error :errors){
System.out.println(error.getField()+"\t"+error.getDefaultMessage());
}
//有错误直接调回到输入 页面
return "demo/validate";
}
return "demo/validate";
}
@RequestMapping(value="/demo2",method=RequestMethod.POST)
public void demo2(@Validated User user,BindingResult br ,HttpServletResponse response) throws Exception{
//获取验证的结果
Map<String,Object> data =this.chekcInput(br);
//这个地方如果没有错误,可以做一些操作啥的。。。。看你具体业务了
//可以直接写出了
this.writeJSON(response,data);
}
/**
* 这个JSON的转化 ,依赖于jackson
* @param br
* @return
* @return
*/
public Map<String, Object> chekcInput(BindingResult br ){
//大集合,用于装返回数据对象
Map<String,Object> data = new HashMap<String, Object>();
//当存在错误的情况
if(br.hasErrors()){
//获取所有字段的错误信息
List<FieldError> errors = br.getFieldErrors();
//建立一个Map集合 用于存map集合里面的内容
Map<String,String> errorsData = new HashMap<String, String>();
//遍历错误信息
for(FieldError error :errors){
//错误的字段
String field = error.getField();
//错误信息
String msg = error.getDefaultMessage();
//System.out.println(field+"\t"+msg);
//将错误信息放到Map集合中
errorsData.put(field, msg);
}
data.put("error", true);
data.put("msg", errorsData);
}else{
//当没有错误的情况
//建立一个Map集合 用于存map集合里面的内容
data.put("error", false);
data.put("msg", "");
}
return data;
}
/**
* 在SpringMvc中获取到Session
* @return
*/
public void writeJSON(HttpServletResponse response,Object object){
try {
//设定编码
response.setCharacterEncoding("UTF-8");
//表示是json类型的数据
response.setContentType("application/json");
//获取PrintWriter 往浏览器端写数据
PrintWriter writer = response.getWriter();
ObjectMapper mapper = new ObjectMapper(); //转换器
//获取到转化后的JSON 数据
String json = mapper.writeValueAsString(object);
//写数据到浏览器
writer.write(json);
//刷新,表示全部写完,把缓存数据都刷出去
writer.flush();
//关闭writer
writer.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
前台
前台代码中,需要注意的是,将form转化为json对象,然后传递到服务器的方法
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib uri="http://www.springframework.org/tags/form" prefix="sf"%>
<html>
<head>
<title>xx文章</title>
<script type="text/javascript"
src="<%=request.getContextPath()%>/resources/plugin/jquery/jquery.min.js"></script>
<script type="text/javascript">
$(function() {
//将表单转化为JSON对象
function fromToJson(form) {
var result = {};
//获取表单的数组对象
var fieldArray = $('#' + form).serializeArray();
//将表单转化为JSON对象
for (var i = 0; i < fieldArray.length; i++) {
var field = fieldArray[i];
if (field.name in result) {
result[field.name] += ',' + field.value;
} else {
result[field.name] = field.value;
}
}
return result;
}
//点击提交
$("#sub").click(function() {
//获取到表单里面的数据
var postData = fromToJson("user");
console.log(postData);
var url = $("#project").val() + "/validate/demo2";
$.ajax({
type : "post", //使用提交的方法 post、get
url : url, //提交的地址
data : postData,
async : false, //配置是否异步操作
dataType : "json", //返回数据类型的格式
success : function(data) { //回调操作
console.log(data)
}
});
});
})
</script>
</head>
<body>
<!-- ${user.username} 这个访问了 用户model里面的属性 -->
<h2>${user.username}--${user.password}-${user.email}</h2>
<input type="hidden" id="project" value="<%=request.getContextPath()%>" />
<form id="user">
用户名:<input type="text" name="username" id="username" /> <br /> 密码:<input
type="text" name="password" id="password" /> <br /> 邮箱: <input
type="text" name="email" id="email" /> <br /> <input type="button"
id="sub" value="提交用户" />
</form>
</body>
</html>
测试结果
我们获取到后台返回的验证及结果