定制Struts控制器组件
来源:互联网 发布:辽宁大学网络与新媒体 编辑:程序博客网 时间:2024/06/03 03:03
在Struts API中,org.apache.struts.action.RequestProcessor类真正包含了Struts控制器在处理servlet请求时所遵循的控制逻辑。控制器核心组件ActionServlet就是通过调用RequestProcessor对象的process()方法来委托其处理客户端请求的,该方法格式如下:
public void process(public void process(
javax.servlet.http.HttpServletRequest request,
javax.servlet.http.HttpServletResponse response)
throws java.io.IOException, javax.servlet.ServletException{ … }
RequestProcessor类中还定义了多个processXXX()方法,process()方法正是通过调用他们来具体的处理工作的。下表中对其中重要的几个做简单介绍:
表1 RequestProcessor类的主要处理方法
方 法 功 能
protected String processPath() 获取客户端请求的路径URI protected ActionForm processActionForm() 获取当前请求表单所映射的ActionForm Bean protected ActionMapping processMapping() 根据请求URI获取所需的映射信息 protected Action processActionCreate() 初始化相应的ActionBean protected ActionForward processActionPerform() 调用Action Bean的execute()方法处理请求 protected void processForwardConfig() 处理由Action Bean的execute()方法返回的ActionForward对象。
(1)RequestProcessor类的process()方法
- Public void process(HttpServletRequest request,HttpServletResponse response)throws IOException,ServletEXception{
- request = processMultipart(request);
- // Identify the path component we will use to select a mapping
- String path = processPath(request,response);
- if(path == null){
- return;
- }
- if(log.isDebugEnabled()){
- log.debug(“Processing a ” +request.getMethod()+”’ for path ‘”+path+”’”);
- }
- //Select a Locale for the current user if requested processLocale(request,response);
- //set the content type and no-caching headers if requested processContent(request,response);
- processNoCache(request,response);
- //General perpse preprocessing hook
- if(!processPreprocess(request,response)){ return; }
- //Identify the mapping for this request
- ActionMapping mapping = processMapping(request,response,path);
- if(mapping == null){ return; }
- //Check for any role request to perform this action
- if(!processRoles(request,response,mapping){ return; }
- //process any ActionForm bean related to this request ActionForm form = processActionForm(request,response,mapping);
- processPopulate(request,response,form,mapping);
- if(!processValidate(request,response,form,mapping){ return; }
- //process a forward or include specified by this mapping
- if(!processForward(request,response ,mapping){ return; }
- if(!processInclude(request,response ,mapping){ return; }
- //create or acquire the Action instance to process this request
- Action action = processActionCreate(request,response ,mapping);
- if(action == null){ return; }
- //call the Action instance itself
- ActionForward forward = processActionPerform(request,response,action,form,mapping);
- //process the returned ActionForward instance
- processForwardConfig(request,response,forward);
- }
RequestProcessor类的process()方法依次执行的流程
<1>调用processMultipart():如果HTTP请求方式为POST,并且请求的contentType属性以“multipart/form-data”开头,标准的HttpServletRequest对象将被重新包装,以方便处理”multipart”类型的HTTP请求。如果请求方式为”GET”,或者contentType属性不是”multipart”,就直接返回原始的HttpServletRequest对象
<2>调用processPath():获得请求URI的路径,这一信息可以用于选择合适的Struts Action 组件
<3>调用processLocale():当ControllerConfig对象的locale属性为true,将读取用户请求中包含的Locale信息,然后把Locale实例保存在session范围内
<4>调用processContent():读取ControllerConfig对象的contentType属性,然后调用response.setContentType(contentType)方法,设置响应结果的文档类型和字符编码。
<5>调用processNoCache():读取ControllerConfig对象的nocache属性,如果nocache==true,在响应结果中将加入特定的头参数
<6>调用processPreprocess():该方法不执行任何操作,直接返回true,子类可以覆盖这个方法,执行客户化的预处理请求操作
<7>调用processMapping():寻找和用户请求的URI匹配的ActionMapping,如果不存在,就返回错误的消息
<8>调用processRoles(): 先判断是否为Action配置了安全角色,如果配置了安全角色,就调用isUserInRole()方法判断当前用户是否具备必需的角色,如果不具备,就结束处理流程,返回错误信息。
<9>调用processActionForm(): 先检查是否为ActionMapping配置了ActionForm,如果是,则找出该实例,如果不是,则创建该实例,并且保存在适当的范围中
<10>调用processPopulate(): 如果ActionMapping配置了ActionForm实例,就先调用它的reset()方法,再把数据装到ActionForm中
<11>调用processValidate(): 如果ActionMapping配置了ActionForm,并且ActionMapping的validate属性为true,就调用ActionForm的validate()方法,如果validate()方法返回的ActionErrors对象包含ActionMessage对象,说明表单验证失败,就把ActionErrors对象存储在request范围内,再把请求转发到ActionMapping的input属性指定的Web组件。要是验证成功,就继续下面的流程
<12>调用processForward(): 判断是否在ActionMapping中配置了forward属性,如果配置了就调用RequestDispatcher的forward()方法,请求流程结束,否则继续下一步。 <13>调用processInclude(): 判断是否在ActionMapping中配置了include属性,是的话接调用RequestDispatcher的include()方法,流程结束,否则继续下一步
<14>调用processActionCreate():先判断Action缓存中是否存在这个Action的实例,如果不存在就创建一个Action实例,并且保存在Action缓存中。
<15>调用processActionPerform():该方法再调用Action实例的execute()方法
<16>调用processActionForward():把Action的execute()方法返回的ActionForward对象作为参数传给他,由它来执行请求转发或者重定向。
如果要定制ActionServlet的行为规则,其实应从RequestProcessor这个RequestProcessor类着手。要开发自己的RequestProcessor类以实现定制的控制逻辑,应遵循以下步骤:
1) 创建一个子类继承org.apache.struts.action.RequestProcessor类,在该子类中显式定义(或使用缺省的)无参、方法体为空的构造方法。
2) 重写所需要的方法,加入定制功能。
3) 将该子类编译后得到的class文件保存到Struts应用程序的WEB-INF/class/目录下
4) 修改配置文件struts-config.xml,在其中加入一个名为<controller>的元素,用以指定客户定制的RequestProcessor类。
在展示一个具体的实现定制功能的例子之前,有必要介绍一下RequestProcessor类中定义的另外几个有关方法:
protected void log(java.lang.String message){…}
功能:将参数String对象message的内容存入当前应用程序日志文件。
protected void log(java.lang.String message, java.lang.Throwable exception) {…}
功能:将参数String对象message和异常对象exception所封装的信息存入当前应用程序日志文件。
protected boolean processPreprocess(javax.servlet.http.HttpServletRequest request,
javax.servlet.http.HttpServletResponse response) {…}
功能:专门用于在子类中被重写,加入由开发者定制的预处理功能。
在RequestProcessor类中定义的processPreprocess()方法什么也不做,只是简单返回一个boolean类型值true,用以告知RequestProcessor继续后续处理程序。在定制RequestProcessor类时通常会重写此方法,注意一定要在方法的结尾返回true,如果重写如果返回值为false,则RequestProcessor对象终止对请求的处理,将控制权送回给ActionServlet的doPost()或doGet()方法。
下面给出用户定制RequestProcessor组件的具体实现步骤:
1)为已有的Struts应用程序创建用户自己的RequestProcessor类,重写其中的processPreprocess()方法,加入所需的控制逻辑。范例源代码如下:
源文件:MyRequestProcessor.java
package test;
import java.util.Enumeration;
import javax.servlet.http.*;
import org.apache.struts.action.RequestProcessor;
public class MyRequestProcessor extends RequestProcessor {
public MyRequestProcessor() {}
public boolean processPreprocess(HttpServletRequest request,
HttpServletResponse response) {
log("-------------- My Logging Start--------------");
log("Request URI = " + request.getRequestURI());
log("Context Path = " + request.getContextPath());
Enumeration headerNames = request.getHeaderNames();
log("Request Header:");
while (headerNames.hasMoreElements()) {
String headerName =(String)headerNames.nextElement();
Enumeration headerValues = request.getHeaders(headerName);
while (headerValues.hasMoreElements()) {
String headerValue =(String)headerValues.nextElement();
log("/t" + headerName + " = " + headerValue);
}
}
log("Locale = " + request.getLocale());
log("Method = " + request.getMethod());
log("Path Info = " + request.getPathInfo());
log("Protocol = " + request.getProtocol());
log("Remote Address = " + request.getRemoteAddr());
log("Remote Host = " + request.getRemoteHost());
log("Remote User = " + request.getRemoteUser());
log("Requested Session Id = "
+ request.getRequestedSessionId());
log("Scheme = " + request.getScheme());
log("Server Name = " + request.getServerName());
log("Server Port = " + request.getServerPort());
log("Servlet Path = " + request.getServletPath());
log("Secure = " + request.isSecure());
log("-------------- My Logging End --------------");
return true;
}
}
2)编译源文件MyRequestProcessor.java,将所生成的字节码文件(包括所在的package子目录)保存到Struts 应用程序的"WEB-INF/classes/"目录下。
3)修改此Struts应用程序配置文件struts-config.xml,在其中加入<controller>元素:
源文件:struts-config.xml
<?xml version="1.0" encoding="ISO-8859-1" ?>
<!DOCTYPE struts-config PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 1.1//EN"
"http://jakarta.apache.org/struts/dtds/struts-config_1_1.dtd">
<struts-config>
……
<controller processorClass="test.MyRequestProcessor" />
</struts-config>
说明:其他组成页面、类设计和应用程序配置均不需做改变。
4)发布Struts应用程序,并通过客户端浏览器访问该应用程序。
5)打开Web服务器日志文件<WAS_HOME>/logs/localhost_log.<当天日期>.txt,可以看到新加入的用户定制信息:
2004-09-24 00:30:28 StandardContext[/myStrutsApp3]action:
-------------- My Logging Start--------------
Request URI = /myStrutsApp3/regist.do
Context Path = /myStrutsApp3
Request Header:
accept = image/gif, image/x-xbitmap, image/jpeg, image/pjpeg,
application/vnd.ms-powerpoint, application/vnd.ms-excel,
application/msword , application/x-shockwave-flash, */*
referer = http://localhost:8080/myStrutsApp3/
accept-language = zh-cn
content-type = application/x-www-form-urlencoded
accept-encoding = gzip, deflate
user-agent = Mozilla/4.0 (compatible; MSIE 6.0;
Windows NT 5.1; .NET CLR 1.1.4322)
host = localhost:8080
content-length = 20
connection = Keep-Alive
cache-control = no-cache
cookie = JSESSIONID=FD8A69F16E329A362DB219596897D6DA
Locale = zh_CN
Method = POST
Path Info = null
Protocol = HTTP/1.1
Remote Address = 127.0.0.1
Remote Host = 127.0.0.1
Remote User = null
Requested Session Id = FD8A69F16E329A362DB219596897D6DA
Scheme = http
Server Name = localhost
Server Port = 8080
Servlet Path = /regist.do
Secure = false
-------------- My Logging End --------------
- 定制Struts控制器组件
- 定制Struts控制器组件
- 定制Struts控制器组件
- 定制Struts控制器组件
- 定制Struts控制器组件
- Struts控制器组件
- Struts控制器组件
- Struts控制器组件
- Struts控制器组件
- Struts控制器组件-ActionServlet
- Struts控制器组件-RequestProcess
- Struts控制器组件-Action
- Struts控制器组件
- Struts控制器组件
- Struts控制器组件
- Struts控制器组件
- struts的控制器组件
- struts控制器组件--actionServlet类
- 一个最近喜欢的游戏。
- 动网论坛的广告注册,广告回复 问题
- 关于kdevelop
- 【Java.Concurrency】Java线程状态图
- HTML iframe 标签
- 定制Struts控制器组件
- Java打印程序设计
- 开发大型高负载类网站应用的几个要点
- C++ Primer学习系列(4):关联容器/泛型算法/类
- jpiviot源码阅读
- 未来增长最快的一项新3G增值业务
- 利用SqlCommand传参数的方法:
- 如何更改vs2005的浏览器
- 一个错误