webx-表单验证服务

表单概述

 

各种表单验证的优缺点比较
验证形式功能性网络负荷用户体验简单性可靠性
服务端批量验证简单可靠
客户端验证复杂不可靠
服务端异步验证较好复杂不可靠

 

目前,webx所提供的表单验证服务并没有实现客户端验证和服务端异步验证。

 

1.设计

(1)验证逻辑与表现逻辑分离,这样当需要修改验证规则时,只需要修改独立的配置文件就可以了。

(2)验证逻辑与应用代码分离。

2.使用表单验证服务

表单验证服务是一个基于Spring和Spring Ext的服务,可利用Schema来配置。

 

<beans:beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:services="http://www.alibaba.com/schema/services"
xmlns:fm-conditions="http://www.alibaba.com/schema/services/form/conditions"
xmlns:fm-validators="http://www.alibaba.com/schema/services/form/validators"
xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="
http://www.alibaba.com/schema/services
http://localhost:8080/schema/services.xsd
http://www.alibaba.com/schema/services/form/conditions
http://localhost:8080/schema/services-form-conditions.xsd
http://www.alibaba.com/schema/services/form/validators
http://localhost:8080/schema/services-form-validators.xsd
http://www.springframework.org/schema/beans
http://localhost:8080/schema/www.springframework.org/schema/beans/spring-beans.xsd
">
<services:form xmlns="http://www.alibaba.com/schema/services/form/validators">
<services:group name="register">
<services:field name="userId" displayName="登录名">
<required-validator>
<message>必须填写 ${displayName}</message>
</required-validator>
<regexp-validator pattern="^[A-Za-z_][A-Za-z_0-9]*$">
<message>${displayName} 必须由字母、数字、下划线构成</message>
</regexp-validator>
<string-length-validator minLength="4" maxLength="10">
<message>${displayName} 最少必须由${minLength}个字组成,最多不能超过${maxLength}个字</
message>
</string-length-validator>
</services:field>
<services:field name="password" displayName="密码">
<required-validator>
<message>必须填写 ${displayName}</message>
</required-validator>
<string-length-validator minLength="4" maxLength="10">
<message>${displayName} 最少必须由${minLength}个字组成,最多不能超过${maxLength}个字</
message>
</string-length-validator>
<string-compare-validator notEqualTo="userId">
<message>${displayName} 不能与 ${userId.displayName} 相同</message>
</string-compare-validator>
</services:field>
<services:field name="passwordConfirm" displayName="密码验证">
<required-validator>
<message>必须填写 ${displayName}</message>
</required-validator>
<string-compare-validator equalTo="password">
<message>${displayName} 必须和 ${password.displayName} 相同</message>
</string-compare-validator>
</services:field>
</services:group>
</services:form>
</beans:beans>

 

  • form代表表单验证服务的配置。
  • 每个group代表一组需要验证的字段。
  • 每个field又包含了多个验证规则(validator)。
  • 每个验证规则都包含了一段文字描述(message),如果用户填写的数据没有通过当前的规则的验证,那么用户将会看到这段文字描述。

创建表单页面需要使用一个pull tool 工具,配置如下:

<services:pull xmlns="http://www.alibaba.com/schema/services/pull/factories">
<form-tool />
...
</services:pull>


上面的配置定义了一个$form工具,可以在模板中直接使用它。

#macro (registerMessage $field)
#if (!$field.valid) $field.message #end
#end
<form action="" method="post">
<input type="hidden" name="action" value="UserAccountAction"/>
#set ($group = $form.register.defaultInstance)
<p>用户注册</p>
<dl>
<dt>用户名</dt>
<dd>
<div>
<input type="text" name="$group.userId.key" value="$!group.userId.value"/>
</div>
<div class="errorMessage">
#registerMessage ($group.userId)
</div>
</dd>
<dt>密码</dt>
<dd>
<div>
<input type="password" name="$group.password.key" value="$!group.password.value"/>
</div>
<div class="errorMessage">
#registerMessage ($group.password)
</div>
</dd>
<dt>再输一遍密码</dt>
<dd>
<div>
<input type="password" name="$group.passwordConfirm.key" value="$!
group.passwordConfirm.value"/>
</div>
<div class="errorMessage">
#registerMessage ($group.passwordConfirm)
</div>
</dd>
</dl>
<p>
<input type="submit" name="event_submit_do_register" value="立即注册!"/>
</p>
</form>


(1)创建group实例

所创建的group instance必须先在配置文件中被定义。

(2)生成表单字段

字段的名称为$group.field.key,表单验证服务会自动生成一个字段名,这个字段名被设计成仅供系统内部解读。字段的值为$!group.field.value。它的初始值是null。

 

(3)创建java代码

在HTML表单中,设置action字段,以及event_submit_do_register提交按钮,就可以让webx框架调用userAccountAction.doRegister方法。

public class UserAccountAction {
@Autowired
private FormService formService;
public void doRegister(Navigator nav) throws Exception {
Form form = formService.getForm();
if (form.isValid()) {
Group group = form.getGroup("register");
MyUser user = new MyUser();
group.setProperties(user);
save(user);
// 跳转到注册成功页面
nav.redirectTo("registerSuccess");
}
}
}


(4)用screen来读取数据

修改老数据的第一步,是要取得老数据。在webx中,这个任务是由screen来完成的。

public class UserAccount {
@Autowired
private UserManager userManager;
public void execute(Context context) throws Exception {
User user = userManager.getUser(getCurrentUser().getId());
context.put("user", user);
}
}

 

#set ($group = $form.userAccount.defaultInstance)
$group.mapTo($user)
...
<input type="hidden" name="$group.userId.key" value="$!group.userId.value"/>
...
<input type="text" name="$group.lastName.key" value="$!group.lastName.value"/>
...
#userAccountMessage ($group.lastName)
...
<input type="submit" name="event_submit_do_update" value="修改"/>

 

mapTo的功能是填充表单。

 

 

表单验证服务详解

1.基本配置

(1)Post only参数

 

<services:form postOnlyByDefault="true">
<services:group name="group1" postOnly="true" />
</services:form>

 

 

(2)Trimming参数

 

<services:form>
<services:group name="group1" trimmingByDefault="true">
<services:field name="field1" trimming="true" />
</services:group>
</services:form>


如果设置了这个参数,那么表单系统可以自动剪除字段值两端的空白字符。

 

(3)类型转换

 

<services:form converterQuiet="true">
<services:property-editor-registrar
class="com.alibaba.citrus.service.configuration.support.CustomDateRegistrar"
p:format="yyyy-MM-dd" />
</services:form>


converterQuiet=true,表示类型转换失败时,将取得默认值。当将group中的field值注入bean properties或mapTo时会引起类型转换。

 

 

 

 

 

(4)国际化

表单验证失败时,将在页面上显示错误信息。

 

  • 将错误信息直接定义在配置文件中。
  • 将错误信息定义在Spring Message Source中,从而支持国际化。
<bean id="messageSource"
xmlns="http://www.springframework.org/schema/beans"
class="org.springframework.context.support.ReloadableResourceBundleMessageSource"
p:defaultEncoding="GB18030">
<property name="basenames">
<list>
<value>form_msgs</value>
</list>
</property>
</bean>


Spring是从ResourceLoader中读取resource bundle文件的,因此,你可能需要配置Resource Loading。

(5)切分表单服务

表单验证服务支持导入多个form表单服务,从而实现分割较长配置文件的功能。

<?xml version="1.0" encoding="UTF-8" ?>
<beans:beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:services="http://www.alibaba.com/schema/services"
xmlns:beans="http://www.springframework.org/schema/beans">
<beans:import resource="inc/form_part1.xml" />
<beans:import resource="inc/form_part2.xml" />
<services:form xmlns="http://www.alibaba.com/schema/services/form/validators" primary="true">
<services:import form="part1" />
<services:import form="part2" />
...
</services:form>
</beans:beans>

(6)Group的继承和导入

<services:form>
<services:group name="baseGroup">
<services:field name="field1" >
<validator1 />
<validator2 />
</services:field>
<services:field name="field2" />
<services:field name="field3" />
</services:group>
<services:group name="subGroup" extends="baseGroup">
<services:field name="field1">
<validator3 />
</services:field>
<services:field name="field4" />
</services:group>
</services:form>

 

<services:form>
<services:group name="group1">
<services:field name="field1" />
<services:field name="field2" />
<services:field name="field3" />
</services:group>
<services:group name="group2">
<services:import group="group1" />
<services:field name="field4" />
</services:group>
<services:group name="group3">
<services:import group="group1" field="field1" />
<services:field name="field5" />
</services:group>
</services:form>

 

2.Form Tool

 

有关Form的API
API用法说明
#if($form.valid)...#end判断当前form是否验证合法,或者未经过验证
#set ($group=$form.group1.defaultInstance)取得group1的默认实例,如果不存在,则创建。
#set ($group=$form.group1.getInstance("id"))取得group1的指定id的实例,如果不存在,则创建。
#set ($group=$form.group1.getInstance("id",flase))取得group1的指定id的实例,如果不存在,则返回null
#foreach($group in $form.groups)...#end遍历当前form中所有group实例
#foreach($group in $form.getGroup("group1")) ..#end遍历当前form中所有名为group1的实例


最后欢迎大家访问我的个人网站:1024s

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值