﻿<?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-javaGrowing-随笔分类-struts学习</title><link>http://www.blogjava.net/juhongtao/category/6224.html</link><description /><language>zh-cn</language><lastBuildDate>Fri, 02 Mar 2007 03:30:21 GMT</lastBuildDate><pubDate>Fri, 02 Mar 2007 03:30:21 GMT</pubDate><ttl>60</ttl><item><title>在Struts中使用JavaBean和List（多行数据）类型属性</title><link>http://www.blogjava.net/juhongtao/archive/2006/12/14/87619.html</link><dc:creator>javaGrowing</dc:creator><author>javaGrowing</author><pubDate>Thu, 14 Dec 2006 01:28:00 GMT</pubDate><guid>http://www.blogjava.net/juhongtao/archive/2006/12/14/87619.html</guid><wfw:comment>http://www.blogjava.net/juhongtao/comments/87619.html</wfw:comment><comments>http://www.blogjava.net/juhongtao/archive/2006/12/14/87619.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/juhongtao/comments/commentRss/87619.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/juhongtao/services/trackbacks/87619.html</trackback:ping><description><![CDATA[ 在 Strust 中，我们可能经常要在 ActionForm 中使用其他 JavaBean 作为属性类型，这里就存在着如何使用好这些属性与 HTML Form 之间的数据交换，下面我们就这些问题做一讲解。<br /><br />如在用户注册界面中，我们通常会将用户的联系方式形成一个单独的新的 Class ，如 Contact ，包含以下属性：电话 (tel) ，手机(cell) ， Email(email) ， QQ(qq) ，通信地址 (adress) 等等，这样条理也比较清晰，以下是这个ActionForm 的部分代码：<br /><br />public class RegisterForm extends ActionForm<br /><br />{<br /><br />private Integer id;<br /><br />private String logonName;<br /><br />private String realName;<br /><br />private Contact contact=new Contact();<br /><br />………..<br /><br />}<br /><br />在这里我们需要将 Contact 实例化（在 reset 函数中需要重新实例化），这主要因为 Struts 的机制：如我们将 HTML 的Form 元素（如 email ）值传给 ActionForm ， Struts 需要执行的操作是getContact().setEmail(String email) ，如果这时返回的 contact 对象为空的话，那么赋值如何进行，而且Struts 也不会知道如何去实例化 Contact ，有时这些 JavaBean 的类型有可能是接口，实例化更是未知，所以关于JavaBean 类型在 ActionForm 中的实例化，你需要自行完成，而且必须完成。至于在实际操作中判断 JavaBean是否被进行过相关操作（不再是初始状态），你需要自行判断，其实也很简单，如可在 Contact 类中编写一个函数检验一下即可。<br /><br />ActionForm 创建完毕后，我们需要在 Jsp Form 中引用这些 JavaBean 类型的属性值，那就很简单啦，只需采用“ Form 的属性名称”＋“ . ”＋“ JavaBean 中的属性名称”结构构成的名称付给相关元素即可。如：<br /><br />&lt;html:text property="contact.email"&gt;<br /><br />通过这种方式我们就可以处理好 ActionForm 中的 JavaBean 类型的属性值了。<br /><br />实际的情况可能更复杂些，我们有时可能要提交多行数据到后退，而且行内的数据是相关的，如我们需要提交多个用户的联系方式，这些行内的数据，如email ，电话，手机，这些数据都是和用户编码相关的，现在我们修改一下 Contact 类，添加一个用户编码 (userId)属性，这时我们构建的 ActionForm 中可能需要一个列表数据（ List ）类型来处理这种情况。以下是这个 ActionForm的部分代码：<br /><br />public class ModifyBatchContactForm extends ActionForm<br /><br />{<br /><br />private List contact =new AutoArrayList (Contact.class);<br /><br />…..<br /><br />}<br /><br />在以上代码中，我们同样处理了 List 类型数据的初始化。 Struts 在给 List 中的对象赋值时，当然需要先获取 List数据，然后在获取 List 中某一个对象（通过 Index），最后给对象赋值。在这里想我们可以更详细点分析浏览器端传过来数据，字段值形式如下：contact[0].email= linux_china@hotmail.com ， Struts 获取 ActionForm 中的 List数据后，通过 Index （此时为 0 ）来获取 List 中封装的 JavaBean 对象，然而此时 List是空的（尽管初始化了，但是没有数据），是无法取得封装的对象的，因此我们要在 Struts 获取 List中封装的对象的时候给它创建一个，这样就保证对象的获取和赋值的成功进行，所有我们新建一个 AutoArrayList 类，继承ArrayList ，只要重写 get(int index) 方法即可，其实很简单，代码如下：<br /><br />public class AutoArrayList extends ArrayList {<br /><br />private Class itemClass;<br /><br />public AutoArrayList(Class itemClass) {<br /><br />this.itemClass = itemClass;<br /><br />}<br /><br />public Object get(int index) {<br /><br />try {<br /><br />while (index &amp;gt;= size()) {<br /><br />add( itemClass.newInstance());<br /><br />}<br /><br />} catch (Exception e) {<br /><br />e.printStackTrace();<br /><br />}<br /><br />return super.get(index);<br /><br />}<br /><br />}<br /><br />这样我们就完成可以多行数据提交的 ActionForm设计，这里还有点提醒，如果从浏览器端传过来的行索引是跳跃是的，如缺少中间行，而你不想要这些数据的话，且首尾行 index相差很大的话，这种方式可能不太适合。这种多行提交形式比较适合对固定行的数据处理。如果行数不固定的话，你可以参考使用 MapForm 方式实现。<br /><br />下面我们就看看如何在 Jsp 中使用这个 ActionForm ，其实只需要执行一个循环即可：<br /><br />&lt;logic:iterate id=" contact " name=" FormName " property=" contact " indexid="index"&gt;<br /><br />&lt;html:text name=" contact " property="userId" indexed="true"&gt;<br /><br />&lt;html:text name=" contact " property="email" indexed="true"&gt;<br /><br />&lt;/html:text&gt;<br /><br />这里我们再讲解一下，代码中出现的“ contact ”（红色）都是 ActionForm 中的 List数据类型变量名称，请确保一致，请不要更改名称，这也是方便提交到后台的数据接收。“ FormName ”为在 struts-config中声明的 ActionForm 名称。 indexed="true" 可以确保生成的 html 元素的名称唯一，不要缺少这个声明。以上的Jsp 代码，你也可以使用 JSTL 来完成，就看你习惯如何了。<br /><br />通过以上步骤，我们完成了多行数据的提交所有环节，这样 Struts 就会完成其他所有的事情，我们的代码逻辑和实现也简单多了。<br /><br />总结：通过以上两个例子，相以信对 ActionForm 中使用 JavaBean 和 List 类型数据不会再陌生，同时使用 Map类型，这样可创建更好的 ActionForm 设计，关于 MapForm ，请参考http://www.jetmaven.net/documents/j_mapformInStruts.php 。不过引入这种方式后，在Validator 方面你可能要花点脑筋啦（如通过 XDoclet 生成 Validator文件可能功能不全），可能你需要手写一些代码来完成相关工作&lt;/html:text&gt;&lt;/logic:iterate&gt;&lt;/html:text&gt;<img src ="http://www.blogjava.net/juhongtao/aggbug/87619.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/juhongtao/" target="_blank">javaGrowing</a> 2006-12-14 09:28 <a href="http://www.blogjava.net/juhongtao/archive/2006/12/14/87619.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>扩展Struts</title><link>http://www.blogjava.net/juhongtao/archive/2005/12/30/25994.html</link><dc:creator>javaGrowing</dc:creator><author>javaGrowing</author><pubDate>Fri, 30 Dec 2005 01:48:00 GMT</pubDate><guid>http://www.blogjava.net/juhongtao/archive/2005/12/30/25994.html</guid><wfw:comment>http://www.blogjava.net/juhongtao/comments/25994.html</wfw:comment><comments>http://www.blogjava.net/juhongtao/archive/2005/12/30/25994.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/juhongtao/comments/commentRss/25994.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/juhongtao/services/trackbacks/25994.html</trackback:ping><description><![CDATA[<center>作者：Sunil Patil</center><br><center>翻译：<a href="http://www.matrix.org.cn/user.shtml?username=loryliu" target="_new">loryliu</a></center><br><br><span style="color: Purple;">版权声明</span>：可以任意转载，转载时请务必以超链接形式标明文章原始出处和作者信息及本声明<br>作者:<br>Sunil Patil;<a href="http://www.matrix.org.cn/user.shtml?username=loryliu" target="_new">loryliu</a><br>原文地址:<br><a href="http://www.onjava.com/pub/a/onjava/2004/11/10/ExtendingStruts.html" target="_new">http://www.onjava.com/pub/a/onjava/2004/11/10/ExtendingStruts.html</a><br>中文地址:<br><a href="http://www.matrix.org.cn/resource/article/43/43857_Struts.html" target="_new">http://www.matrix.org.cn/resource/article/43/43857_Struts.html</a><br>关键词： extending Struts<br><br><br><b><span style="font-size: 16px;">简介</span></b><br><br>我
见过许多项目开发者实现自己专有的MVC框架。这些开发者并不是因为想实现不同于Struts的某些功能，而是还没有意识到怎么去扩展Struts。通过
开发自己的MVC框架，你可以掌控全局，但同时这也意味着你必须付出很大的代价；在项目计划很紧的情况下也许根本就不可能实现。<br><br>Struts不但功能强大也易于扩展。你可以通过三种方式来扩展Struts:<br><br>1.PlugIn：在应用启动或关闭时须执行某业务逻辑，创建你自己的PlugIn类<br><br>2.RequestProcessor：在请求处理阶段一个特定点欲执行某业务逻辑，创建你自己的RequestProcessor。例如：你想继承RequestProcessor来检查用户登录及在执行每个请求时他是否有权限执行某个动作。<br><br>3.ActionServlet：在应用启动或关闭或在请求处理阶段欲执行某业务逻辑，继承ActionServlet类。但是必须且只能在PligIn和RequestProcessor都不能满足你的需求时候用。<br><br>本文会列举一个简单的Struts应用来示范如何使用以上三种方式扩展Struts。在本文末尾资源区有每种方式的可下载样例源代码。Struts Validation 框架和 Tiles 框架是最成功两个的Struts扩展例子。<br><br>我是假设读者已经熟悉Struts框架并知道怎样使用它创建简单的应用。如想了解更多有关Struts的资料请参见资源区。<br><br><b><span style="font-size: 16px;">PlugIn</span></b><br><br>根据Struts文档，“PlugIn是一个须在应用启动和关闭时需被通知的模块定制资源或服务配置包”。这就是说，你可以创建一个类，它实现PlugIn的接口以便在应用启动和关闭时做你想要的事。<br><br>假
如创建了一个web应用，其中使用Hibernate做为持久化机制；当应用一启动，就需初始化Hinernate，这样在web应用接收到第一个请求
时，Hibernate已被配置完毕并待命。同时在应用关闭时要关闭Hibernate。跟着以下两步可以实现Hibernate PlugIn的需求。<br><br>1.创建一个实现PlugIn接口的类，如下：<br><br><pre class="overflow">public class HibernatePlugIn implements PlugIn{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;private String configFile;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// This method will be called at application shutdown time<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public void destroy() {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println("Entering HibernatePlugIn.destroy()");<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//Put hibernate cleanup code here<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println("Exiting HibernatePlugIn.destroy()");<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//This method will be called at application startup time<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public void init(ActionServlet actionServlet, ModuleConfig config)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;throws ServletException {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println("Entering HibernatePlugIn.init()");<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println("Value of init parameter " +<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;getConfigFile());<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println("Exiting HibernatePlugIn.init()");<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public String getConfigFile() {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return name;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public void setConfigFile(String string) {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;configFile = string;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br>}</pre><br><br>实现PlugIn接口的类必须是实现以下两个方法：<br>init()
和destroy().。在应用启动时init()被调用，关闭destroy()被调用。Struts允许你传入初始参数给你的PlugIn类；为了传
入参数你必须在PlugIn类里为每个参数创建一个类似JavaBean形式的setter方法。在HibernatePlugIn类里，欲传入
configFile的名字而不是在应用里将它硬编码进去<br><br>2.在struts-condig.xml里面加入以下几行告知Struts这个新的PlugIn<br><br><pre class="overflow">&lt;struts-config&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;...<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;!-- Message Resources --&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;message-resources parameter=<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"sample1.resources.ApplicationResources"/&gt;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;!-- Declare your plugins --&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;plug-in className="com.sample.util.HibernatePlugIn"&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;set-property property="configFile"<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; value="/hibernate.cfg.xml"/&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/plug-in&gt;<br>&lt;/struts-config&gt;</pre><br>ClassName
属性是实现PlugIn接口类的全名。为每一个初始化传入PlugIn类的初始化参数增加一个&lt;set-property&gt;元素。在这个例子
里，传入config文档的名称，所以增加了一个config文档路径的&lt;set-property&gt;元素。<br><br>Tiles和Validator框架都是利用PlugIn给初始化读入配置文件。另外两个你还可以在PlugIn类里做的事情是：<br><br>假如应用依赖于某配置文件，那么可以在PlugIn类里检查其可用性，假如配置文件不可用则抛出ServletException。这将导致ActionServlet不可用。<br><br>PlugIn接口的init()方法是你改变ModuleConfig方法的最后机会，ModuleConfig方法是描述基于Struts模型静态配置信息的集合。一旦PlugIn被处理完毕，Struts就会将ModuleCOnfig冻结起来。<br><br><b><span style="font-size: 16px;">请求是如何被处理的</span></b><br><br>ActionServlet
是Struts框架里唯一一个Servlet，它负责处理所有请求。它无论何时收到一个请求，都会首先试着为现有请求找到一个子应用。一旦子应用被找到，
它会为其生成一个RequestProcessor对象，并调用传入HttpServletRequest和HttpServletResponse为参
数的process()方法。<br><br>大部分请处理都是在RequestProcessor.process()发生的。Process()方法
是以模板方法（Template
Method）的设计模式来实现的，其中有完成request处理的每个步骤的方法；所有这些方法都从process()方法顺序调用。例如，寻找当前请
求的ActionForm类和检查当前用户是否有权限执行action
mapping都有几个单独的方法。这给我们提供了极大的弹性空间。Struts的RequestProcessor对每个请求处理步骤都提供了默认的实
现方法。这意味着，你可以重写你感兴趣的方法，而其余剩下的保留默认实现。例如，Struts默认调用request.isUserInRole()检查
用户是否有权限执行当前的ActionMapping，但如果你需要从数据库中查找，那么你要做的就是重写processRoles()方法，并根据用户
角色返回true 或 false。<br><br>首先我们看一下process()方法的默认实现方式，然后我将解释RequestProcessor类里的每个默认的方法，以便你决定要修改请求处理的哪一部分。<br><br><pre class="overflow">public void process(HttpServletRequest request,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;HttpServletResponse response)<br>&nbsp;&nbsp;&nbsp;&nbsp;throws IOException, ServletException {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// Wrap multipart requests with a special wrapper<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;request = processMultipart(request);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// Identify the path component we will<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// use to select a mapping<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;String path = processPath(request, response);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (path == null) {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (log.isDebugEnabled()) {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;log.debug("Processing a '" + request.getMethod() +<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"' for path '" + path + "'");<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// Select a Locale for the current user if requested<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;processLocale(request, response);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// Set the content type and no-caching headers<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// if requested<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;processContent(request, response);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;processNoCache(request, response);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// General purpose preprocessing hook<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (!processPreprocess(request, response)) {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// Identify the mapping for this request<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ActionMapping mapping =<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;processMapping(request, response, path);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (mapping == null) {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// Check for any role required to perform this action<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (!processRoles(request, response, mapping)) {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// Process any ActionForm bean related to this request<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ActionForm form =<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;processActionForm(request, response, mapping);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;processPopulate(request, response, form, mapping);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (!processValidate(request, response, form, mapping)) {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// Process a forward or include specified by this mapping<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (!processForward(request, response, mapping)) {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (!processInclude(request, response, mapping)) {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// Create or acquire the Action instance to<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// process this request<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Action action =<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;processActionCreate(request, response, mapping);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (action == null) {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// Call the Action instance itself<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ActionForward forward =<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;processActionPerform(request, response,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;action, form, mapping);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// Process the returned ActionForward instance<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;processForwardConfig(request, response, forward);<br>&nbsp;&nbsp;&nbsp;&nbsp;}</pre><br><br><br><b>1、processMultipart(): </b>在
这个方法中，Struts读取request以找出contentType是否为multipart/form-data。假如是，则解析并将其打包成一
个实现HttpServletRequest的包。当你成生一个放置数据的HTML
FORM时，request的contentType默认是application/x-www-form-urlencoded。但是如果你的form
的input类型是FILE-type允许用户上载文件，那么你必须把form的contentType改为multipart/form-data。如
这样做，你永远不能通过HttpServletRequest的getParameter()来读取用户提交的form值；你必须以
InputStream的形式读取request，然后解析它得到值。<br><br><b>2、processPath():</b> 在这个方法中，Struts将读取request的URI以判断用来得到ActionMapping元素的路径。<br><br><b>3、processLocale():</b>
在这个方法中，Struts将得到当前request的Locale；Locale假如被配置，将作为
org.apache.struts.action.LOCALE属性的值被存入HttpSession。这个方法的附作用是HttpSession会被
创建。假如你不想此事发生，可将在struts-config.xml
文件里ControllerConfig的local属性设置为false,如下：<br><pre class="overflow">&lt;controller&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;set-property property="locale" value="false"/&gt;<br>&lt;/controller&gt;</pre><br><br><b>4、processContent()：</b>通过调用response.setContentType()设置response的contentType。这个方法首先会试着的得到配置在struts-config.xml里的contentType。默认为text/html，重写方法如下：<br><pre class="overflow">&lt;controller&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;set-property property="contentType" value="text/plain"/&gt;<br>&lt;/controller&gt;</pre><br><br><b>5、processNoCache()：</b>Struts将为每个response的设置以下三个header，假如已在struts 的config.xml将配置为no-cache。<br><pre class="overflow">response.setHeader("Pragma", "No-cache");<br>response.setHeader("Cache-Control", "no-cache");<br>response.setDateHeader("Expires", 1);</pre><br><br>假如你想设置为no-cache header，在struts-config.xml中加如以下几行<br><pre class="overflow">&lt;controller&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;set-property property="noCache" value="true"/&gt;<br>&lt;/controller&gt;</pre><br><br><b>6、processPreprocess()：</b>这是一个一般意义的预处理hook，其可被子类重写。在RequestProcessor里的实现什么都没有做，总是返回true。如此方法返回false会中断请求处理。<br><br><b>7、processMapping():</b>这个方法会利用path信息找到ActionMapping对象。ActionMapping对象在struts-config.xml file文件里表示为&lt;action&gt;<br><pre class="overflow">&lt;action path="/newcontact" type="com.sample.NewContactAction"<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;name="newContactForm" scope="request"&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;forward name="sucess" path="/sucessPage.do"/&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;forward name="failure" path="/failurePage.do"/&gt;<br>&lt;/action&gt;</pre><br><br>ActionMapping元素包含了如Action类的名称及在请求中用到的ActionForm的信息，另外还有配置在当前ActionMapping的里的ActionForwards信息。<br><br><b>8、processRoles():</b> Struts的web 应用安全提供了一个认证机制。这就是说，一旦用户登录到容器，Struts的processRoles()方法通过调用request.isUserInRole()可以检查他是否有权限执行给定的ActionMapping。<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;action path="/addUser" roles="administrator"/&gt;<br><br>假如你有一个AddUserAction，限制只有administrator权限的用户才能新添加用户。你所要做的就是在AddUserAction 的action元素里添加一个值为administrator的role属性。<br><br><b>9、processActionForm()：</b>每个ActionMapping都有一个与它关联的ActionForm类。struts在处理ActionMapping时，他会从&lt;action&gt;里name属性找到相关的ActionForm类的值。<br><pre class="overflow">&lt;form-bean name="newContactForm" <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; type="org.apache.struts.action.DynaActionForm"&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;form-property name="firstName"<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;type="java.lang.String"/&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;form-property name="lastName"<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;type="java.lang.String"/&gt;<br>&lt;/form-bean&gt;</pre><br><br>在这个例子里，首先会检查org.apache.struts.action.DynaActionForm类的对象是否在request 范围内。如是，则使用它，否则创建一个新的对象并在request范围内设置它。<br><br><b>10、processPopulate():：</b>在这个方法里，Struts将匹配的request parameters值填入ActionForm类的实例变量中。<br><br><b>11、processValidate()：</b>Struts将调用ActionForm的validate()方法。假如validate()返回ActionErrors，Struts将用户转到由&lt;action&gt;里的input属性标示的页面。<br><br><b>12、processForward() and processInclude()：</b>在这两个方法里，Struts检查&lt;action&gt;元素的forward和include属性的值，假如有配置，则把forward和include 请求放在配置的页面内。<br><pre class="overflow">&lt;action forward="/Login.jsp" path="/loginInput"/&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;action include="/Login.jsp" path="/loginInput"/&gt;</pre><br><br>你
可以从他们的名字看出其不同之处。processForward()调用RequestDispatcher.forward(),，
processInclude()调用RequestDispatcher.include()。假如你同时配置了orward 和include
属性，Struts总会调用forward，因为forward,是首先被处理的。<br><br><b>13、processActionCreate()：</b>这个方法从&lt;action&gt;的type属性得到Action类名，并创建返回它的实例。在这里例子中struts将创建一个com.sample.NewContactAction类的实例。<br><br><b>14、processActionPerform()：</b>这个方法调用Action 类的execute()方法，其中有你写入的业务逻辑。<br><br><b>15、processForwardConfig()：</b>Action类的execute()将会返回一个ActionForward类型的对象，指出哪一页面将展示给用户。因此Struts将为这个页面创建RequestDispatchet，然后再调用RequestDispatcher.forward()方法。<br><br>以
上列出的方法解释了RequestProcessor在请求处理的每步默认实现及各个步骤执行的顺序。正如你所见，RequestProcessor很有
弹性，它允许你通过设置&lt;controller&gt;里的属性来配置它。例如，假如你的应用将生成XML内容而不是HTML，你可以通过设置
controller的某个属性来通知Struts。<br><br><b><span style="font-size: 16px;">创建你自己的RequestProcessor</span></b><br><br>从
以上内容我们已经明白了RequestProcessor的默认实现是怎样工作的，现在我将通过创建你自己的RequestProcessor.展示一个
怎样自定义RequestProcessor的例子。为了演示创建一个自定义RequestProcessor，我将修改例子实现以下连个业务需求：<br><br>我们要创建一个ContactImageAction类，它将生成images而不是一般的HTMl页面<br><br>在处理这个请求之前，将通过检查session里的userName属性来确认用户是否登录。假如此属性没有被找到，则将用户转到登录页面。<br><br><br>分两步来实现以上连个业务需求。<br>创建你自己的CustomRequestProcessor类，它将继承RequestProcessor类，如下：<br><br><pre class="overflow">public class CustomRequestProcessor<br>&nbsp;&nbsp;&nbsp;&nbsp;extends RequestProcessor {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;protected boolean processPreprocess (<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;HttpServletRequest request,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;HttpServletResponse response) {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;HttpSession session = request.getSession(false);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//If user is trying to access login page<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// then don't check<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if( request.getServletPath().equals("/loginInput.do")<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|| request.getServletPath().equals("/login.do") )<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return true;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//Check if userName attribute is there is session.<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//If so, it means user has allready logged in<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if( session != null &amp;&amp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;session.getAttribute("userName") != null)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return true;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;try{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//If no redirect user to login Page<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;request.getRequestDispatcher <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;("/Login.jsp").forward(request,response);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}catch(Exception ex){<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return false;<br>&nbsp;&nbsp;&nbsp;&nbsp;}<br><br>&nbsp;&nbsp;&nbsp;&nbsp;protected void processContent(HttpServletRequest request,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;HttpServletResponse response) {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//Check if user is requesting ContactImageAction<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// if yes then set image/gif as content type<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if( request.getServletPath().equals("/contactimage.do")){<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;response.setContentType("image/gif");<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;super.processContent(request, response);<br>&nbsp;&nbsp;&nbsp;&nbsp;}<br>}</pre><br><br>在CustomRequestProcessor 类的processPreprocess方法里，检查session的userName属性，假如没有找到，将用户转到登录页面。<br><br>对
于产生images作为ContactImageAction类的输出，必须要重写processContent方法。首先检查其request是否请求
/contactimage路径，如是则设置contentType为image/gif；否则为text/html。<br><br>加入以下几行代码到sruts-config.xml文件里的&lt;action-mapping&gt;后面，告知Struts ，CustomRequestProcessor应该被用作RequestProcessor类<br><br><pre class="overflow">&lt;controller&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;set-property&nbsp;&nbsp;property="processorClass"<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;value="com.sample.util.CustomRequestProcessor"/&gt;<br>&lt;/controller&gt;</pre><br><br>请
注意，假如你只是很少生成contentType不是text/html输出的Action类，重写processContent()就没有问题。如不是
这种情况，你必须创建一个Struts子系统来处理生成image&nbsp;&nbsp;Action的请求并设置contentType为image/gif<br><br>Title框架使用自己的RequestProcessor来装饰Struts生成的输出。<br><br><b>ActionServlet</b><br><br>假如你仔细研究Struts web应用的web.xml文件，它看上去像这样：<br><pre class="overflow">&lt;web-app &gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;servlet&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;servlet-name&gt;action=&lt;/servlet-name&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;servlet-class&gt;org.apache.struts.action.ActionServlet&lt;/servlet-class&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;!-- All your init-params go here--&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/servlet&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;servlet-mapping&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;servlet-name&gt;action&lt;/servlet-name&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;url-pattern&gt;*.do&lt;/url-pattern&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/servlet-mapping&gt;<br>&lt;/web-app &gt;</pre><br><br>这
就是说，ActionServlet负责处理所有发向Struts的请求。你可以创建ActionServlet的一个子类，假如你想在应用启动和关闭时
或每次请求时做某些事情。但是你必须在继承ActionServlet类前创建PlugIn 或 RequestProcessor。在Servlet
1.1前，Title框架是基于继承ActionServlet类来装饰一个生成的response。但从1.1开始，就使用
TilesRequestProcessor类。<br><br><span style="font-size: 16px;">结论</span><br><br>开发你自己的MVC模型是一个很大的决心——你必须考虑开发和维护代码的时间和资源。Struts是一个功能强大且稳定的框架，你可以修改它以使其满足你大部分的业务需求。<br><br>另一方面，也不要轻易地决定扩展Struts。假如你在RequestProcessor里放入一些低效率的代码，这些代码将在每次请求时执行并大大地降低整个应用的效率。当然总有创建你自己的MVC框架比扩展Struts更好的情况。<br><br><b>资源</b><br>下载本文源码：[<a href="http://www.matrix.org.cn/resource/article/43/resource/upload/forum/2005_10_11_235836_uOFYmvsYQp.zip">下载文件</a>] <br>Struts主页 <br>"Jakarta Struts框架介绍" <br>"学习Jakarta Struts 1.1" <br><br><br>Sunil Pail已从事J2EE四年，现今与IBM实验室合作。<img src ="http://www.blogjava.net/juhongtao/aggbug/25994.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/juhongtao/" target="_blank">javaGrowing</a> 2005-12-30 09:48 <a href="http://www.blogjava.net/juhongtao/archive/2005/12/30/25994.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>struts中文的解决</title><link>http://www.blogjava.net/juhongtao/archive/2005/12/27/25587.html</link><dc:creator>javaGrowing</dc:creator><author>javaGrowing</author><pubDate>Tue, 27 Dec 2005 07:56:00 GMT</pubDate><guid>http://www.blogjava.net/juhongtao/archive/2005/12/27/25587.html</guid><wfw:comment>http://www.blogjava.net/juhongtao/comments/25587.html</wfw:comment><comments>http://www.blogjava.net/juhongtao/archive/2005/12/27/25587.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/juhongtao/comments/commentRss/25587.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/juhongtao/services/trackbacks/25587.html</trackback:ping><description><![CDATA[<span class="javascript" id="text9057">
		 转自 <a href="http://www.javaresearch.org/" target="_blank" class="ilink">www.javaresearch.org</a><br>作者 fishandfly  <br><br>1.使<font style="background-color: rgb(255, 255, 0);"><b>ApplicationResources.properties</b></font>支持中文<br>建立一个ApplicationResources_ISO.properties文件，把应用程序用的message都写进去，然后在dos下执行这个命令，<br>native2ascii -encoding gb2312 ApplicationResources_ISO.properties <font style="background-color: rgb(255, 255, 0);"><b>ApplicationResources.properties</b></font><br>这样就会将ISO编码的ApplicationResources转换成GB2312编码的格式了，同时保存到<font style="background-color: rgb(255, 255, 0);"><b>ApplicationResources.properties</b></font>.<br>native2ascii这个工具是jdk自带的一个东东，所以如果path都设定正确就可以直接运行了，你可以在$java_home$/bin下找到他。<br>转换后的中文类似于这个样子<br>iso 格式下 ：tj.type=商品车类型<br>gb2312格式下 ：tj.type=\u5546\u54c1\u8f66\u7c7b\u578b<br>然后在struts-config.xml中设置应用这个资源文件<br>&lt;message-resources parameter="com.huahang.tj.ApplicationResources" key="org.apache.struts.action.MESSAGE" /&gt;<br>开发jsp时在jsp的开头写上&lt;%@ page contentType="text/html; charset=gb2312" %&gt;，将字符集设置成gb2312就可以了。<br><br>2.使数据库操作支持中文。<br>数据库操作支持中文一直让我比较头痛，但是感谢善解人衣向我推荐了www.chinaxp.org，这个网站是用struts框架开发的，而且<br>开放源码，下载了源码后发现它的中文处理得很好，阅读部分源码，没有发现什么特殊的字符集转换，很纳闷，偶然看到楼上网友<br>留言知道原来servlet可以统一设置字符转换。chinaxp.org就是这么做的。<br>在web.xml中加上<br>&lt;filter&gt;<br>&lt;filter-name&gt;Set Character Encoding&lt;/filter-name&gt;<br>&lt;filter-class&gt;com.huahang.tj.struts.filters.SetCharacterEncodingFilter&lt;/filter-class&gt;<br>&lt;init-param&gt;<br>&lt;param-name&gt;encoding&lt;/param-name&gt;<br>&lt;param-value&gt;GB2312&lt;/param-value&gt;<br>&lt;/init-param&gt;<br>&lt;init-param&gt;<br>&lt;param-name&gt;ignore&lt;/param-name&gt;<br>&lt;param-value&gt;true&lt;/param-value&gt;<br>&lt;/init-param&gt;<br>&lt;/filter&gt;<br>&lt;filter-mapping&gt;<br>&lt;filter-name&gt;Set Character Encoding&lt;/filter-name&gt;<br>&lt;servlet-name&gt;action&lt;/servlet-name&gt;<br>&lt;/filter-mapping&gt;<br>这里会涉及一个bean,源码如下：<br>/*<br>* XP Forum<br>* <br>* Copyright <img src="http://www.cjsdn.net/images/smiles/coffee_smile.gif" alt="Coffee" width="19"> 2002-2003 RedSoft Group. All rights reserved.<br>*<br>*/<br>package com.huahang.tj.struts.filters;<br><br>import javax.servlet.*;<br>import java.io.IOException;<br><br>/**<br>* &lt;p&gt;Filter that sets the character encoding to be used in parsing the<br>* incoming request, either unconditionally or only if the client did not<br>* specify a character encoding. Configuration of this filter is based on<br>* the following initialization parameters:&lt;/p&gt;<br>* &lt;ul&gt;<br>* &lt;li&gt;&lt;strong&gt;encoding&lt;/strong&gt; - The character encoding to be configured<br>* for this request, either conditionally or unconditionally based on<br>* the &lt;code&gt;ignore&lt;/code&gt; initialization parameter. This parameter<br>* is required, so there is no default.&lt;/li&gt;<br>* &lt;li&gt;&lt;strong&gt;ignore&lt;/strong&gt; - If set to "true", any character encoding<br>* specified by the client is ignored, and the value returned by the<br>* &lt;code&gt;selectEncoding()&lt;/code&gt; method is set. If set to "false,<br>* &lt;code&gt;selectEncoding()&lt;/code&gt; is called &lt;strong&gt;only&lt;/strong&gt; if the<br>* client has not already specified an encoding. By default, this<br>* parameter is set to "true".&lt;/li&gt;<br>* &lt;/ul&gt;<br>*<br>* &lt;p&gt;Although this filter can be used unchanged, it is also easy to<br>* subclass it and make the &lt;code&gt;selectEncoding()&lt;/code&gt; method more<br>* intelligent about what encoding to choose, based on characteristics of<br>* the incoming request (such as the values of the &lt;code&gt;Accept-Language&lt;/code&gt;<br>* and &lt;code&gt;User-Agent&lt;/code&gt; headers, or a value stashed in the current<br>* user's session.&lt;/p&gt;<br>*<br>* @author &lt;a href="mailto:jwtronics@yahoo.com"&gt;John Wong&lt;/a&gt;<br>*<br>* @version $Id: SetCharacterEncodingFilter.java,v 1.1 2002/04/10 13:59:27 johnwong Exp $<br>*/<br>public class SetCharacterEncodingFilter implements Filter {<br><br>// ----------------------------------------------------- Instance Variables<br><br>/**<br>* The default character encoding to set for requests that pass through<br>* this filter.<br>*/<br>protected String encoding = null;<br><br>/**<br>* The filter configuration object we are associated with. If this value<br>* is null, this filter instance is not currently configured.<br>*/<br>protected FilterConfig filterConfig = null;<br><br>/**<br>* Should a character encoding specified by the client be ignored?<br>*/<br>protected boolean ignore = true;<br><br>// --------------------------------------------------------- Public Methods<br><br>/**<br>* Take this filter out of service.<br>*/<br>public void destroy() {<br><br>this.encoding = null;<br>this.filterConfig = null;<br><br>}<br><br>/**<br>* Select and set (if specified) the character encoding to be used to<br>* interpret request parameters for this request.<br>*<br>* @param request The servlet request we are processing<br>* @param result The servlet response we are creating<br>* @param chain The filter chain we are processing<br>*<br>* @exception IOException if an input/output error occurs<br>* @exception ServletException if a servlet error occurs<br>*/<br>public void doFilter(ServletRequest request, ServletResponse response,<br>FilterChain chain)<br>throws IOException, ServletException {<br><br>// Conditionally select and set the character encoding to be used<br>if (ignore || (request.getCharacterEncoding() == null)) {<br>String encoding = selectEncoding(request);<br>if (encoding != null)<br>request.setCharacterEncoding(encoding);<br>}<br><br>// Pass control on to the next filter<br>chain.doFilter(request, response);<br><br>}<br><br>/**<br>* Place this filter into service.<br>*<br>* @param filterConfig The filter configuration object<br>*/<br>public void init(FilterConfig filterConfig) throws ServletException {<br><br>this.filterConfig = filterConfig;<br>this.encoding = filterConfig.getInitParameter("encoding");<br>String value = filterConfig.getInitParameter("ignore");<br>if (value == null)<br>this.ignore = true;<br>else if (value.equalsIgnoreCase("true"))<br>this.ignore = true;<br>else if (value.equalsIgnoreCase("yes"))<br>this.ignore = true;<br>else<br>this.ignore = false;<br><br>}<br><br>// ------------------------------------------------------ Protected Methods<br><br>/**<br>* Select an appropriate character encoding to be used, based on the<br>* characteristics of the current request and/or filter initialization<br>* parameters. If no character encoding should be set, return<br>* &lt;code&gt;null&lt;/code&gt;.<br>* &lt;p&gt;<br>* The default implementation unconditionally returns the value configured<br>* by the &lt;strong&gt;encoding&lt;/strong&gt; initialization parameter for this<br>* filter.<br>*<br>* @param request The servlet request we are processing<br>*/<br>protected String selectEncoding(ServletRequest request) {<br><br>return (this.encoding);<br><br>}<br><br>}//EOC<br>加上这个后，在action中就可以直接从form中接收gb2312编码的数据了，返回时自然也是gb2312了。<br>但是这个好像需要servlet 2.2以上的容器<br><br>综合上面的方法，我解决了struts中的中文问题，现在还没发现新的问题。<br><br>我的环境是<br>windows2000 Professional,tomcat 4.04 , struts1.1b2
			</span>
<br><img src ="http://www.blogjava.net/juhongtao/aggbug/25587.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/juhongtao/" target="_blank">javaGrowing</a> 2005-12-27 15:56 <a href="http://www.blogjava.net/juhongtao/archive/2005/12/27/25587.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>