Struts2 调整 JQuery 开发 Web应用程序

Struts2 整合 JQuery 开发 Web应用程序
眼下很多Web项目都是选择 Struts2 作为表现层。 在09年底我去过阿里几个部门面试,无一例外都提到了这个框架。

Struts2 能够这么快就让众多程序员放下Struts1的原因在于它的许多更优异的改进之外, 还有一方面就是它的插件体系。

本文要讲的就是运用插件,Struts2可以和Jquery 完美结合。

我假定你已经在你的项目中选择了Struts2,你的项目中会有一些表单需要作前端验证, 比如登录表单, 注册表单等等, 甚至, 你还想加一些Ajax进去, 这一切, Struts2和它的JQuery 插件可以帮你搞定。

Okay, 在讲这些之前, 可以先看看Jquery 插件的 Show case, 以印证我之前提到的所谓的完美。

http://www.weinfreund.de/struts2-jquery-showcase/index.action


接下来我分几个步骤一步步讲如何将Struts2 与 jquery 两者整合。


第一步:引入Struts2-Jquery 插件

如果你的项目是基于Maven开发, 则在你的pom.xml里面加入

		<dependency>
			<groupId>com.jgeppert.struts2.jquery</groupId>
			<artifactId>struts2-jquery-plugin</artifactId>
			<version>2.0.0</version>
		</dependency>






第二步:在表单中使用Jquery 组件画一个日期控件

要用JQuery 画 UI控件, 就要在jsp 页面中引入Jquery 相关的的JS文件, 使和Struts2-Jquery 插件会使这一步变得很简单。

1. 在jsp页面引入 struts2 Jquery 标签, 如下:
<%@ taglib prefix="sj" uri="/struts-jquery-tags"%>

2. 在<head></head> 之间加入Jquery头标签, 实际上这个标签的作用就是帮你引入Jquery 的相关js 文件, 同时, 初始化一些配置信息:
<sj:head locale='en' jqueryui="true"/>


3. 在表单里面放入你想放的日期控件, 并打开网页查看效果。

<sj:datepicker id="date0" label="Select a Date" />



第三步: 中文

我相信你在完成第二步的时候已经开始查看你的页面效果了, 你是不是看到了一个日期控件? 可惜它是英文的, 如果你不是在做外包, 估计你还得往下看。


在第二步时, 我在<head></head> 之间加入Jquery头标签已经定义了接下来展示的控件是英文的。

<sj:head locale='en' jqueryui="true"/> 中的 locale='en' 就表示要使用英文展示控件内容, 将它变成 locale='zh_CN' 使表示要展示的是简体中文内容的控件啦。


可是, 别急。 你得注意一下你的网页字符格式, 它是UTF-8吗? 如果是, 恭喜你完工了, 打开网页你就可以看到一个中文化的日期控件。

可是现实很残酷, 在中国的软件公司做中国的项目, 数据库里存的尽是GB2312, 说是为了节省空间, 好像这年头最贵的不是程序员工资而是服务器硬盘。 网页打开的格式也基本要求是GB2312或GBK。


这给Java程序员引入开源带来不少麻烦, 因为老外它就认UTF-8, 在Struts2-JQuery 插件里面存的js格式也是UTF-8的。

在GBK格式的网页里面一引入带中文字符的UTF-8格式的js文件就会出js错误。

办法:

在Struts2-Jquery 插件里面有两个带中文字符的js文件,分别是 template/i18/grid.locale-zh-CN.js 和 template\i18n\jquery.ui.datepicker-zh-CN.min.js 把它们拉出来, 改为GB2312的。 存到class目录的 template/i18n 目录下。 根据class加载顺序, 应当会将class目录下的两个文件载入, struts2-Jquery.jar 目录中的两个js文件会被忽略。



好了, GBK格式的网页的麻烦也没有啦。



第四步:表单验证


服务器当然也可以完成验证工作, 而表单客户端验证其实是变相的把一部分计算让客户端来承担。

打开以下链接, 可以看到Jquery validation 的 Demo
http://bassistance.de/jquery-plugins/jquery-plugin-validation/

Jquery 的验证框架整合到 Struts2 中非常easy.

如下:

在JSP的head 中引入 javascript 文件。

http://IP/app/js/jquery.validate.min.js

另加一段Javacript
  <script>
  $(document).ready(function(){
    $("#formId").validate();
  });
  </script>


假设你的表单项如下:

<form id="formId">
<input type="text" name="username" />
<input type="submit" value="提交" />
</form>


这样就说明, 你的验证框架已经和 fromId 这个表单建立了关联, 假设你想把 表单项 username  设置为必填项, username 表单项改为如下:

<input type="text" name="username" class="required"/>

好了, 这时候,你点击提交按钮的时候便会提示 usrename is required.




第五步: Ajax 提交

struts-jquery 插件提供了ajax 的表单提交按钮。

    <s:form id="form" action="echo" theme="simple" cssClass="yform">
        <fieldset>
            <legend>AJAX Form</legend>
	        <div class="type-text">
	            <label for="echo">Echo: </label>
	            <s:textfield id="echo" name="echo" value="Hello World!!!"/>
	        </div>
	        <div class="type-button">
	            <sj:submit targets="formResult" value="AJAX Submit" />

	        </div>
        </fieldset>
    </s:form>
<div id="formResult"></div>


以上的代码表示提交到服务器之后, 服务器返回的内容将展示到id为formResult的div上。


第六步:整合验证框架与ajax 提交按钮

加了ajax提交按钮之后, 你会发现原有的验证已经不起作用了。 这一点我觉得可能是struts2-jquery插件的一个Bug, 事实上可能是表单在提交之前, 没有去调用onsubmit方法。

不过没有关系, 我们只要在提交之前手工调用一下验证方法即可。

如下:

将之前的
<sj:submit targets="formResult" value="AJAX Submit" />

改为

<sj:submit targets="formResult" value="AJAX Submit" onBeforeTopics="beforeForm"
/>

注册beforeForm逻辑
    $.subscribe('beforeForm', function(event,data) {
		var validatorResult = validator.form();
		if(validatorResult){
			event.originalEvent.options.submit = true;
		}else{
			event.originalEvent.options.submit = false;
		}
    });


这样, 就可以做到提交之前, 先验证一下表单内容啦。


第七步:还是中文

如果你刚好是用utf-8的网页格式, 你不会有任何问题。但如果不是, 则意味着你的表单内容将通过utf-8格式传输到服务器(ajax就是这样子, 即使在tomcat 里面在server.xml 里面将 charset="GBK"也没用)

我之前看到过有博友提到过的解决方案是:

在jsp网页加入如下这一句


	$.ajaxSetup( {  
		beforeSend : function(xhr) {
		  xhr.setRequestHeader('isAjax', 'true');
		}
	});




然后改掉
org/apache/struts2/dispatcher/Dispatcher.java

将 prepare 方法里的第一句改为
        String encoding = null;
		if (request.getHeader("isAjax") != null) {
			encoding = "UTF-8";
			LOG.debug("ajax request");
		} else if (defaultEncoding != null) {
			encoding = defaultEncoding;
		}


整合完成。













1 楼 yhjhoo 2010-06-14  
我喜欢各自干各自的东西,据说struts2的那个jquery插件作者不打算持续开发。 这个是有一次我在他们的文档上看到的
2 楼 atit 2010-06-15  
我写这篇Blog的时候是2.0.0, 现在已经是2.2.0啦。 看来作者是在忽悠呢。
3 楼 zuo_huai 2010-06-17  
呵呵…… ,还可以吧