Unmi 的 Struts2 学习笔记(十四)

生活中常为一些无伤大体之事优柔寡断,譬如买羽毛球拍是方头的还是圆头的呢?电子产品是这款好还是那款好呢?拿此又放下,举彼又放下,最后靠概率来决定。取其一,少段时间内总有些戚戚然,而后全然无所谓。小事无碍,大事可就会后悔不及,无疑亦会让许多机会径直溜去。

1. 从此开始学习 Struts2 对 Ajax 的支持。这也是 Struts2 新注入的元素。Struts2 的 Ajax 支持是建立在 Dojo 和 DWR 基础之上的。提供了 Ajax 的输入检验,表单提交;pub-sub 事件模型、自动完成以及与 JSON 的使用等功能。

2. 在 Struts2.0.6 和 Struts2.0.11 的 apps/struts-showcase-2.x.x.war 中的 dwr 包都还是 dwr-1.1-beta-3.jar,当前 DWR 最新版是 2.0,前一个稳定版是 1.1.4,所以正式应用可用 1.1.4 版,若用 2.0 DWR 需做充分的测试。Struts2 的 Ajax 支持是建立在 ajax 主题上的,ajax 是扩展了 xhtml 主题。

3. 用 Ajax 进行输入校验有以下几个步骤(当然项目中要引入 dwr 的 jar 包):
  1) web.xml 中声明 uk.ltd.getahead.dwr.DWRServlet 对 /dwr/* 请求进行处理。
  2) 增加 WEB-INF/dwr.xml 文件,内容为:

注意 Map<String,String> 的写法其实与泛型关系不大,DWR 里的写法,在 JVM 1.4 下照样能运行。

3) <s:head theme="ajax"> 导入 Ajax 主题的 controlheader.ftl;<s:form.../> 要设置 ajax 主题,并且设置 validate="true" 就会在输入组件失去焦点时,将输入发到服务器进行校验。

注:没有 <s:head theme="ajax"/> 也能完成校验,提示信息,但有 'dojo 未定义' 错误,且提示信息不会是红色的。<s:form.../> 一定要是 theme="ajax" validate="true",否则不能作 ajax 校验。

4) 校验规则文件,规则文件的命名与提交到后端校验是一样的,所以此时 ajax 会用 LoginAction-validation.xml 中定义的规则来校验输入。

4. 试过一下把 xwork-2.0.1.jar 换成了 xwork-2.0.4.jar,结果进行 Ajax 校验时,老报 java.lang.NoClassDefFoundError: Could not initialize class com.opensymphony.xwork2.validator.ValidatorFactory,原因还不明,但 ValidatorFactory 一直都的的确确是存在,以后用时先要注意到这一点,暂用 xwork-2.0.1.jar,有时间再去查明原因。

5. 表单的 Ajax 校验未通过之前,是不能提交的,点提交按钮没反应。但是真正的表单提交后的后台校验也是必不可少的,因为 Ajax 校验并不一定可靠,在页面上总有办法改变值后不触发 onblur 事件的,幸好,Ajax 校验和提交后的检验本来用的就是同一个校验规则文件,Ajax 校验之后还会有一次更可靠的校验。

6. 使用这种 Ajax 输入校验,一旦给 <s:form.../> 加上了 theme="ajax" validate="true" 属性后就会给每个输入组件加上 onblur 事件,那要是某个输入组件不需要 ajax 校验,该如何做呢?连自己给组件加的 onblur 属性也覆盖不了 Struts2 生成的 onblur="validate(this);",处理办法有二:
  1) 在校验规则文件中不加对该字段的配置,但中间的 XMLHttpRequest 请求是少不了
  2) 单独给输入组件指定 theme="xhtml",这样风格也可以保持一致,因为 ajax 主题扩展自 xhtml 主题的。

7. 使用 Ajax 表单,如果给 <s:form.../> 指定了 theme="ajax",如果点击了 <s:submit targets="show"/> 将会以 Ajax 方式提交数据,当前页面不刷新,然后 Struts2 处理后的 result 页面的内容将会作为当前页中 ID 为 "show" 的 HTML 元素(如 <div id="show"></div>)的 innerHTML。targets 可以指定多个 ID,用逗号分隔,意味着同时更新多处。

8. 使用了 ajax 主题的 form 中,<s:submit executeScripts="true" targets="show"/>,点击这个按钮以 Ajax 提交表单,并以转向页的内容填充 ID 为 "show" 元素的 innerHTML,还能执行结果页中的 JavaScript(vbscript不执行)。最后那个结果应该只输出需要数据,不用完整的 HTML 标签。碰到一个问题是,在结果页里加了 <s:debug/> 点击提交按钮执行不到其中的 javascript 脚本。

9. 考虑一个问题,当我们要用 Ajax 对表单校验,<s:submit.../> 就会以 Ajax 方式提交数据。那如果我们的需求只是用 Ajax 对输入校验,仍以传统方式对表单提交,该如何处理呢?问题关键其实就在那个提交按钮上,<s:submit .../> 未指定 theme 属性是继承自 <s:form.../> 的 ajax 主题,只要给 <s:submit .../> 指定 theme="xhtml" 的话,风格不变,却可以用传统方式提交,这个问题和第六点是一样的。

10. 是关于 pub-sub 的理解,有些书写的模模糊糊,我会把我对此的理解记录下来,这几天有点事情太多,太累了,先占住这点,会补充的。


补充:
2008-05-27 dwr.xml 中的
    <signatures>
        <![CDATA[
            import java.util.Map;
            import org.apache.struts2.validators.DWRValidator;
            DWRValidator.doPost(String,String,Map<String,String>);
        ]]>
    </signatures>
是为了说明,DWRValidator 的 doPost 方法的参数 Map 集合中的类型,有了这个 DWR 才知道怎么处理这个参数,这是一种泛型的写法。因为 DWR 本身提供了对这种泛型写法的解析器,所以可不依赖于 JDK 1.5 开始的泛型特性。在实际使用中,如果集合 List/Map 中的元素类型(包括 Map 的 Key) 都是字符串的话,可以不配置相应的 signatures。

本文链接 https://yanbin.blog/unmi-study-struts2-14/, 来自 隔叶黄莺 Yanbin Blog

[版权声明] Creative Commons License 本文采用 署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0) 进行许可。

Subscribe
Notify of
guest

2 Comments
Inline Feedbacks
View all comments
star
16 years ago

学习+收藏了..谢谢博主为我们出学者无私奉献

creasure
16 years ago

恩,正看了一点struts2+ajax的东西,你写得很有见地,