一、 Controller(控制器)
Struts中的控制器包括三个组件:ActionServlet类、Action类、Plugins以及RequestProcesser。
1. ActionServlet类:
◆ 处理过程:
org.apache.struts.action.ActionServlet 类是Struts应用程序的核心。它是处理客户端请求和决定哪一个Action类来处理每个接收到的请求的最主要的控制器组件。它担当着Action工厂类的角色去创建一个指定的Action类。事实上,它也就是继承于HttpServlet类的一个Servlet类。它实现了HttpServlet生命周期中的所有方法,如:init(),doGet(),doPost(),destroy()。当ActionServlet接收到请求之后,它的执行步骤如下:
① doGet()或者doPost()方法接收请求,然后调用ActionServlet类的process()方法。Process()方法会返回一个当前的RequestProcessor类的实例对象。然后调用RequestProcessor类的process()方法。而实际为当前请求提供处理服务的就是这个process()方法。所有的一切都是在这里完成的。
② RequestProcessor.process()方法会从struts-config.xml文件中将<form-bean>的name属性与<action>中的name属性对应起来,从而找到相关的ActionForm类的类名称
③ 到实例池中找一个ActionForm类的实例。将它的数据成员与请求的值对应起来。
④ 调用ActionForm类的validate()方法,检查提交数据的有效性。
⑤ 从<action>中接收到Action类的类名称。创建一个Action类,然后调用Action类的execute()方法。当Action类返回一个ActionForward类的实例之后,控制权再次交给ActionServlet。
⑥ ActionServlet则forward到指定的target进行处理。至此ActionServlet对request的处理完毕。
◆ 扩展ActionServlet类:
如果想写自己的ActionServlet类,则一定要继承自org.apache.struts.action.ActionServlet类,并且按下面的四个步骤进行:
① 创建一个继承自org.apache.struts.action.ActionServlet类的类。
② 实现自定义的商业逻辑方法。
③ 编译这个类,并且将它放到Web 应用程序的类路径中
④ 修改web.xml文件中的<servlet>元素中的相关设置。
◆ 配置ActionServlet:见“web.xml配置文件”一文。
2. Action类:
这是Struts控制器的第二个组件,Action类在每一个应用系统中都必须被扩展。下面看一看Action中重要的方法:
① execute()方法:这个方法是必须要重写的方法。Action类中实现了两个execute()方法,一个接受Http请求,一个不是。
◆ 扩展Action类
① 创建一个继承于Action的类
② 实现execute()方法和自己的商业逻辑
③ 在struts-config.xml文件中配置<Action-mappings />元素
在struts-config.xml中配置Action类的参数,请参考“struts-config配置文件讲解”。
3. Struts Plugins:
Plugin 从Struts1.1开始介绍,它定义了一个org.apache.struts.action.Plugin接口,它主要用来分配资源 (allocating resources)或者建立数据库的连结或者JNDI资源。这个接口提供了两个必须实现的方法:init()和destroy()。如果运用了 Plugin技术,那么在容器启动的时候,会调用Plugin的init()方法。所以将应用系统的初始化信息写在这里。当容器停止Struts应用系统的时候,会调用destroy()方法,destroy()方法主要是用来收回在init()方法中分配的资源信息。
◆ 扩展Plugin类
① 创建一个实现Plugin接口的类
② 添加一个空的构造器
③ 实现init()及destroy()两个方法
④ 在struts-config.xml文件中对<plug-in />元素的配置
创建Plugin必须继承org.apache.struts.action.Plugin接口。并且实现init()及destroy()方法。例子:
package wiley;
import java.util.Properties;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.ServletContext;
import org.apache.struts.action.PlugIn;
import org.apache.struts.config.ModuleConfig;
import org.apache.struts.action.ActionServlet;
public class WileyPlugin implements PlugIn {
public static final String PROPERTIES = "PROPERTIES";
public WileyPlugin() {}
public void init(ActionServlet servlet,
ModuleConfig config)
throws javax.servlet.ServletException {
System.err.println("....>The Plugin is starting<....");
Properties properties = new Properties();
String path = "C://ApplicationResources"+
".properties";
try {
// Build a file object referening the properties file
// to be loaded
File file = new File(path);
// Create an input stream
FileInputStream fis = new FileInputStream(file);
// load the properties
properties.load(fis);
// Get a reference to the ServletContext
ServletContext context = servlet.getServletContext();
// Add the loaded properties to the ServletContext
// for retrieval throughout the rest of the Application
context.setAttribute(PROPERTIES, properties);
}
catch (FileNotFoundException fnfe) {
throw new ServletException(fnfe.getMessage());
}
catch (IOException ioe) {
throw new ServletException(ioe.getMessage());
}
}
public void destroy() {
// We don't have anything to clean up, so
// just log the fact that the Plugin is shutting down
System.err.println("....>The Plugin is stopping<....");
}
}
◆ 配置Plugin:
在struts-config.xml文件中配置<plug-in>元素。如下:
<plug-in className=”wiley.WileyPlugin” />
<plug-in />的详细配置信息见”struts-config.xml配置文件讲解”。
4. RequestProcessor:
有关的ActionServlet的实际处理都是在RequestProcessor类中完成的。我们也可以创建我们自己的 RequestProcessor类,这需要继承RequestProcessor类。并且要有一个缺省的空的构造器。在这个自定义的 RequestProcessor类中重写相关的方法,一般都是重写processXXX()方法。
◆ 扩展RequestProcessor类
扩展Processor类按下面的步骤完成:
① 创建一个继承于org.apache.struts.action.RequestProcessor的类
② 添加一个缺省的空的构造器
③ 实现想要重写的方法
例子:
package wiley;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServlet;
import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import java.io.IOException;
import java.util.Enumeration;
import org.apache.struts.action.RequestProcessor;
public class WileyRequestProcessor extends RequestProcessor {
public WileyRequestProcessor() {
}
public boolean processPreprocess(HttpServletRequest request, HttpServletResponse response) {
log("----------processPreprocess Logging--------------");
log("Request URI = " + request.getRequestURI());
log("Context Path = " + request.getContextPath());
Cookie cookies[] = request.getCookies();
if (cookies != null) {
for (int i = 0; i < cookies.length; i++) {
log("Cookie = " + cookies[i].getName() + " = " +
cookies[i].getValue());
}
}
Enumeration headerNames = request.getHeaderNames();
while (headerNames.hasMoreElements()) {
String headerName =(String) headerNames.nextElement();
Enumeration headerValues =request.getHeaders(headerName);
while (headerValues.hasMoreElements()) {
String headerValue =(String) headerValues.nextElement();
log("Header = " + 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("-------------------------------------------------");
return true;
}
}
◆ 配置RequestProcessor:
在struts-config.xml文件中配置<controller/>元素。如下:
<controller processorClass=”wiley.WileyRequestProcessor” />
详细配置信息见”struts-config.xml配置文件讲解”。
二、 出错管理(Managing Errors)
Struts 框架有两个主要的类来管理出错,一个是org.apache.struts.action.ActionError类,它对错误信息进行包装。另一个是 org.apache.struts.action.ActionErrors类,它是ActionError实例的容器。这两个类经常要在 ActionForm及Action类中使用。其具体的使用如下:
ActionErrors errors = new ActionErrors();
errors.add("propertyname", new ActionError("key");
errors.add(ActionErrors.GLOBAL_ERROR,new ActionError("key");
关于"propertyname"和ActionErrors.GLOBAL_ERROR,对前者用在ActionForm中,这里是对应表现层(JSP)中的属性值。而对后者则用在Action中,它对应struts-config.xml的<global-forwards />中描述的信息。例子:
ActionForm类:
public class LoginForm extends ActionForm {
…………………
public ActionErrors validate(ActionMapping mapping,HttpServletRequest request) {
ActionErrors errors = new ActionErrors();
if ( (username == null ) || (username.length() == 0) ) {
errors.add("username",new ActionError("errors.username.required"));
}
if ( (password == null ) || (password.length() == 0) ) {
errors.add("password",new ActionError("errors.password.required"));
}
return errors;
}
…………………
}
Action类:
public class LoginAction extends Action {
……………………
public ActionForward execute(ActionMapping mapping,ActionForm form,HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
String user = null;
// Default target to success
String target = "success";
// Use the LoginForm to get the request parameters
String username = ((LoginForm)form).getUsername();
String password = ((LoginForm)form).getPassword();
user = getUser(username, password);
// Set the target to failure
if ( user == null ) {
target = "login";
ActionErrors errors = new ActionErrors();
errors.add(ActionErrors.GLOBAL_ERROR,new ActionError("errors.login.unknown",username));
// Report any errors we have discovered back to the
// original form
if (!errors.empty()) {
saveErrors(request, errors);
}
}
else {
HttpSession session = request.getSession();
session.setAttribute("USER", user);
}
// Forward to the appropriate View
return (mapping.findForward(target));
}
}
在表现层中表现错误只须要写上<html:error />标签即可。
Struts中的控制器包括三个组件:ActionServlet类、Action类、Plugins以及RequestProcesser。
1. ActionServlet类:
◆ 处理过程:
org.apache.struts.action.ActionServlet 类是Struts应用程序的核心。它是处理客户端请求和决定哪一个Action类来处理每个接收到的请求的最主要的控制器组件。它担当着Action工厂类的角色去创建一个指定的Action类。事实上,它也就是继承于HttpServlet类的一个Servlet类。它实现了HttpServlet生命周期中的所有方法,如:init(),doGet(),doPost(),destroy()。当ActionServlet接收到请求之后,它的执行步骤如下:
① doGet()或者doPost()方法接收请求,然后调用ActionServlet类的process()方法。Process()方法会返回一个当前的RequestProcessor类的实例对象。然后调用RequestProcessor类的process()方法。而实际为当前请求提供处理服务的就是这个process()方法。所有的一切都是在这里完成的。
② RequestProcessor.process()方法会从struts-config.xml文件中将<form-bean>的name属性与<action>中的name属性对应起来,从而找到相关的ActionForm类的类名称
③ 到实例池中找一个ActionForm类的实例。将它的数据成员与请求的值对应起来。
④ 调用ActionForm类的validate()方法,检查提交数据的有效性。
⑤ 从<action>中接收到Action类的类名称。创建一个Action类,然后调用Action类的execute()方法。当Action类返回一个ActionForward类的实例之后,控制权再次交给ActionServlet。
⑥ ActionServlet则forward到指定的target进行处理。至此ActionServlet对request的处理完毕。
◆ 扩展ActionServlet类:
如果想写自己的ActionServlet类,则一定要继承自org.apache.struts.action.ActionServlet类,并且按下面的四个步骤进行:
① 创建一个继承自org.apache.struts.action.ActionServlet类的类。
② 实现自定义的商业逻辑方法。
③ 编译这个类,并且将它放到Web 应用程序的类路径中
④ 修改web.xml文件中的<servlet>元素中的相关设置。
◆ 配置ActionServlet:见“web.xml配置文件”一文。
2. Action类:
这是Struts控制器的第二个组件,Action类在每一个应用系统中都必须被扩展。下面看一看Action中重要的方法:
① execute()方法:这个方法是必须要重写的方法。Action类中实现了两个execute()方法,一个接受Http请求,一个不是。
◆ 扩展Action类
① 创建一个继承于Action的类
② 实现execute()方法和自己的商业逻辑
③ 在struts-config.xml文件中配置<Action-mappings />元素
在struts-config.xml中配置Action类的参数,请参考“struts-config配置文件讲解”。
3. Struts Plugins:
Plugin 从Struts1.1开始介绍,它定义了一个org.apache.struts.action.Plugin接口,它主要用来分配资源 (allocating resources)或者建立数据库的连结或者JNDI资源。这个接口提供了两个必须实现的方法:init()和destroy()。如果运用了 Plugin技术,那么在容器启动的时候,会调用Plugin的init()方法。所以将应用系统的初始化信息写在这里。当容器停止Struts应用系统的时候,会调用destroy()方法,destroy()方法主要是用来收回在init()方法中分配的资源信息。
◆ 扩展Plugin类
① 创建一个实现Plugin接口的类
② 添加一个空的构造器
③ 实现init()及destroy()两个方法
④ 在struts-config.xml文件中对<plug-in />元素的配置
创建Plugin必须继承org.apache.struts.action.Plugin接口。并且实现init()及destroy()方法。例子:
package wiley;
import java.util.Properties;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.ServletContext;
import org.apache.struts.action.PlugIn;
import org.apache.struts.config.ModuleConfig;
import org.apache.struts.action.ActionServlet;
public class WileyPlugin implements PlugIn {
public static final String PROPERTIES = "PROPERTIES";
public WileyPlugin() {}
public void init(ActionServlet servlet,
ModuleConfig config)
throws javax.servlet.ServletException {
System.err.println("....>The Plugin is starting<....");
Properties properties = new Properties();
String path = "C://ApplicationResources"+
".properties";
try {
// Build a file object referening the properties file
// to be loaded
File file = new File(path);
// Create an input stream
FileInputStream fis = new FileInputStream(file);
// load the properties
properties.load(fis);
// Get a reference to the ServletContext
ServletContext context = servlet.getServletContext();
// Add the loaded properties to the ServletContext
// for retrieval throughout the rest of the Application
context.setAttribute(PROPERTIES, properties);
}
catch (FileNotFoundException fnfe) {
throw new ServletException(fnfe.getMessage());
}
catch (IOException ioe) {
throw new ServletException(ioe.getMessage());
}
}
public void destroy() {
// We don't have anything to clean up, so
// just log the fact that the Plugin is shutting down
System.err.println("....>The Plugin is stopping<....");
}
}
◆ 配置Plugin:
在struts-config.xml文件中配置<plug-in>元素。如下:
<plug-in className=”wiley.WileyPlugin” />
<plug-in />的详细配置信息见”struts-config.xml配置文件讲解”。
4. RequestProcessor:
有关的ActionServlet的实际处理都是在RequestProcessor类中完成的。我们也可以创建我们自己的 RequestProcessor类,这需要继承RequestProcessor类。并且要有一个缺省的空的构造器。在这个自定义的 RequestProcessor类中重写相关的方法,一般都是重写processXXX()方法。
◆ 扩展RequestProcessor类
扩展Processor类按下面的步骤完成:
① 创建一个继承于org.apache.struts.action.RequestProcessor的类
② 添加一个缺省的空的构造器
③ 实现想要重写的方法
例子:
package wiley;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServlet;
import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import java.io.IOException;
import java.util.Enumeration;
import org.apache.struts.action.RequestProcessor;
public class WileyRequestProcessor extends RequestProcessor {
public WileyRequestProcessor() {
}
public boolean processPreprocess(HttpServletRequest request, HttpServletResponse response) {
log("----------processPreprocess Logging--------------");
log("Request URI = " + request.getRequestURI());
log("Context Path = " + request.getContextPath());
Cookie cookies[] = request.getCookies();
if (cookies != null) {
for (int i = 0; i < cookies.length; i++) {
log("Cookie = " + cookies[i].getName() + " = " +
cookies[i].getValue());
}
}
Enumeration headerNames = request.getHeaderNames();
while (headerNames.hasMoreElements()) {
String headerName =(String) headerNames.nextElement();
Enumeration headerValues =request.getHeaders(headerName);
while (headerValues.hasMoreElements()) {
String headerValue =(String) headerValues.nextElement();
log("Header = " + 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("-------------------------------------------------");
return true;
}
}
◆ 配置RequestProcessor:
在struts-config.xml文件中配置<controller/>元素。如下:
<controller processorClass=”wiley.WileyRequestProcessor” />
详细配置信息见”struts-config.xml配置文件讲解”。
二、 出错管理(Managing Errors)
Struts 框架有两个主要的类来管理出错,一个是org.apache.struts.action.ActionError类,它对错误信息进行包装。另一个是 org.apache.struts.action.ActionErrors类,它是ActionError实例的容器。这两个类经常要在 ActionForm及Action类中使用。其具体的使用如下:
ActionErrors errors = new ActionErrors();
errors.add("propertyname", new ActionError("key");
errors.add(ActionErrors.GLOBAL_ERROR,new ActionError("key");
关于"propertyname"和ActionErrors.GLOBAL_ERROR,对前者用在ActionForm中,这里是对应表现层(JSP)中的属性值。而对后者则用在Action中,它对应struts-config.xml的<global-forwards />中描述的信息。例子:
ActionForm类:
public class LoginForm extends ActionForm {
…………………
public ActionErrors validate(ActionMapping mapping,HttpServletRequest request) {
ActionErrors errors = new ActionErrors();
if ( (username == null ) || (username.length() == 0) ) {
errors.add("username",new ActionError("errors.username.required"));
}
if ( (password == null ) || (password.length() == 0) ) {
errors.add("password",new ActionError("errors.password.required"));
}
return errors;
}
…………………
}
Action类:
public class LoginAction extends Action {
……………………
public ActionForward execute(ActionMapping mapping,ActionForm form,HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
String user = null;
// Default target to success
String target = "success";
// Use the LoginForm to get the request parameters
String username = ((LoginForm)form).getUsername();
String password = ((LoginForm)form).getPassword();
user = getUser(username, password);
// Set the target to failure
if ( user == null ) {
target = "login";
ActionErrors errors = new ActionErrors();
errors.add(ActionErrors.GLOBAL_ERROR,new ActionError("errors.login.unknown",username));
// Report any errors we have discovered back to the
// original form
if (!errors.empty()) {
saveErrors(request, errors);
}
}
else {
HttpSession session = request.getSession();
session.setAttribute("USER", user);
}
// Forward to the appropriate View
return (mapping.findForward(target));
}
}
在表现层中表现错误只须要写上<html:error />标签即可。