﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>BlogJava-J度空间-文章分类-Struts</title><link>http://www.blogjava.net/jdo/category/24569.html</link><description /><language>zh-cn</language><lastBuildDate>Sat, 25 Aug 2007 19:44:13 GMT</lastBuildDate><pubDate>Sat, 25 Aug 2007 19:44:13 GMT</pubDate><ttl>60</ttl><item><title>tomcat下中文的彻底解决</title><link>http://www.blogjava.net/jdo/articles/139346.html</link><dc:creator>蓝色幽默</dc:creator><author>蓝色幽默</author><pubDate>Sat, 25 Aug 2007 16:03:00 GMT</pubDate><guid>http://www.blogjava.net/jdo/articles/139346.html</guid><wfw:comment>http://www.blogjava.net/jdo/comments/139346.html</wfw:comment><comments>http://www.blogjava.net/jdo/articles/139346.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jdo/comments/commentRss/139346.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jdo/services/trackbacks/139346.html</trackback:ping><description><![CDATA[这些天开发一个项目，服务器是tomcat,操作系统是xp,采用的是MVC架构，模式是采用Facade模式，总是出现乱码，自己也解决了好多天，同事也帮忙解决，也参考了网上众多网友的文章和意见，总算是搞定。但是好记性不如烂笔杆，所以特意记下，以防止自己遗忘，同时也给那些遇到同样问题的人提供一个好的参考途径：<br />(一)    JSP页面上是中文，但是看的是后是乱码：<br />解决的办法就是在JSP页面的编码的地方&lt;%@ page language="java" contentType="text/html;charset=GBK" %&gt;，因为Jsp转成Java文件时的编码问题，默认的话有的服务器是ISO-8859-1，如果一个JSP中直接输入了中文，Jsp把它当作ISO8859-1来处理是肯定有问题的，这一点，我们可以通过查看Jasper所生成的Java中间文件来确认<br />(二)    当用Request对象获取客户提交的汉字代码的时候，会出现乱码：<br />解决的办法是：要配置一个filter,也就是一个Servelet的过滤器，代码如下：<br />import java.io.IOException;<br />import javax.servlet.Filter;<br />import javax.servlet.FilterChain;<br />import javax.servlet.FilterConfig;<br />import javax.servlet.ServletException;<br />import javax.servlet.ServletRequest;<br />import javax.servlet.ServletResponse;<br />import javax.servlet.UnavailableException;<br /><br />/**<br /> * Example filter that sets the character encoding to be used in parsing the<br /> * incoming request<br /> */<br />public class SetCharacterEncodingFilter implements Filter {<br /><br />    /**<br />     * Take this filter out of service.<br />     */<br />    public void destroy() {<br />    }<br />    /**<br />     * Select and set (if specified) the character encoding to be used to<br />     * interpret request parameters for this request.<br />     */<br />    public void doFilter(ServletRequest request, ServletResponse response,<br />    FilterChain chain)throws IOException, ServletException {<br /><br />    request.setCharacterEncoding("GBK");<br /><br />    // 传递控制到下一个过滤器<br />    chain.doFilter(request, response);<br />    }<br /><br />    public void init(FilterConfig filterConfig) throws ServletException {<br />    }<br />}<br />配置web.xml<br />&lt;filter&gt;<br />&lt;filter-name&gt;Set Character Encoding&lt;/filter-name&gt;<br />&lt;filter-class&gt;SetCharacterEncodingFilter&lt;/filter-class&gt;<br />&lt;/filter&gt;<br />&lt;filter-mapping&gt;<br />&lt;filter-name&gt;Set Character Encoding&lt;/filter-name&gt;<br />&lt;url-pattern&gt;/*&lt;/url-pattern&gt;<br />&lt;/filter-mapping&gt;<br />如果你的还是出现这种情况的话你就往下看看是不是你出现了第四中情况，你的Form提交的数据是不是用get提交的，一般来说用post提交的话是没有问题的，如果是的话，你就看看第四中解决的办法。<br />还有就是对含有汉字字符的信息进行处理，处理的代码是：<br />package dbJavaBean;<br /><br />public class CodingConvert<br />{   <br /> public CodingConvert()<br /> {<br />  //<br /> }<br /> public String toGb(String uniStr){<br />     String gbStr = "";<br />     if(uniStr == null){<br />   uniStr = "";<br />     }<br />     try{<br />   byte[] tempByte = uniStr.getBytes("ISO8859_1");<br />   gbStr = new String(tempByte,"GB2312");<br />     }<br />  catch(Exception ex){<br />    }<br />     return gbStr;<br /> }<br />   <br /> public String toUni(String gbStr){<br />     String uniStr = "";<br />     if(gbStr == null){<br />   gbStr = "";<br />     }<br />     try{<br />   byte[] tempByte = gbStr.getBytes("GB2312");<br />   uniStr = new String(tempByte,"ISO8859_1");<br />     }catch(Exception ex){<br />    }<br />    return uniStr;<br /> }<br />}<br />你也可以在直接的转换，首先你将获取的字符串用ISO-8859-1进行编码，然后将这个编码存放到一个字节数组中，然后将这个数组转化成字符串对象就可以了，例如：<br />String str=request.getParameter(“girl”);<br />Byte B[]=str.getBytes(“ISO-8859-1”);<br />Str=new String(B);<br />通过上述转换的话，提交的任何信息都能正确的显示。<br />(三)    在Formget请求在服务端用request. getParameter(“name”)时返回的是乱码；按tomcat的做法设置Filter也没有用或者用request.setCharacterEncoding("GBK");也不管用问题是出在处理参数传递的方法上：如果在servlet中用doGet(HttpServletRequest request, HttpServletResponse response)方法进行处理的话前面即使是写了：<br />request.setCharacterEncoding("GBK");<br />response.setContentType("text/html;charset=GBK");<br />也是不起作用的，返回的中文还是乱码！！！如果把这个函数改成doPost(HttpServletRequest request, HttpServletResponse response)一切就OK了。<br />同样，在用两个JSP页面处理表单输入之所以能显示中文是因为用的是post方法传递的，改成get方法依旧不行。<br />由此可见在servlet中用doGet()方法或是在JSP中用get方法进行处理要注意。这毕竟涉及到要通过浏览器传递参数信息，很有可能引起常用字符集的冲突或是不匹配。<br />解决的办法是：<br />1) 打开tomcat的server.xml文件，找到区块，加入如下一行： <br />URIEncoding=”GBK” <br />完整的应如下： <br />&lt;Connector port="8080" maxThreads="150" minSpareThreads="25" maxSpareThreads="75" enableLookups="false" redirectPort="8443" acceptCount="100" debug="0" connectionTimeout="20000" disableUploadTimeout="true" URIEncoding="GBK"/&gt; <br /><br />2)重启tomcat,一切OK。<br />需要加入的原因大家可以去研究 $TOMCAT_HOME/webapps/tomcat-docs/config/http.html下的这个文件就可以知道原因了。需要注意的是：这个地方如果你要是用UTF-8的时候在传递的过程中在Tomcat中也是要出现乱码的情况，如果不行的话就换别的字符集。<br /><br />(四)    JSP页面上有中文，按钮上面也有中文，但是通过服务器查看页面的时候出现乱码：<br />     解决的办法是：首先在JSP文件中不应该直接包含本地化的消息文本，而是应该通过&lt;bean:message&gt;标签从Resource Bundle中获得文本。应该把你的中文文本放到Application.properties文件中，这个文件放在WEB-INF/classes/*下，例如我在页面里有姓名，年龄两个label,我首先就是要建一个Application.properties，里面的内容应该是name=”姓名” age=”年龄”,然后我把这个文件放到WEB-INF/classes/properties/下，接下来根据Application.properties文件，对他进行编码转化，创建一个中文资源文件，假定名字是Application_cn.properties。在JDK中提供了native2ascii命令，他能够实现字符编码的转换。在DOS环境中找到你放置Application.properties的这个文件的目录，在DOS环境中执行一下命令，将生成按GBK编码的中文资源文件Application_cn.properties：native2ascii ?encoding gbk Application.properties Application_cn.properties执行以上命令以后将生成如下内容的Application_cn.properties文件：name=\u59d3\u540d age=\u5e74\u9f84,在Struts-config.xml中配置：&lt;message-resources parameter="properties.Application_cn"/&gt;。到这一步，基本上完成了一大半，接着你就要在JSP页面上写&lt;%@ page language="java" contentType="text/html;charset=GBK" %&gt;,到名字的那个label是要写&lt;bean:message key=”name”&gt;,这样的化在页面上出现的时候就会出现中文的姓名，年龄这个也是一样，按钮上汉字的处理也是同样的。<br />(五)    写入到数据库是乱码：<br />解决的方法：要配置一个filter,也就是一个Servelet的过滤器，代码如同第二种时候一样。<br />如果你是通过JDBC直接链接数据库的时候，配置的代码如下：jdbc:mysql://localhost:3306/workshopdb?useUnicode=true&amp;characterEncoding=GBK，这样保证到数据库中的代码是不是乱码。<br />如果你是通过数据源链接的化你不能按照这样的写法了，首先你就要写在配置文件中，在tomcat 5.0.19中配置数据源的地方是在C:\Tomcat 5.0\conf\Catalina\localhost这个下面，我建立的工程是workshop，放置的目录是webapp下面,workshop.xml的配置文件如下：<br />&lt;!-- insert this Context element into server.xml --&gt;<br /><br />&lt;Context path="/workshop" docBase="workshop" debug="0"<br />reloadable="true" &gt;<br /><br />  &lt;Resource name="jdbc/WorkshopDB"<br />               auth="Container"<br />               type="javax.sql.DataSource" /&gt;<br /><br />  &lt;ResourceParams name="jdbc/WorkshopDB"&gt;<br />    &lt;parameter&gt;<br />      &lt;name&gt;factory&lt;/name&gt;<br />      &lt;value&gt;org.apache.commons.dbcp.BasicDataSourceFactory&lt;/value&gt;<br />    &lt;/parameter&gt;<br />    &lt;parameter&gt;<br />      &lt;name&gt;maxActive&lt;/name&gt;<br />      &lt;value&gt;100&lt;/value&gt;<br />    &lt;/parameter&gt;<br />    &lt;parameter&gt;<br />      &lt;name&gt;maxIdle&lt;/name&gt;<br />      &lt;value&gt;30&lt;/value&gt;<br />    &lt;/parameter&gt;<br /><br />    <br />    &lt;parameter&gt;<br />      &lt;name&gt;maxWait&lt;/name&gt;<br />      &lt;value&gt;10000&lt;/value&gt;<br />    &lt;/parameter&gt;<br /><br />      &lt;parameter&gt;<br />     &lt;name&gt;username&lt;/name&gt;<br />     &lt;value&gt;root&lt;/value&gt;<br />    &lt;/parameter&gt;<br />    &lt;parameter&gt;<br />     &lt;name&gt;password&lt;/name&gt;<br />     &lt;value&gt;&lt;/value&gt;<br />    &lt;/parameter&gt;<br /><br />    &lt;!-- Class name for mm.mysql JDBC driver --&gt;<br />    &lt;parameter&gt;<br />       &lt;name&gt;driverClassName&lt;/name&gt;<br />       &lt;value&gt;com.mysql.jdbc.Driver&lt;/value&gt;<br />&lt;/parameter&gt;<br />   &lt;parameter&gt;<br />      &lt;name&gt;url&lt;/name&gt;<br /> &lt;value&gt;&lt;![CDATA[jdbc:mysql://localhost:3306/workshopdb?useUnicode=true&amp;characterEncoding=GBK]]&gt;&lt;/value&gt;<br />    &lt;/parameter&gt;<br />  &lt;/ResourceParams&gt;<br /><br />&lt;/Context&gt;<br />粗体的地方要特别的注意，和JDBC直接链接的时候是有区别的，如果你是配置正确的化，当你输入中文的时候到数据库中就是中文了，有一点要注意的是你在显示数据的页面也是要用&lt;%@ page language="java" contentType="text/html;charset=GBK" %&gt;这行代码的。需要注意的是有的前台的人员在写代码的是后用Dreamver写的，写了一个Form的时候把他改成了一个jsp，这样有一个地方要注意了，那就是在Dreamver中Action的提交方式是request的，你需要把他该过来，因为在jsp的提交的过程中紧紧就是POST和GET两种方式，但是这两种方式提交的代码在编码方面还是有很大不同的，这个在后面的地方进行说明。3<br /><br />以上就是我在开发系统中解决中文的问题，不知道能不能解决大家的问题，时间匆忙，没有及时完善，文笔也不是很好，有些地方估计是词不达意。大家可以给我意见，希望能共同进步。<br /><img src ="http://www.blogjava.net/jdo/aggbug/139346.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jdo/" target="_blank">蓝色幽默</a> 2007-08-26 00:03 <a href="http://www.blogjava.net/jdo/articles/139346.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>AJAXAnywhere 总结</title><link>http://www.blogjava.net/jdo/articles/136520.html</link><dc:creator>蓝色幽默</dc:creator><author>蓝色幽默</author><pubDate>Mon, 13 Aug 2007 14:49:00 GMT</pubDate><guid>http://www.blogjava.net/jdo/articles/136520.html</guid><wfw:comment>http://www.blogjava.net/jdo/comments/136520.html</wfw:comment><comments>http://www.blogjava.net/jdo/articles/136520.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jdo/comments/commentRss/136520.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jdo/services/trackbacks/136520.html</trackback:ping><description><![CDATA[1，简介<br />AjaxAnywhere被设计成能够把任何一套现存的JSP组件转换成AJAX感知组件而不需要复杂的JavaScript编码.它利用标签把Web页面简单地划分成几个区域,然后使用AjaxAnywhere来刷新那些需要被更新地区域<br />2,ajaxanywhere学习有两天了。ajaxanywhere与jsp,servlet,struts都能配合使用得很好。但是也有一些问题。<p>这几天找了一些ajax的开源，感觉ajaxtags功能有限且实现复杂，很难和其他框架集成。strutstags<br />倒
很对路但是提供的例子里竟然没有strutsconfig.xml运行不起来，没办法，我只好转向ajaxanywhere,用了一天的时间才把
ajaxanywhere与servlet,struts框架分别结成起来，处理主要集中在aa.js，不是不用写js，而是只要写少量的js就可以实现
复杂的调用。感觉很简单。</p><p>但是它也有不足之处，Demo中deServerSide.jsp例子点14下后竟然死掉了，sourceforge论坛上<br />294条记录竟然没有一个人发现，我和其他几个同事使用他们提供的网上Demo也是一样，提了这个<br />问题一时半会也没有人解答。看来，这也是js牛人才能真正玩的通的，为什么这么说呢？因为一旦出<br />了问题就要研究aa.js了。说是不用自己写js，但实际上还是要把aa.js研究透了才敢用到项目中。<br /></p><p>下面把我这两天的所学做一下总结：<br />2.1 从配置上来讲：<br /> ajaxanywhere没有tld文件，但是他需要在web.xml中配置一个filter，这就足够了。<br />   &lt;filter&gt;<br />        &lt;filter-name&gt;AjaxAnywhere&lt;/filter-name&gt;<br />        &lt;filter-class&gt;org.ajaxanywhere.AAFilter&lt;/filter-class&gt;<br />    &lt;/filter&gt;<br />    &lt;filter-mapping&gt;<br />        &lt;filter-name&gt;AjaxAnywhere&lt;/filter-name&gt;<br />        &lt;url-pattern&gt;*.jsf&lt;/url-pattern&gt;<br />    &lt;/filter-mapping&gt;<br />    &lt;filter-mapping&gt;<br />        &lt;filter-name&gt;AjaxAnywhere&lt;/filter-name&gt;<br />        &lt;url-pattern&gt;*.jsp&lt;/url-pattern&gt;<br />    &lt;/filter-mapping&gt;<br />     &lt;filter-mapping&gt;<br />        &lt;filter-name&gt;AjaxAnywhere&lt;/filter-name&gt;<br />        &lt;url-pattern&gt;*.do&lt;/url-pattern&gt;<br />    &lt;/filter-mapping&gt;<br /> 
值得注意的是，只有通过此filter的request
url才能够使用它的功能，所以要确保需要此功能的url能够通过此filter！我刚开始的时候写了一个servlet与ajaxanywhere的
jsp页面联合使用，但总是抱错：“说返回的类型并不是text/xml”类型，后来<br />我想肯定是要求servlet必须返回text/xml类型了，于是就在servlet的末尾增加了一句话：<br />response.setContentType("text/xml; charset=UTF-8");心想这回没错了吧，没想到运行时仍旧显示“返回类型不是<br />text/xml”，这是页面的js报的错误，也就是在返回信息到了页面，叶面分析返回数据的时候报的错误。仔细检查了servlet<br />设置返回类型的那句话并没有错误。</p><p> 
原来问题出在servlet的mapping上面，设置了一个/xxxx没有带".do"(这时还没有struts环境呢)，这样一来，servelt返
回给页面的response并没有被AjAxanywhere
Filter截获，当然就没有没有被处理过（具体内部处理不太清楚），于是就出了上面的错误。<br /> 解决方法很简单，把所有需要ajaxanywhere的servlet  mapping配置成一个比较特殊的后缀，例如localServlet.aj这样在<br />web.xml中配置AjaxAnywhere过滤器的filer-mapping 增加一条<br />     &lt;filter-mapping&gt;<br />        &lt;filter-name&gt;AjaxAnywhere&lt;/filter-name&gt;<br />        &lt;url-pattern&gt;*.aj&lt;/url-pattern&gt;<br />    &lt;/filter-mapping&gt;<br />这样所有的后缀为aj的servlet就都可以使用上此Filter了。错误就没有了。ok，上面讲了ajaxanywhere +　servlet 的方法。</p><p>2.2 配置ajaxanywhere + struts .<br /> 
配置也比较简单。在struts的配置正确的基础上，只需要配置ajaxanywhere的filter，增加一个mapping，如果struts
ActionServlet配置了mapping *.xx
,那么表示所与后缀为xx的url都经过AcitonServlet来处理，好，ajaxanywhere要求所有的<br />url在进入AciontServlet之前首先进入他的Filter，离开ActionServlet之后也要首先进入他的Filter，而不是直接返回页面。<br />这样，只要在ajaxanywhere filter的mapping后面增加<br />     &lt;filter-mapping&gt;<br />        &lt;filter-name&gt;AjaxAnywhere&lt;/filter-name&gt;<br />        &lt;url-pattern&gt;*.xx&lt;/url-pattern&gt;<br />    &lt;/filter-mapping&gt;<br />即可。这样就能和struts配置使用了。</p><p>2.3 配置ajaxanywhere +　ｊｓf<br /> 
例子中也讲到了与jsf配合使用的方法，jsf我没有用过，但是配置ajaxanywhere要做得就是增加一个filter-mapping而已。假设
jsf的后缀是*.jsf,那么只需要在 ajaxanywhere filter中增加一个此后缀的mapping，就ok了。</p><p>2.4 ajaxanywhere + * +　ｊｓｔｌ<br /> 于ｊｓｔｌ连用实际上就是与ｊｓｐ连用，但是把jstl也融合进来需要注意，ajaxanywhere Demo例子中的web.xml<br /> 不兼容jstl,所以除了要把必要的jar文件tld文件拷贝到项目之外，还要把web.xml的头部进行修改，原来是这样写的<br /> &lt;web-app&gt;..... ,必须要修改成<br /> &lt;web-app xmlns="<a href="http://java.sun.com/xml/ns/j2ee">http://java.sun.com/xml/ns/j2ee</a>" xmlns:xsi="<a href="http://www.w3.org/2001/XMLSchema-instance">http://www.w3.org/2001/XMLSchema-instance</a>" xsi:schemaLocation="<a href="http://java.sun.com/xml/ns/j2ee">http://java.sun.com/xml/ns/j2ee</a><a href="http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd</a>" version="2.4"&gt;<br /> 这样才行。<br /> 否则你会发现一个特别奇怪的错误，例如&lt;c:forEach items="sdfsd" var="item"&gt;${item.value}&lt;/c:forEach&gt;<br /> 就是不循环显示，但是&lt;c:out value="xxxx"/&gt;却可以运行，当时就懵了。修改了web.xml之后就一切正常了^_^</p><p> </p><p>3，ajaxanywhere的目录结构和文件的特色。<br /> 和普通的项目的区别就在三个地方：<br /> 3.1 /aa/aa.js 里面包含了ajaxanywhere必须使用的javascript对象和方法。这个文件必须用，<br />  而且每个jsp页面都要引用他，如果想深入使用就有必要对里面的方法有所了解。<br /> <br /> 3.2   多了一个Filter，一个ajaxanywhere.jar，对程序员是透明的。</p><p> 3.3   jsp页面要引入lib&lt;%@ taglib uri="<a href="http://ajaxanywhere.sourceforge.net/">http://ajaxanywhere.sourceforge.net/</a>" prefix="aa" %&gt;。<br />  简单使用时只需要配置好&lt;aa:zone&gt;,<br />  然后当Get方法（链接跳转），某标签的onclick中调用“ajaxAnywhere.getAJAX(目标url)”。<br />  当Post方法（表单提交）时，首先配置form名字，例如，ajaxAnywhere.formName = "main"<br />    在表单里调用“ajaxAnywhere.submitAJAX();”或者干脆设置一个能够自动submit<br />    的input按钮例如&lt;intput type="image"&gt;&lt;input type="submit"&gt;就什么都不用写，也能提交。</p><p>4，具体使用方法：<br /> 4.1 jsp页面上：<br />  定义刷新区域，使用&lt;aa:zone name="xxxx"&gt;来定义一个区域。<br />  可以在jsp页面上“指定”刷新区域，他和“定义”刷新区域的区别在于，定义了不一定会被刷新，定义后<br />   又被指定的刷新区域才能被刷新。通过覆盖js中AjaxAnywere对象的ajaxAnywhere.getZonesToReload<br />   方法来指定刷新区域。例如，<br />   ajaxAnywhere.getZonesToReload = function () {<br />           return "zone,1"<br />      };<br />   指定了两块刷新区域。<br />  在刷新区域显示新的内容：<br />   刷新区域里面，使用动态脚本（scriplet，jstl）从request（或其他范围）获得服务端返回的新的数据，<br />   并显示。（推荐使用jstl比scriptlet更简洁）。</p><p> 4.2 服务端：<br />  不论是Servlet还是Action还是直接使用jsp做服务端，代码都是一样的。<br />  必须有的几行代码是：<br />  if (AAUtils.isAjaxRequest(request)){<br />        AAUtils.addZonesToRefresh(request, "xxxx");//这句话也可以不写如果jsp页面已经指定了刷新区域<br />  }<br />  然后返回一个List放到request或者其他范围内，供页面显示。<br />  <br />       注意：<br />   服务端代码不必使用设置context-type为xml，没有必要。因为通过ajaxanywhere filter可以做到这一点。<br /> <br />5，定制js<br /> 5.1 如何在response尚未返回期间不显示默认的“loading...”（蓝色图层）？<br />  通过在jsp页面里覆盖 ajaxAnywhere.showLoadingMessage = function() {}并设置为空。<br /> <br /> 5.2 如何修改默认的loading。。。图片为其他图片？<br />  通过在jsp页面里覆盖 ajaxAnywhere.showLoadingMessage ，hideLoadingMessage,方法。<br />  ajaxAnywhere.showLoadingMessage = function() {</p><p>    var img = document.getElementById("myImg");<br />    if (img == null) {<br />        img = document.createElement("img");<br />        document.body.appendChild(img);<br />        img.id = "myImg";<br />        <br />        <br />        img.src="psyline.gif";<br />        img.style.position = "absolute";<br />        img.style.border = "1 solid black";<br />        img.style.top = 0;<br />        img.style.left = documet.body.offsetLeft;<br />    }<br />    <br />    img.style.display = "";<br /> }</p><p> /**<br /> *  Default sample loading message hide function. Overrride it if you like.<br /> */<br /> AjaxAnywhere.prototype.hideLoadingMessage = function() {<br />     var img = document.getElementById("myImg");<br />     if (img != null)<br />         img.style.display = "none";<br /> }<br /> 好，这样就把把默认图片替换成其他图片了。<br /> <br /> 5.3 如何修改loading图片的显示为之为相对位置？<br />  只需要配置top，left，例如:<br /> ajaxAnywhere.showLoadingMessage = function() {<br />    var div = document.getElementById("testshowdiv");<br />    if (div == null) {<br />        div = document.createElement("DIV");<br />        document.body.appendChild(div);<br />        div.id = "testshowdiv";<br />        div.innerHTML = "&lt;img src='shc.gif' border=0/&gt;";<br />        div.style.position = "absolute";<br />        div.style.border = "1 solid black";<br />        div.style.color = "white";<br />        div.style.backgroundColor = "blue";<br />        div.style.width = "100px";<br />        div.style.heigth = "50px";<br />        div.style.fontFamily = "Arial, Helvetica, sans-serif";<br />        div.style.fontWeight = "bold";<br />        div.style.fontSize = "11px";<br />    }<br /> //注意，如果alink没有定义，那么就始终显示进度条了。有时抱错，有时不抱错。<br />    div.style.top = document.all.alink.offsetTop;<br />    div.style.left =document.all.alink.offsetWidth-170; // 如果不减，在屏幕上就看不到了。<br />    div.style.display = "";<br />    <br />    }<br /> <br /> /**<br /> *  Default sample loading message hide function. Overrride it if you like.<br /> */<br /> AjaxAnywhere.prototype.hideLoadingMessage = function() {<br />     var div = document.getElementById("testshowdiv");<br />     if (div != null)<br />         div.style.display = "none";<br /> }<br /> <br />5.4 如果设置默认的弹出框。在上次请求被忽略后，默认会弹出一个框，如果让不让他出来？<br /> 只需要覆盖或者直接在aa。js中修改<br /> ajaxAnywhere.handlePrevousRequestAborted = function() {<br />       // alert("放弃上一次的提交");//或者什么都不作<br />    }</p><p>5.5 如何处理异常弹出框？<br /> 只需要覆盖<br /> ajaxAnywhere.handleException = function(type, details) {<br />        alert("出异常了: \n\n\n ***************\n"+details.substring(0,350)+"\n...\n\n     ***************");<br />    }<br />5.6 如何处理错误弹出框？<br /> 只需要覆盖<br /> ajaxAnywhere.handleHttpErrorCode = function(code) {<br />        alert("返回错误: \n \n \n ***************\n错误码:" + code+"\n\n ***************");<br />    }</p><p>5.7 如何定时刷新指定区域？<br /> ajax定时刷新执行得更象普通的js，<br /> // 指定定期执行的刷新所指向的url<br /> function go() {<br />        ajaxAnywhere.getAJAX('demo.jsp');<br />    }<br /> //指定刷新区域<br />    ajaxAnywhere.getZonesToReload = function () {<br />        return "zone,1"<br />    };<br /> //指定刷新之后的动作<br />    ajaxAnywhere.onAfterResponseProcessing = function () {<br />        window.setTimeout("go();", 1000);<br />     //setInterval("go()",1000);<br />    }<br /> //隐藏loading图片<br />    ajaxAnywhere.showLoadingMessage = function(){};<br /> //调用刷新后的动作<br />    ajaxAnywhere.onAfterResponseProcessing();<br /> 这样就构成了一个循环。</p><p> 与普通的js定时执行某个操作并没有什么不同，只不过通过在定时操作中使用ajax，可以调用非客户端的程序，即后台程序。而普通的定时执行却做不来。<br /> <br />6，一些与ajaxanywhere无关的技术。<br /> 6.1 struts动态form<br /> ajaxanywhere
不是必须指定formName，因为它默认使用forms[0]当作提交的form，这并不保险（一个页面可能有多个form），所以有必要指定
formName，struts的&lt;html:form&gt;标签，必须struts-config配置了form时才行，没有必要使用
ActionForm时可以定义一个空的DynaActionForm,例如，<br /> &lt;form-bean name="localeform" type="org.apache.struts.action.DynaActionForm"&gt;<br />    &lt;form-property name="nnn" type="java.lang.String"/&gt; //这句话也可以没有。即没有属性的form<br />   &lt;/form-bean&gt;<br /> 这样就不必多定义一个类了，动态form与ajaxanywhere配合得很好。</p><p> 6.2 struts DispatchAction<br /> ajax与strutsDispatchAction配合得也很好。</p><p>总结：<br /> 比较ajax tags，struts ajaxtag，还是ajaxanywhere比较好些。<br /> ajaxtags是基于组件的，能实现的功能有限。struts ajaxtags我用了之后感觉复杂。好了，暂时就写这么多，以后的实践经验就算在ajaxanywhere的补充了。<br /> 下载地址：<a href="http://ajaxanywhere.sourceforge.net/index.html">http://ajaxanywhere.sourceforge.net/index.html</a></p><img src ="http://www.blogjava.net/jdo/aggbug/136520.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jdo/" target="_blank">蓝色幽默</a> 2007-08-13 22:49 <a href="http://www.blogjava.net/jdo/articles/136520.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>struts+ajax</title><link>http://www.blogjava.net/jdo/articles/136304.html</link><dc:creator>蓝色幽默</dc:creator><author>蓝色幽默</author><pubDate>Mon, 13 Aug 2007 02:24:00 GMT</pubDate><guid>http://www.blogjava.net/jdo/articles/136304.html</guid><wfw:comment>http://www.blogjava.net/jdo/comments/136304.html</wfw:comment><comments>http://www.blogjava.net/jdo/articles/136304.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jdo/comments/commentRss/136304.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jdo/services/trackbacks/136304.html</trackback:ping><description><![CDATA[
		<span id="ctl00_MainContentPlaceholder_ctl00_ctl00_lblEntry">
				<div id="msgcns!2993BC1DDCEB5D2E!242" class="bvMsg">
						<div>  
标准的struts是同步交互的,客户端提交请求到Action,服务端处理后findforward()刷新整个页面,ajax是异步交互,页面通过
xmlHttpRequest提交一个后台线程到服务端,服务端处理后将xml或者html写回客户端,客户端回调函数随即刷新内存中的dom树.<br />  <br />  
由于ajax不用刷新整个页面,且每次回调函数直接更新内存,所以速度非常快,且客户体验很丰富,比如用ajax可以很容易实现菜单联动(因为它只更新下
级菜单,上一级菜单根本不会受影响,在jsp中意味着不用关心页面刷新时其它表单元素的选择值),另外还有一点ajax是客户端的技术,对struts的
架构不会影响(客户端的提交可以用ajax提交到servlet,也可以沿用struts方式提交到Action中),因此很容易想到将ajax和
Struts结合起来,共用两者的优势.<br /><br /></div>
						<div>   用ajax+struts的架构有一些需要注意的问题,这是我在项目中的一些感受,在这里写出来,供各位同仁参考:<br /><br /></div>
						<div>  
1:设计页面跳转的操作不要用ajax.ajax主要是用于异步交互,所以它是同一个页面的操作,在xmlHttpRequest.open()方法中,
"get"方法明确表示是从服务端获取,"post"方法虽然表示提交,但主要用于浏览器url隐藏参数的具体值,在ajax的servlet中用
response.sendRedirect()方法是无效的,原页面会傻等后台servlet的相应.因此MIS系统中的新增,修改等需要到另一个页面
的操作都应该用传统的form.submit()的方式提交页面.<br /><br /></div>
						<div>   
2:在ajax传参时要特别注意\",\'这些字符,尤其是一个参数中含多个字段的情况,尽量不要用'$','%'等特殊字符来分割.在servlet端
getParameter()的时候会出问题,比如你的参数是param1="dkfjdslf"+form1.text1.value;而你的
text1中的字符串含有\"字符,那\"后面的<br />就都传不过去了.我们项目中遇到过这种情况,找了很久才发现参数只传了一部分.建议如果参数不全的情况首先检查其中是否有特殊字符.<br /><br /></div>
						<div>   
3:struts和ajax合用时有时会出现struts刷新整个页面结果把ajax效果覆盖了的情况,比如我们的翻页组件是会提交整个表单到原页面,这
时如果客户做了ajax的其它操作,翻页返回时这些效果就都没有了.我的建议是在页面中用&lt;input
type=hidden&gt;元素保留ajax的主要效果,每次ajax回调函数返回时更新该元素,这样即时重新提交了该页面也可以通过
request.getParameter()取到ajax效果元素的值.在我们项目中是把每次的查询sql语句做为hidden元素保存了的,因此每次
翻页后下级表格或者其它表单元素仍可以通过该sql取得.<br /><br /></div>
						<div>  
4:ajax大部分是js脚本,js脚本的调试比较麻烦,主要的办法就是alert()和iE左下脚的错误提示,一般来说大部分的脚本错误都在语法上,比
如select1.options[1]写成了select1.option[1]什么的,看资料上有IE有Dom
Inspector可以查看内存中的dom树结构(在google上搜Internet Explorer developer
toolbar),用这些第三方的工具可以帮我们调试ajax<br /><br /></div>
						<div>  
5:有时候strust在request中setAttribute的东西会跟ajax传的parameter冲突(比如上头提到的sql,在新增操作完
后返回查询页面时,struts会在request.setAttribute("sql",sql),
而原查询页面的下级菜单查询等ajax操作会传以"sql="+sql的方式传参,这样两个sql会冲突,我的建议是
request.getParameter("sql")==null?request.getAttribute("sql"):request.getParameter
("sql"),首先保证本页面的异步操作,再考虑其它页面的跳转操作.<br /><br /></div>
						<div>   好了,暂且写这些吧,其中有些可能各位高人看起来是废话,那请毫不留情的斧正!在此祝各位同仁中秋国庆愉快,祝和我一样国庆加班的同事们身体健康,万事如意.</div>
				</div>
		</span>
<img src ="http://www.blogjava.net/jdo/aggbug/136304.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jdo/" target="_blank">蓝色幽默</a> 2007-08-13 10:24 <a href="http://www.blogjava.net/jdo/articles/136304.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Struts模块化编程教程</title><link>http://www.blogjava.net/jdo/articles/134926.html</link><dc:creator>蓝色幽默</dc:creator><author>蓝色幽默</author><pubDate>Tue, 07 Aug 2007 05:10:00 GMT</pubDate><guid>http://www.blogjava.net/jdo/articles/134926.html</guid><wfw:comment>http://www.blogjava.net/jdo/comments/134926.html</wfw:comment><comments>http://www.blogjava.net/jdo/articles/134926.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jdo/comments/commentRss/134926.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jdo/services/trackbacks/134926.html</trackback:ping><description><![CDATA[
		<span class="myp111">
				<font id="zoom">
						<b>1、前言</b>
						<br />
						<br />STRUTS是标准的"模型2"的WEB应用框架，其中的ActionServlet代表了"模型2"MVC设计模式中的"控制器"
。STRUTS应用程序一般使用JSP代码生成用户界面，这些代码不包括任何商业逻辑，代表了MVC中的”VIEW”部分。需要执行商业逻辑的用户界面中
的表单或超链将会由"控制器"
ActionServlet接收和处理。在STRUTS中，只有一个ActionServlet实例，这个实例将接收和处理应用中的相关用户交互请求。
ActionServlet实例将选择和调用相应的ACTION类来处理商业逻辑。在设计模式上，ACTION类被称为“控制辅助者”，它将修改
JavaBeans，这些JavaBeans就是MVC中的” model”部分。本文将分析在STRUTS中进行模块化编程的具体细节。 <br /><br /><b>2、样例描述</b><br /><br />我们将作一个模块编程的例子，这个例子包括三个模块，缺省模块、registration模块和approval模块。缺省模块下有资源
index.html，我们使用它来连接其它两个模块。registration模块和approval模块的编程类似，都包含一个index.jsp和
一个结果jsp：result.jsp。下面是目录结构： <br /><br /><center><img src="http://tech.ccidnet.com/pub/attachment/2004/1/269764.jpg" height="424" width="533" /></center><br /><br />目录结构表明，struts的模块由配置文件、java类(这里者action和form类)和资源文件构成，另外各模块可以共享web.xml，message （这里是applicatonResources.properties）文件。 
<br /><br />我们的例子的界面交互图可以表示如下： 
<br /><br /><center><img src="http://tech.ccidnet.com/pub/attachment/2004/1/269765.jpg" height="352" width="539" /></center><p><br /><br />缺省模块的index.html包括两个链接，分别连接两个模块的index.jsp资源，registration模块的index.jsp提
交后，如果验证失败会重新返回到该模块的index.jsp，否则用资源resultok.jsp显示注册成功的结果。模块approval的
index.jsp提交后进入到resultok.jsp的界面，显示批准与否的结果。 <br /><br />我们从应用程序的文件组成和交互两方面的模块情况对我们要实现的例子进行了比较清晰的组织，下面我们讲解如何在struts中实现模块化编程。
</p></font>
		</span>
		<p>
				<b>3、STRUTS的模块化机制</b>
				<br />
				<br />我们将讲解STRUTS的相关配置，这些配置大部分与模块化编程有关系，有些没关系但对理解STRUTS程序有利。 
<br /><br />3.1 ActionServlet参数 
<br /><br />ActionServlet有好多参数可供设置，STRUTS在WEB应用部署描述符中定义这些参数： 
<br /><br />·Config——逗号相隔的应用上下文相对的配置文件的路径，这些配置文件包含了STRUTS WEB应用的缺省模块的设置。缺省值为 /WEB-INF/struts-config.xml；
<br />·config/${module} -逗号相隔的应用上下文相对的配置文件的路径，这些配置文件包含了STRUTS
WEB应用的${module}模块的设置。这个模块的前缀是/${module}，多个config/${module}参数定义了多个STRUTS
WEB应用模块；
<br />·convertNull - 如果这个参数的值为 true, 数值型Java 包装类（比如java.lang.Integer）的初始值将会是null，而不是0。缺省值[false]
<br />·rulesets-逗号相隔的附加的org.apache.commons.digester.RuleSet列表，Digester在分析配置文件时，除了针对标准的配置元素的RuleSet之外，还会利用这些对象来分析配置文件，这样提供了一个配置扩展机制。
<br />·validatin - 指示我们是否使用验证型的XML分析器来处理配置文件，缺省值为 [true] 
<br /><br />3.2 配置文件 
<br /><br />我们说STRUTS针对每个模块可以有一个或多个配置文件，这些配置文件使用XML来书写，下面是标准的配置文件XML的元素解释。 
<br /><br />3.2.1 元素 action 
<br /><br />这个元素描述了一个ActionMapping 对象，这个对象将用来处理用户针对某个模块相对应的URI 的请求。 
<br /><br /><img src="http://tech.ccidnet.com/pub/attachment/2004/1/269845.jpg" height="558" width="668" /><br /><br /><br /><br />3.2.2元素 action-mappings 
<br /><br />这个元素描述了一个ActionMapping
对象集，类型是org.apache.struts.action.ActionMapping。与STRUTS的ActionServlet
注册的URL模式匹配的用户请求将具体地被这些ActionMapping 对象处理。子元素定义了各个ActionMapping对象。 <br /><br /><img src="http://tech.ccidnet.com/pub/attachment/2004/1/269851.jpg" height="168" width="666" /><br /><br />3.2.3元素 controller 
<br /><br />这个元素描述了一个struts模块运行环境的配置——ControllerConfig bean 
<br /><br /><img src="http://tech.ccidnet.com/pub/attachment/2004/1/269852.jpg" height="506" width="670" /><br /><br /><img src="http://tech.ccidnet.com/pub/attachment/2004/1/269853.jpg" height="426" width="617" /><br /><br /><img src="http://tech.ccidnet.com/pub/attachment/2004/1/269854.jpg" height="361" width="669" /><br /><br /><br /><br />3.2.4 元素 data-source 
<br /><br />这个元素描述了一个DataSource 对象——JDBC 2.0 标准扩展。这个对象将被保存在应用上下文中，而且可以象JavaBean 一样被设置。 
<br /><br /><img src="http://tech.ccidnet.com/pub/attachment/2004/1/269855.jpg" height="360" width="669" /><br /><br />3.2.5 元素 exception 
<br /><br />这个元素向struts系统为一个exception类型注册了一个ExceptionHandler。. 
<br /><br /><img src="http://tech.ccidnet.com/pub/attachment/2004/1/269856.jpg" height="487" width="671" /><br /><br />3.2.6 元素 form-bean 
<br /><br />这个元素定义了一个ActionForm[org.apache.struts.action.ActionForm子类，这个定义被"action"元素所引用。 
<br /><br /><img src="http://tech.ccidnet.com/pub/attachment/2004/1/269857.jpg" height="259" width="670" /><br /><br />3.2.7 元素 form-property 
<br /><br />这个元素描述了一个配置DynaActionForm 或其子类的JavaBean属性。当这个元素的父元素"form-bean"
的"type" 是 [org.apache.struts.action.DynaActionForm]
或其子类时有效。如果使用了一个定制的DynaActionForm 子类，父元素"form-bean" 的"dynamic"属性必须设为
"true"。 <br /><br /><img src="http://tech.ccidnet.com/pub/attachment/2004/1/269846.jpg" height="337" width="668" /><br /><br />3.2.8 元素 forward 
<br /><br />这个元素描述了一个ActionForward
对象，这个对象将被Action的doPerform返回。在代码中一般用一个逻辑名字来引用ActionForward
对象。一个"forward" 可以用来描述全局或局部ActionForwards. 全局的 forwards对模块内所有的Action
对象有效，局部forwards 嵌套在<action></action> 元素内，只能被相应的ActionMapping 中的Action访问。 
<br /><br /><img src="http://tech.ccidnet.com/pub/attachment/2004/1/269847.jpg" height="464" width="661" /><br /><br />3.2.9元素 message-resources 
<br /><br /><img src="http://tech.ccidnet.com/pub/attachment/2004/1/269848.jpg" height="464" width="666" /><br /><br />3.2.10元素 plug-in 
<br /><br /><img src="http://tech.ccidnet.com/pub/attachment/2004/1/269849.jpg" height="152" width="671" /><br /><br />3.2.11 元素 set-property 
<br /><br /><img src="http://tech.ccidnet.com/pub/attachment/2004/1/269850.jpg" height="132" width="666" /> 
<br /><br /></p>
		<p>
				<b>目录： 
<br /><br /><a href="http://tech.ccidnet.com/pub/article/c1077_a82053_p1.html#1">4、模块定义</a><br /><a href="http://tech.ccidnet.com/pub/article/c1077_a82053_p1.html#2">5、模块选择</a><br /><a href="http://tech.ccidnet.com/pub/article/c1077_a82053_p1.html#3">6、总结</a><br /><br /></b>
				<br />
				<br />
				<a name="1">
						<b>4、模块定义</b>
				</a>
				<br />
				<br />通过上面对STRUTS的模块化机制的讲解，我们现在可以开始实现我们的模块化例子程序了。 
<br /><br />4.1 Actionservlet参数 
<br /><br />我们在struts的web.xml中定义模块。下面的代码定义了三个模块：缺省模块，approval和registration模块，前缀分别是””,/approval和/registration。 
<br /><br /><ccid_nobr></ccid_nobr></p>
		<table bordercolordark="#ffffff" bordercolorlight="#000000" align="center" border="1" cellpadding="2" cellspacing="0" width="400">
				<tbody>
						<tr>
								<td class="code" style="font-size: 9pt;" bgcolor="#e6e6e6">
										<pre>
												<ccid_code>
												</ccid_code>&lt;web-app&gt;<br />    &lt;servlet&gt;<br />        &lt;servlet-name&gt;action&lt;/servlet-name&gt;<br />        &lt;servlet-class&gt;org.apache.struts.action.ActionServlet&lt;/servlet-class&gt;<br />        &lt;init-param&gt;<br />            &lt;param-name&gt;config&lt;/param-name&gt;<br />            &lt;param-value&gt;/WEB-INF/struts-config.xml&lt;/param-value&gt;<br />                    &lt;/init-param&gt;<br />        &lt;init-param&gt;<br />            &lt;param-name&gt;config/approval&lt;/param-name&gt;<br />            &lt;param-value&gt;/WEB-INF/struts-config-approval.xml&lt;/param-value&gt;<br />                    &lt;/init-param&gt;<br />        &lt;init-param&gt;<br />            &lt;param-name&gt;config/registration&lt;/param-name&gt;<br />            &lt;param-value&gt;/WEB-INF/struts-config-registration.xml&lt;/param-value&gt;<br />        &lt;/init-param&gt;<br />     &lt;/init-param&gt;<br />         &lt;load-on-startup&gt;1&lt;/load-on-startup&gt;<br />            &lt;/servlet&gt;    &lt;servlet-mapping&gt;<br />        &lt;servlet-name&gt;action&lt;/servlet-name&gt;<br />        &lt;url-pattern&gt;*.do&lt;/url-pattern&gt;<br />            &lt;/servlet-mapping&gt;<br />    &lt;/web-app&gt;</pre>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<br />这样在初始化actionservlet的过程中，servletcontext的属性中就会有这样的属性键/值关系： 
<br /><br /><center><img src="http://tech.ccidnet.com/pub/attachment/2004/1/270101.jpg" height="212" width="506" /></center><p><br /><br />4.2 approval模块配置文件 
<br /><br />下面是approval模块的配置文件，定义了form和action，以及相应的forward。 
<br /><br /><ccid_nobr></ccid_nobr></p><table bordercolordark="#ffffff" bordercolorlight="#000000" align="center" border="1" cellpadding="2" cellspacing="0" width="400"><tbody><tr><td class="code" style="font-size: 9pt;" bgcolor="#e6e6e6"><pre><ccid_code></ccid_code>&lt;?xml version="1.0" encoding="UTF-8"?&gt;<br />&lt;!DOCTYPE struts-config PUBLIC "-//Apache Software Foundation//<br />                              DTD Struts Configuration 1.1//EN" <br />"http://jakarta.apache.org/struts/dtds/struts-config_1_1.dtd"&gt;<br />&lt;struts-config&gt;<br />        &lt;form-beans&gt;<br />        &lt;form-bean name="approvalForm" type="com.i505.struts.approval.form.ApprovalForm"&gt;<br />         &lt;/form-bean&gt;<br />            &lt;/form-beans&gt;<br />       &lt;action-mappings&gt;<br />        &lt;action<br />            attribute="approvalForm"<br />            name="approvalForm"<br />            input="/index.jsp"<br />            path="/approval"<br />            scope="request"<br />            type="com.i505.struts.approval.action.ApprovalAction"&gt;<br />            &lt;forward name="success" contextRelative="false" path="/resultok.jsp" /&gt;<br />        &lt;/action&gt;<br />    &lt;/action-mappings&gt;<br />&lt;/struts-config&gt;</pre></td></tr></tbody></table><br /><br />4.3 registration模块配置文件 
<br /><br />下面是registration模块的配置文件，定义了form和action，以及相应的message-resources和forward。 
<br /><br /><ccid_nobr></ccid_nobr><table bordercolordark="#ffffff" bordercolorlight="#000000" align="center" border="1" cellpadding="2" cellspacing="0" width="400"><tbody><tr><td class="code" style="font-size: 9pt;" bgcolor="#e6e6e6"><pre><ccid_code></ccid_code>&lt;?xml version="1.0" encoding="UTF-8"?&gt;<br />&lt;!DOCTYPE struts-config PUBLIC "-//Apache Software Foundation//<br />                              DTD Struts Configuration 1.1//EN" <br />"http://jakarta.apache.org/struts/dtds/struts-config_1_1.dtd"&gt;<br />&lt;struts-config&gt;<br />    &lt;form-beans&gt;<br />        &lt;form-bean name="registrationForm" type="com.i505.struts.registration.form.RegistrationForm" /&gt;<br />            &lt;/form-beans&gt;<br />      &lt;action-mappings&gt;<br />        &lt;action<br />            attribute="registrationForm"<br />            input="/index.jsp"<br />            name="registrationForm"<br />            path="/registration"<br />            type="com.i505.struts.registration.action.RegistrationAction"&gt;<br />             &lt;forward name="success" path="/resultok.jsp" /&gt;<br />        &lt;/action&gt;<br />    &lt;/action-mappings&gt;<br />    &lt;message-resources    parameter="com.i505.struts.ApplicationResources"/&gt;<br />    &lt;/struts-config&gt;</pre></td></tr></tbody></table><br /><br /><a name="2"><b>5、模块选择</b></a><br /><br />本节主要讲述struts中如何选择模块，实现模块的真正运作的。 
<br /><br />5.1 action的模块选择 
<br /><br />当我们在浏览器中使用http://hostaddress/contextpath/module/action.do式样的的url时,actionservlet会根据module选择模块对象，下面是actionservlet处理http请求的代码： 
<br /><br /><ccid_nobr></ccid_nobr><table bordercolordark="#ffffff" bordercolorlight="#000000" align="center" border="1" cellpadding="2" cellspacing="0" width="400"><tbody><tr><td class="code" style="font-size: 9pt;" bgcolor="#e6e6e6"><pre><ccid_code></ccid_code>protected void process(HttpServletRequest request,<br />                           HttpServletResponse response)<br />        throws IOException, ServletException {<br />        RequestUtils.selectModule(request, getServletContext());<br />             getRequestProcessor(getModuleConfig(request)).process<br />            (request, response);<br />    }</pre></td></tr></tbody></table><br /><br />RequestUtils.selectModule函数将使用下面的代码把url中的模块前缀（下面代码的prefix将代表上面url式样中的/module）指定的模块对象保存在request属性中，这个模块对象就成了处理这个请求的当前模块对象： 
<br /><br /><ccid_nobr></ccid_nobr><table bordercolordark="#ffffff" bordercolorlight="#000000" align="center" border="1" cellpadding="2" cellspacing="0" width="400"><tbody><tr><td class="code" style="font-size: 9pt;" bgcolor="#e6e6e6"><pre><ccid_code></ccid_code>// Expose the resources for this module<br />        ModuleConfig config = (ModuleConfig)<br /> context.getAttribute(Globals.MODULE_KEY + prefix);<br />        if (config != null) {<br />            request.setAttribute(Globals.MODULE_KEY, config);<br />        }<br /> else {<br />            request.removeAttribute(Globals.MODULE_KEY);<br />        }</pre></td></tr></tbody></table><br /><br />5.2 资源的模块化 
<br /><br />资源（比如jsp）的模块化是指资源可以按照模块一样来组织，比如approval模块的资源可以放在approval目录下，而registration模块的资源则放在registration目录下，缺省模块的资源放在webroot下。 
<br /><br />url访问这些资源很简单,url式样是
http://hostaddress/contextpath/module/xxx.jsp。对于input和forward访问这些资源，我们只需
直接写相对于模块路径下的路径，注意它们必须以”/”开头。如果forward是相对servletcontext的，则要加上模块路径。 <br /><br /><ccid_nobr></ccid_nobr><table bordercolordark="#ffffff" bordercolorlight="#000000" align="center" border="1" cellpadding="2" cellspacing="0" width="400"><tbody><tr><td class="code" style="font-size: 9pt;" bgcolor="#e6e6e6"><pre><ccid_code></ccid_code>&lt;action-mappings&gt;<br />        &lt;action<br />            attribute="registrationForm"<br />            input="/index.jsp"<br />            name="registrationForm"<br />            path="/registration"<br />            type="com.i505.struts.registration.action.RegistrationAction"&gt;<br />             &lt;forward name="success" path="/resultok.jsp" /&gt;<br />        &lt;/action&gt;<br />    &lt;/action-mappings&gt;</pre></td></tr></tbody></table><br /><br />5.3 Formtag中表单action url的生成 
<br /><br />对于模块编程，struts在formtag的action属性好像有些问题，这些问题出现在struts没有考虑直接访问jsp时的情况。应为
forward和直接访问这两种环境是不同的，主要是直接访问这些JSP，request属性中没有模块对象，而forward访问这些jsp时
request属性中有模块对象。我们需要修改代码，使得在产生action属性时不受jsp所在环境的影响，也就是我们将在formtag的
action属性中指定模块，而不是request中得到模块。下面是registration模块的index.jsp的代码，它的formtag的
action属性包括了模块的前缀/registration： <br /><br /><ccid_nobr></ccid_nobr><table bordercolordark="#ffffff" bordercolorlight="#000000" align="center" border="1" cellpadding="2" cellspacing="0" width="400"><tbody><tr><td class="code" style="font-size: 9pt;" bgcolor="#e6e6e6"><pre><ccid_code></ccid_code>&lt;%@ taglib uri="/WEB-INF/struts-bean.tld" prefix="bean"%&gt;<br /> &lt;%@ taglib uri="/WEB-INF/struts-html.tld" prefix="html"%&gt;<br /> &lt;head&gt;<br />&lt;title&gt;申请注册&lt;/title&gt;<br />&lt;%@ page contentType="text/html;charset=GB2312" %&gt;<br /> &lt;/head&gt;<br />&lt;body&gt;<br />&lt;html:form action="/registration/registration.do" &gt;<br />      姓名：&lt;html:text property="name" /&gt;&lt;html:errors property="name"/&gt;&lt;br /&gt;&lt;br /&gt;<br />      年龄：&lt;html:text property="age" /&gt;&lt;html:errors property="age"/&gt;&lt;br /&gt;&lt;br /&gt;<br />      &lt;html:submit /&gt;<br />&lt;/html:form&gt;<br />&lt;/body&gt;<br />&lt;/html&gt;</pre></td></tr></tbody></table><br /><br />下面我们来修改struts的相关代码达到这个效果。 
<br /><br />5.3.1 Formtag 
<br /><br />Formtag的setAction将识别form tag的acton属性的module前缀，并分离出真正的模块相对的action路径，lookup将直接从ServletContext中获取模块配置对象。 
<br /><br /><ccid_nobr></ccid_nobr><table bordercolordark="#ffffff" bordercolorlight="#000000" align="center" border="1" cellpadding="2" cellspacing="0" width="400"><tbody><tr><td class="code" style="font-size: 9pt;" bgcolor="#e6e6e6"><pre><ccid_code></ccid_code>private String getActionPath(String action) {<br />            String temp = action.trim();<br />            String x;      <br />               int pos=0;<br />            if(!temp.startsWith("/")) temp = "/"+ temp;<br />            pos = temp.indexOf("/", 1);<br />            if(pos&lt;=0) return action;<br />                        <br />                  return temp.substring(pos);      }<br />private String getModulePrefix(String action) {<br />            String result;<br />            int pos;<br />            String temp=action.trim();<br />            if(!temp.startsWith("/")) {<br />                  temp= "/"+temp;<br />            }<br />            pos = temp.indexOf("/", 1);<br />            if(pos&lt;=1) return "";<br />            else<br />              return temp.substring(0, pos);<br />                  }<br />public void setAction(String action)<br /> {this.modulePrefix = this.getModulePrefix(action);<br />            this.action = this.getActionPath(action);<br />    }<br />protected void lookup() throws JspException {<br />            //我们直接从ServletContext中获取模块配置对象<br />                  moduleConfig = (ModuleConfig)<br /> pageContext.getServletContext().getAttribute(Globals.MODULE_KEY + modulePrefix);<br />      …}<br />     rotected String renderFormStartElement() {<br />        HttpServletResponse response =<br />            (HttpServletResponse) this.pageContext.getResponse();<br />                    StringBuffer results = new StringBuffer("&lt;form");<br />        results.append(" name=\"");<br />        results.append(beanName);<br />        results.append("\""); <br />       results.append(" method=\"");<br />        results.append(method == null ? "post" : method);<br />        results.append("\" action=\"");<br />//我们的action已经去掉了modulePrefix，所以我们得重新加上<br />       results.append(<br />            response.encodeURL(<br />                RequestUtils.getActionMappingURL(this.modulePrefix+ this.action, this.pageContext)));<br />         …<br />}</pre></td></tr></tbody></table><br /><br />5.3.2 Requestutils 
<br /><br />Requestutils的getActionMappingURL主要用作附加servletcontext 路径，因为我们现在在action参数附加了modulePrefix路径，所以没必要再追加模块前缀。 
<br /><br /><ccid_nobr></ccid_nobr><table bordercolordark="#ffffff" bordercolorlight="#000000" align="center" border="1" cellpadding="2" cellspacing="0" width="400"><tbody><tr><td class="code" style="font-size: 9pt;" bgcolor="#e6e6e6"><pre><ccid_code></ccid_code>public static String getActionMappingURL(String action, PageContext pageContext)<br /> {<br />        HttpServletRequest request = (HttpServletRequest) pageContext.getRequest();<br />        StringBuffer value = new StringBuffer(request.getContextPath());<br />        ModuleConfig config =<br />            (ModuleConfig) pageContext.getRequest().getAttribute(Globals.MODULE_KEY);<br />//我们jsp中的formtag的action属性已经表示了模块，所以我们不能再追加模块名//<br /> if (config != null) { <br />      //<br />     value.append(config.getPrefix());<br />       // }<br />        // Use our servlet mapping, if one is specified<br />        String servletMapping =<br />            (String) pageContext.getAttribute(Globals.SERVLET_KEY,<br /> PageContext.APPLICATION_SCOPE);<br />        if (servletMapping != null) {<br />            String queryString = null;<br />            int question = action.indexOf("?");<br />            if (question &gt;= 0) {<br />                queryString = action.substring(question);<br />            }<br />            String actionMapping = getActionMappingName(action);<br />            if (servletMapping.startsWith("*.")) {<br />                value.append(actionMapping);<br />                value.append(servletMapping.substring(1));<br />            } else if (servletMapping.endsWith("/*")) {<br />                value.append(servletMapping.substring(0, servletMapping.length() - 2));<br />                value.append(actionMapping);<br />            } else if (servletMapping.equals("/")) {<br />                value.append(actionMapping);<br />            }<br />            if (queryString != null) {<br />                value.append(queryString);<br />            }<br />        }<br />        else {<br />            if (!action.startsWith("/")) {<br />                value.append("/");<br />            }<br />            value.append(action);<br />        }<br />        // Return the completed value<br />        return (value.toString());<br />     }</pre></td></tr></tbody></table><br /><br /><a name="3"><b>6、总结</b></a><br /><br />模块化编程有利于提高编程效率，但是struts中的模块化支持有些小问题，本文详细分析了struts支持模块化编程的机制，并作了些修改，希
望对大家有帮助。另外如果我们可以把其改进为模块化的相关的东西可以打成一个包进行动态部署（比如approval.mar）的话，那将会更加有用。
<img src ="http://www.blogjava.net/jdo/aggbug/134926.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jdo/" target="_blank">蓝色幽默</a> 2007-08-07 13:10 <a href="http://www.blogjava.net/jdo/articles/134926.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>