利用strut2标签自动生成form前端验证代码,使用到的技术有
1.struts2标签,如<s:form>
<s:textfieled>
2.struts2读取*Validation.xml文件(*为Action名字),
org.apache.struts2.components.Form.findFieldValidators(String
name, Class actionClass, String actionName, List<Validator> validatorList,
List<Validator> retultValidators, String
prefix)
这是在freemarker解析form-close.ftl文件(<#assign
validators=tag.getValidators("${tagName}")>)是调用的,获取关于某个输入控件的所有验证,如非空验证/长度验证
3.在void
org.apache.struts2.components.UIBean.evaluateParams()方法中,会解析Form标签下的所有输入控件标签,
如<s:textfield>,<s:textarea>,主要是得到输入控件的name属性值,并存放在Map<String,
Object>
org.apache.struts2.components.Component.parameters这个属性中(Form.java继承与Component),
4.Freemarker解析form-close.ftl文件,主要做的工作是
遍历Map<String,
Object>
org.apache.struts2.components.Component.parameters字段,得到某个输入控件的tagName,
通过调用Form.findFieldValidators得到关于该输入控件的所有验证(如非空/长度/范围等)
5.解析form-close.ftl可能生成的代码如下形式,使用了jquery-validation插件:
---------------------------------开始------------------------------------------
</form>
<script
type="text/javascript">$(function() { //最大提示信息数 var maxTips = 10; //
validate form on keyup and submit var formElement =
$("#submitDeviceManagementAdd"); //是否正在提交 var isSubmitting = false;
formElement.validate({ rules: { "device.dimensionNo":{ trim:‘true‘,
minlength:1, maxlength:20 ,customValidation: true }
,"device.assetsNo":{ trim:‘true‘, minlength:1,
maxlength:25 ,customValidation: true } ,"device.buildingName":{
required: true, minlength:0 ,customValidation: true }
,"device.brandName":{ required: true, minlength:0 ,
trim:‘true‘, minlength:1, maxlength:50 ,customValidation:
true } ,"device.deviceModel":{ required: true,
minlength:0 , trim:‘true‘, minlength:1, maxlength:128
,customValidation: true } ,"device.ipv4":{ trim:‘true‘,
minlength:1, maxlength:200 ,customValidation: true }
,"device.macAddress":{ trim:‘true‘, minlength:1,
maxlength:128 ,customValidation: true } ,"device.remark":{
trim:‘true‘, minlength:1, maxlength:2000
,customValidation: true } }, messages: { "device.dimensionNo":{
minlength:"二维码编号的长度只能是1到20个字符!", maxlength:"二维码编号的长度只能是1到20个字符!"
,customValidation: ‘_customValidationMessage‘ } ,"device.assetsNo":{
minlength:"固定资产编号的长度只能是1到25个字符!", maxlength:"固定资产编号的长度只能是1到25个字符!"
,customValidation: ‘_customValidationMessage‘ }
,"device.buildingName":{ required: "使用单位是必填项!" ,customValidation:
‘_customValidationMessage‘ } ,"device.brandName":{ required:
"品牌是必填项!" , minlength:"品牌的长度只能是1到25个字符!",
maxlength:"品牌的长度只能是1到25个字符!" ,customValidation:
‘_customValidationMessage‘ } ,"device.deviceModel":{ required:
"设备型号是必填项!" , minlength:"设备型号的长度只能是1到128个字符!",
maxlength:"设备型号的长度只能是1到128个字符!" ,customValidation:
‘_customValidationMessage‘ } ,"device.ipv4":{
minlength:"IP地址的长度只能是1到100个字符!", maxlength:"IP地址的长度只能是1到100个字符!"
,customValidation: ‘_customValidationMessage‘ } ,"device.macAddress":{
minlength:"MAC地址的长度只能是1到128个字符!", maxlength:"MAC地址的长度只能是1到128个字符!"
,customValidation: ‘_customValidationMessage‘ }
,"device.remark":{ minlength:"备注的长度只能是1到1000个字符!",
maxlength:"备注的长度只能是1到1000个字符!" ,customValidation:
‘_customValidationMessage‘ } }, errorPlacement: function(error,
element) { // Set positioning based on the elements position
in the form var elem = $(element); if
(elem.attr(‘type‘) == ‘hidden‘) { var widgetName =
elem.attr(‘name‘) + ‘_widget‘; elem = elem.next("input[name=" +
widgetName + "]"); } // Check we
have a valid error message if(!error.is(‘:empty‘)) {
elem.addClass(‘add_error_border‘); var show =
elem.qtip(‘api‘) != undefined; // Apply the
tooltip only if it isn‘t valid elem.filter(function() {
if ($(this).hasClass(‘ui-autocomplete-input‘) ||
!$(this).hasClass(‘valid‘)) { $(this).removeClass(‘valid‘);
return true; } else return false;
}).qtip({ overwrite: false,
content: error, position: { my: ‘left
bottom‘, at: ‘right top‘ },
show: { event: ‘mouseenter‘,
ready: true, persistent: false },
hide: false, style: { classes:
‘ui-tooltip-red‘ // Make it red... the classic error colour!
}, events: { show: function(event, api) { var
currentTips = formElement.data(‘currentTips‘); if (typeof currentTips ==
‘undefined‘) { currentTips = 0; } if (++currentTips <=
maxTips) { formElement.data(‘currentTips‘, currentTips);
_timer.call(api.elements.tooltip, event); } else { return false;
} }, hide: function(event, api) {
var currentTips = formElement.data(‘currentTips‘); if (typeof
currentTips != ‘undefined‘) { if (--currentTips < 0) {
currentTips = 0; }
formElement.data(‘currentTips‘, currentTips); } }
} }) // If we have a tooltip on this element
already, just update its content .qtip(‘option‘, ‘content.text‘,
error); if (show) { elem.qtip(‘show‘);
} } // If the error is empty, remove the
qTip else { if(elem.hasClass(‘add_error_border‘)){
elem.toggleClass(‘add_error_border‘); }
elem.qtip(‘destroy‘); formElement.data(‘currentTips‘, 0);
} }, success: $.noop, // Odd workaround for errorPlacement
not firing! submitHandler: function(form) { if
(isSubmitting) { alert("请勿重复提交表单!"); } else {
isSubmitting = true; form.submit(); } }, focusInvalid:
false, debug: false }); $.validator.addMethod("trim",
function(value, element, params) { if (params.trim === ‘true‘) {
$(element).val($.trim($(element).val())); } return true; });
$.validator.addMethod("customValidation", function(value, element, params) {
var result = true; return true; });
});</script>
---------------------------------结束---------------------------------------------
原文:http://www.cnblogs.com/wenwujuncheng/p/3558989.html