今天做的工程是修改之前的取消按钮,因为之前的取消按钮,通过window.history.back方法返回上一个页面,但是在工程运行过程我们发先部分页面返回的结果并不是我们要的,如,在验证时出现错误,点击取消按钮表明我们要停止这个程序的执行,返回到开始验证之前的页面,但是根据window.history.back()方法返回的是验证的第一个页面,不符合我们的需要,所以我们再取消的按钮实现点击功能是不采用onclick事件,而是一个通过链接的形式跳转到对应的controller中执行相应的方法。这个具体代码在上一次的学习中可以看到。这里主要说验证这部分,验证不再是仅仅显示某项不为空,而是有具体的验证内容,如,某一项只能为数字类型的以及长度固定多少。
在验证哪个属性时要在对应的form(或者是Bean)中找到属性值,在其上边找到相应的验证,如
@NotEmpty(field="用户ID", message="{errors.required}")
private String guestId;(这里验证了用户ID不能为空)
@Email(message="{errors.email}")
private String email;(这里验证的是email是否写正确)
@Digits(fraction = 0, integer = 11,message="{errors.qq}")
private String qq;(这里验证的qq位数只能为11为整数,fraction值指的几位小数,integer值指的是几位整数)
@Digits(fraction = 0, integer = 6,message="{errors.zip}")
@Length(min=6,max=6,message="{errors.length}")
private String zip;(这个验证的时候不仅是数字还有长度限制,仅能为6位)
@Pattern(regexp = "(([0-9]{3}[1-9]|[0-9]{2}[1-9][0-9]{1}|[0-9]{1}[1-9][0-9]{2}|[1-9][0-9]{3})-(((0[13578]|1[02])-(0[1-9]|[12][0-9]|3[01]))|((0[469]|11)-(0[1-9]|[12][0-9]|30))|(02-(0[1-9]|[1][0-9]|2[0-8]))))|((([0-9]{2})(0[18]|[2468][048]|[13579][26])|((0[48]|[2468][048]|[3579][26])00))-02-09)",message="{errors.date}")
private String orderDate;(这个是通过正则表达式验证日期的格式)
当然在使用时,我们需要在对应的Validationmessages.properties中添加对应的错误信息,如
errors.required={field}\u4e3a\u5fc5\u987b\u8f93\u5165\u9879\u76ee
errors.email=email\u683c\u5f0f\u4e0d\u6b63\u786e
errors.qq=qq\u683c\u5f0f\u4e0d\u6b63\u786e
errors.zip=zip\u5fc5\u987b\u4e3a\u6570\u5b57\u683c\u5f0f
errors.length=zip\u957f\u5ea6\u5fc5\u987b\u4e3a\u516d\u4f4d
除此之外,我们在验证时要在执行controller方法的参数中加入我们要验证的数据类型,加入这两个参数:
@Valid @ModelAttribute("cityForm") CityForm cityForm, BindingResult results
第一个是用来表名验证的对象是前台的modelAttribute的值,第二个是验证的结果,我们在方法中通过results的hasErrors方法来判断验证结果,并在错误时,返回当前页面,并显示出验证内容信息。当然这个验证通过的前台的一个<form:form>标签,这个标签是springMVC中的标签,其中的<form:input>标签有cssClass属性和cssErrorClass属性,我们可以通过设置两个样式,在出现错误时,显示出不同的样式提示出错位置。<form:errors path="name"></form:errors>即会显示模型对应属性的错误信息,当path="*"时则显示模型全部属性的错误信息,这里的<form:errors>标签是仅出现在<form:form>中的,而且这个<form:input >中的path是与后台bean对应的,为了防止命名冲突。
特别需要注意的是:视图中<form:form modelAttribute="contentModel" method="post">的modelAttribute="xxx"后面的名称xxx必须与对应的@Valid @ModelAttribute("xxx") 中的xxx名称一致,否则模型数据和错误信息都绑定不到。
关于验证的: @AssetFalse 用于验证是否为假
@AssertTrue 用于验证是否为真
@DecimalMax(value=x)用于验证注解元素的值小于等于value
@DecimalMax(value=x)用于验证注解元素的值大于等于value
@Digits(integer=整数位数, fraction=小数位数)用于验证元素的值得小数和整数位数的上限,
@Future 验证注解的元素值(日期类型)比当前时间晚(对应的有@Past)
@Max(value=x)验证元素的值小于等于max指定的value(对应的还有@Min)
@NotNull 验证元素的值不能为null(对应的有@Null)
@Pattern(regex=正则表达式, flag=)验证指定元素与正则表达式相匹配
@Size(min=最小值, max=最大值)验证注解的元素值的在min和max(包含)指定区间之内,如字符长度、集合大小
@Valid验证关联的对象,如账户对象里有一个订单对象,指定验证订单对象
@Range(min=最小值, max=最大值)验证注解的元素值在最小值和最大值之间
@NotBlank验证注解的元素值不为空(不为null、去除首位空格后长度为0),不同于@NotEmpty,@NotBlank只应用于字符串且在比较时会去除字符串的空格
@Length(min=下限, max=上限)验证注解的元素值长度在min和max区间内
@Email验证注解的元素值是Email,也可以通过正则表达式和flag指定自定义的email格式
下面的代码是jsp页面中的下拉列表的写法,注意<form:select>用path属性来识别内容,<form:options>是id,而且多了itemLabel和itemValue属性,这两个属性的值对应的Item这个类的两个属性。
<form:select path="province" itemValue="${supplierForm.province}">
<form:options id="province" items="${provinceList}" itemLabel="label" itemValue="value" />
</form:select>
与上面代码在同一个页面的文件中(文件名为editSupplier.jsp),有一个ajax的javascript的脚本文件:它的内容是实现省市的同步更新,因为对应的省包含不同的市,所以我们的方法是通过一个javascript代码发起一个post请求去执行getCity这个方法
<script src="js/bootstrap-datepicker.js"></script>
<script type="text/javascript">
$(function(){
$("#province").change(function(){
var pro=$("#province").val();
$.ajax({
type: "POST",
url: "getCity",
data: {
provinceId:pro
},
dataType: "json",
success: function(data){
$("#city").empty();
$.each(data.citys, function(index, item){
var myOption = document.createElement("option");
myOption.value = item.value;
myOption.text = item.label;
$("#city").append(myOption);
//$("#city").empty();
//$("#city").append(''+item.label+'');
});
}
});
});
});
</script>
注意对应的看getCity的controller里的内容,下面是具体的请求内容:
@RequestMapping(value = "getCity", method = RequestMethod.POST)
public @ResponseBody Map<String, List<Map<String, String>>> getCity(String provinceId) {
List<Item> cityList = itemListComponent.getCityList(provinceId);
List<Map<String, String>> list= new ArrayList<>();
for(Item item:cityList) {
Map<String, String> cityMap = new HashMap<>();
cityMap.put("value", item.getValue());
cityMap.put("label", item.getLabel());
list.add(cityMap);
}
Map<String, List<Map<String, String>>> josnMap = new HashMap<>();
josnMap.put("citys", list);
return josnMap;
}