Webx 的表单验证服务学习经验
说说
我曾经使用过 Tornado 框架以及 Spring MVC 框架的表单系统, 他们的表单系统相当轻量级, 于是我以为 webx 框架的表单服务也差不多. 今天仔细看了一下官方文档, 发现 webx 确实有其独特的地方.
学习了表单验证, 如何写一个表单页面就没有问题了. 也并不需要先学会写一个表单然后再学表单验证服务, 直接开始学这个就OK.
验证形式
表单验证就是对用户输入的信息是否规范进行检查. 检查有三种形式:
- 数据传到服务器, 服务器在后台检查
- 数据在前端通过 js 来检查
- 通过 js 异步请求, 实现服务器异步验证.
目前 webx 框架实现了第一种形式. 后两种形式均需要在前端编写相应 js 代码方能完成. 相比之下 Tornado 框架并不自带服务端检查表单的功能, 完全需要靠 js + 后台api 来编写.
学习 webx 的表单验证服务就是学习这里的第一种形式.
webx 表单验证的特色
- 验证逻辑与表现逻辑分离
这就是说, 画表单的代码, 和对表单里面填的东西是否正确的验证代码, 是分开在不同的文件里面存放的. 这样可以多个表单共用一个验证器, 在修改验证器的时候也不会觉得两种代码杂糅在一起很烦. 我觉得这个特性非常棒!
- 验证逻辑和应用代码分离
这就是说, 验证代码也不用写在 java 文件里面. 优点同上.
这两个分离, 就是说验证代码完全独立, 既不存在于前端渲染代码中, 也不存在于后端应用的业务逻辑代码中, 而是单独出来成为一个独立的部分. 这种程度的解耦真是美好:)
极简例子
下面假设表单的 url 是 http://localhost:8080/ljw/test_1.htm, 工程基于 com.alibaba.webx.tutorial1 进行开发.
1. src/main/java/com….app1/module/screen/ljw/Test1.java
当用户发起第一次请求的时候, 此处的out会显示到网页上, 此外 vm 文件上的内容也会跟着显示出来.
public class Test1 { @Autowired private HttpServletResponse response; public void execute() throws Exception { response.setContentType("text/html"); PrintWriter out = response.getWriter(); out.print("<h1>This is from Java</h1>"); } }
2. src/main/java/com….app1/User.java
public class User { private String id; private String pwd; public String getId() { return id; } public void setId(String id) { this.id = id; } public String getPwd() { return pwd; } public void setPwd(String pwd) { this.pwd = pwd; } }
3. src/main/webapp/app1/templates/screen/ljw/Test1.vm
下面这段 vm 模板代码有好多个关键点:
- #set ($group = $form.ljw.defaultInstance) 创建一个 group 实例
- #registerMessage($group.id) 这个宏定义在用户输入错误需要返回提示的时候显示出 group.id.message 里面的内容
- $!group.id.value 这个感叹号是用来让 value 忽略 null 错误的
- <input type=”hidden” name=”action” value=”ljw_action” /> 粗体部分 ljw_action 会由webx框架转为驼峰风格 LjwAction 并交由这个 Java 类进行表单处理
- event_submit_do_ljw 这个最隐蔽, 粗体部分的下划线风格 do_ljw 会由 webx 框架转为驼峰的 doLjw 并由 LjwAction.doLjw() 处理.
#macro (registerMessage $field) #if (!$field.valid) $field.message #end #end <h2>From Template</h2> <form action="$app1Link.setTarget("ljw/Test1")" method="post"> $csrfToken.hiddenField <input type="hidden" name="action" value="ljw_action" /> #set ($group = $form.ljw.defaultInstance) #registerMessage($group.id) #registerMessage($group.pwd) <input type="text" name="$group.id.key" value="$!group.id.value"/> <input type="password" name="$group.pwd.key" value="$!group.pwd.value"/> <input type="submit" name="event_submit_do_ljw"/> #if ($id) <p> $id </p> #end </form>
4. src/main/webapp/WEB-INF/app1/form.xml
与其他的 group 并列, 加入一个新的 group, 这个一看就懂了, 什么 required 的已经自解释了. 当然除了必填项, 还支持各种各样的验证形式, 正则表达什么的, 交给 Java 判断等等. 详见官网文档.
<group name="ljw" extends="csrfCheck"> <field name="id" displayName="你的账号"> <fm-validators:required-validator> <message>必须填写 ${displayName}</message> </fm-validators:required-validator> </field> <field name="pwd" displayName="你的密码"> <fm-validators:required-validator> <message>${displayName} 还是要填的</message> </fm-validators:required-validator> </field> </group>
博主加油啊继续更新造福大家
加油加油
为毛都是水军给你评论。。。
外面没什么人用 webx