Struts學習筆記zz

ysuncn發表於2020-04-05
一、    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 />標籤即可。


相關文章