最近在学习Java Web因为.net已经写的想吐了。通过网易云课堂了解了当前常用的SSM框架的使用方法,前期一切都很顺利,包括数据库的访问、事务提交、对象注入、面向切片等等,但是当我对页面视图进行实现时发现相对于.net有一点不方便。Java Web的视图层的实现方式非常多,常用的有JSP、FreeMarker和Thymeleaf等等,但是在验证这一块我发现都只能使用后端验证,通过例如hibernate validator之类的插件。如果想实现前端验证就只能自己写js脚本或者通过jquery validate进行配置来实现。这相对于.net来说让我觉得非常不方便,因为在.net中通过配置viewmodel中的验证标签,再通过htmlhelper类中的表单生成方法可以自动为表单组件添加前端验证规则,只要在js中引入jquery、jquery validate和微软提供的jquery validate unobtrusive就可以简单的完成表单验证的配置。
那么是否可以在Java Web中实现类似的功能呢?答案是肯定的,方法就是通过自定义标签的方法。最完美的情况当然是通过自定义标签将.net中的htmlhelper中的表单插件生成方法都实现一遍,但是这种方法开发量略大,我暂时没时间去尝试,当然理论上是绝对可行的。这里我实现了一个折中的方案,通过解析绑定了后端验证规则的viewmodel来自动生成基于jquery validate的验证脚本,从而实现前段验证脚本的自动生成和绑定,下面上代码(我这里因为使用的是FreeMarker所以提供FreeMarker的实现方法)。
首先先定义一个简单的viewmodel,并设置其验证规则,我这里使用的是hibernate validator插件,代码如下。
package com.netease.JavaFinal.web.viewmodel;
import javax.validation.constraints.Size;
import org.hibernate.validator.constraints.Length;
import org.hibernate.validator.constraints.NotEmpty;
public class RegisterEditModel {
@NotEmpty(message = "不能为空")
@Size(min = 6, max = 15, message = "请输入长度在{min}到{max}之间的字符串")
private String userName;
@NotEmpty(message = "不能为空")
@Length(min = 6, message = "不能少于{min}个字符")
private String password;
@NotEmpty(message = "不能为空")
@Length(min = 6, message = "不能少于{min}个字符")
private String confirmPassword;
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getConfirmPassword() {
return confirmPassword;
}
public void setConfirmPassword(String confirmPassword) {
this.confirmPassword = confirmPassword;
}
}
下面实现一个对各类验证Annotation的解析并生成JS验证规则和提示信息的类ValidCreator,代码如下。
package com.netease.JavaFinal.utils;
import java.lang.annotation.Annotation;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
import javax.validation.constraints.Min;
import javax.validation.constraints.Size;
import org.hibernate.validator.constraints.Email;
import org.hibernate.validator.constraints.Length;
import org.hibernate.validator.constraints.NotEmpty;
public class ValidCreator {
private Map<Class<?>, Method> creator;
public ValidCreator() throws NoSuchMethodException, SecurityException {
creator = new HashMap<Class<?>, Method>();
this.creator.put(NotEmpty.class, ValidCreator.class.getDeclaredMethod("CreateNotEmptyRule", Annotation.class));
this.creator.put(Size.class, ValidCreator.class.getDeclaredMethod("CreateSizeRule",