生活中常为一些无伤大体之事优柔寡断,譬如买羽毛球拍是方头的还是圆头的呢?电子产品是这款好还是那款好呢?拿此又放下,举彼又放下,最后靠概率来决定。取其一,少段时间内总有些戚戚然,而后全然无所谓。小事无碍,大事可就会后悔不及,无疑亦会让许多机会径直溜去。
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 文件,内容为:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
<!DOCTYPE dwr PUBLIC "-//GetAhead Limited//DTD Direct Web Remoting 1.0//EN" "http://www.getahead.ltd.uk/dwr/dwr10.dtd"> <dwr> <allow> <create javascript="validator" creator="new"> <param name="class" value="org.apache.struts2.validators.DWRValidator"/> </create> <convert match="com.opensymphony.xwork2.ValidationAwareSupport" converter="bean"/> </allow> <signatures> <![CDATA[ import java.util.Map; import org.apache.struts2.validators.DWRValidator; DWRValidator.doPost(String,String,Map<String,String>); ]]> </signatures> </dwr> |
注意 Map<String,String> 的写法其实与泛型关系不大,DWR 里的写法,在 JVM 1.4 下照样能运行。
3) <s:head theme="ajax"> 导入 Ajax 主题的 controlheader.ftl;<s:form.../> 要设置 ajax 主题,并且设置 validate="true" 就会在输入组件失去焦点时,将输入发到服务器进行校验。
1 2 3 4 5 6 |
<s:head theme="ajax"/> <s:form action="Login" method="post" theme="ajax" validate="true"> <s:textfield name="name" label="姓名"/> <s:textfield name="pass" label="密码"/> <s:submit label="登陆"/> </s:form> |
注:没有 <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
[版权声明] 本文采用 署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0) 进行许可。
学习+收藏了..谢谢博主为我们出学者无私奉献
恩,正看了一点struts2+ajax的东西,你写得很有见地,