Struts簡介、原理及簡單實現


struts簡介

Struts是Apache軟件基金會(ASF)贊助的一個開源項目。它最初是jakarta項目中的一個子項目,並在2004年3月成為ASF的頂級項目。它通過采用JavaServlet/JSP技術,實現了基於JavaEEWeb應用的MVC設計模式的應用框架,是MVC經典設計模式中的一個經典產品。

Struts發展歷史

Struts是作為ApacheJakarta項目的組成部分,項目的創立者希望通過對該項目的研究,改進和提高JavaServerPages、servlet、標簽庫以及面向對象的技術水准。

Struts這個名字的來源於在建築和舊式飛機中使用的支持金屬架。之所以這個框架叫做“struts”,是為了提醒我們記住那些支撐我們房屋,建築,橋梁,甚至我們踩高蹺的基礎支撐。這也是解釋struts在開發web應用程序中所扮演的角色的精彩描述。

Struts的含義是”支柱,枝干”,它的目的是為了減少程序開發的時間,項目的創建者認為JSP,servlet的存在雖然可以幫助用戶解決大部分問題,但是由於它們的編碼對項目的開發帶來了許多的不方便,可重用性也差,所以struts應運而生,幫助用戶在最短的時間內解決這些問題。Struts框架提供如下服務:

(1)作為控制器的Servlet。

(2)提供大量的標簽庫。

(3)提供了用於國際化的框架,利用不同的配置文件,可以幫助用戶選擇合適自己的語言。

(4)提供了JDBC的實現,來定義數據源和數據庫連接池。

(5)XML語法分析工具。

(6)文件下載機制。

 

Struts原理

Struts是對JSPModel2設計標准的一種實現,下面分別從模型(Model)、視圖(view)和控制器3個部分介紹Struts的體系結構和工作原理。調用流程如下所示(圖1.1)。

 

圖1.1

 

(1)視圖(view)

在Struts中,視圖層包含兩個部分,JSP頁面和ActionForm。

ActionForm封裝了用戶提交的表單信息,其實ActonForm本質上就是JavaBean,這些JavaBean中沒有業務邏輯,只提供了所有屬性的getter和setter方法,這些屬性和用戶表單中的輸入項是一一對應的。在Struts中就是通過ActionForm把用戶表單信息提交給控制器。

JSP頁面是經典MVC中主要的視圖組件,主要是信息顯示和控制器處理結果顯示的功能。

除了以上,struts還提供了一個強大的struts標簽庫,來幫助用戶解決顯示邏輯,並且利用ActonForm組件將信息傳遞到控制層。

(2)控制器(Controller)

在控制層,struts提供了一個控制器組件ActionServlet,它繼承自HttpServlet,並重載了HttpServlet的doGet(),doPost()方法,可以接受HTTP的響應,並進行轉發,同時還提供了使用XML進行轉發Mapping(映射)的功能。

(3)模型(Model)

模型表示狀態和業務邏輯的處理,在一般的web應用程序中,用JavaBean或者EJB來實現系統的業務邏輯。在Struts中,struts提供Action對象,來管理業務邏輯的調用,幫助用戶分離業務邏輯,也就是說struts本身不實現業務邏輯,但可以調用已完成的業務邏輯。

Struts工作流程

Struts工作流程如下(圖1.2)所示。

 

 

圖1.2

 

ActionServlet是struts中核心的控制器,所有的用戶請求都必須通過ActionServlet的處理,而struts-config.xml是struts中核心的配置文件,在這個文件中配置了用戶請求URL和控制器Action的映射關系,ActionServlet通過這個配置文件把用戶的請求發送到對應的控制器中。

在struts web應用程序中,當web應用程序啟動的時候,就會初始化ActionServlet在初始化ActionServlet的時候會加載struts-config.xml配置文件,在加載成功后會把這些URL和控制器映射關系存放在ActionMapping對象或者其他對象中。當ActionServlet接收到用戶請求的時候,就會按照下面的流程對用戶請求進行處理。

(1)ActionServlet接收到用戶的請求后,會根據請求URL尋找匹配的ActionMapping對象,如果匹配失敗,說明用戶請求的URL路徑信息有誤,所以返回請求路徑無效的信息,當找到匹配的ActionMapping的時候,進入到下一步。

(2)當ActionServlet找到匹配的ActionMapping對象的時候,會根據ActionMapping中的映射信息判斷對應的ActionForm對象是否存在,如果不存在對應的ActionForm對象就創建一個新的ActionForm對應,並把用戶提交的表單信息保存到這個ActionForm對象中。

(3)在struts-config.xml中這個配置文件,可以配置表單是否需要驗證,如果需要驗證,就調用ActionForm中的validate()方法對用戶輸入的表單進行驗證。

(4)如果ActionForm的validate()方法返回了ActionErrors對象,則表明驗證失敗,ActionServlet把這個頁面返回到用戶輸入的界面,提示用戶重新輸入。如果方法的返回值為null,就表明驗證已經通過,可以進入下一步處理。

(5)ActionServlet可以根據ActionMapping對象查找用戶請求轉發給哪個控制器Action,如果對應的Action對象不存在,就創建這個對象,並調用這個Action的excute()方法。

(6)業務邏輯控制器Action的execute()方法就會返回一個ActionForward對象,ActionServlet把控制器處理的結果轉發到ActionForward對象指定的JSP頁面。

(7)ActionForward對象指定的JSP頁面根據返回的處理結果,用合適形式把服務器處理的結果展示給用戶,到這里為止,一個客戶請求的整個過程完畢。

 

以上初步struts框架進行了介紹,和對原理進行了簡單的分析。至於struts是如何實現MVC的,ActionServlet屬於Controller部分,Action和ActionForm屬於Model層,還是Action屬於Controller層,不同的人對struts有不同的理解。接下來真正的運用到實踐中,在實踐中深刻去體會,原理固然重要,重要的是運用,是能駕馭和使用這個框架。就像學習開車一樣,不是一蹴而就的。

下面已登錄為例,進行簡單的實現。

Struts配置步驟總結如下(如圖2.1):

 

1、  jar包拷貝

首先是建立java web項目,之后打開我們我們下載好strtus框架,Struts-1.2.9-bin文件夾和struts-1.2.9.src源文件文件夾。在bin文件夾中的lib文件中拷貝struts的jar包,拷貝到我們自己項目struts_login –>lib文件夾下(如圖2.2)。

 

2、 web.xml文件配置

找到Struts-1.2.9-bin中Struts-1.2.9-bin-->webapps下的struts實例struts-blank中的struts-1.2.9-bin\webapps\struts-blank\WEB-INF下的web.xml文件,復制配置對ActionServlet的配置,粘貼到我們的項目struts_login的WEB-INF下的web.xml中,代碼如下所示。主要是對struts自帶的ActionServlet進行配置。

<servlet>  
   <servlet-name>action</servlet-name>  
   <servlet-class>org.apache.struts.action.ActionServlet</servlet-class>  
   <init-param>  
     <param-name>config</param-name>  
     <param-value>/WEB-INF/struts-config.xml</param-value>  
   </init-param>  
   <init-param>  
     <param-name>debug</param-name>  
     <param-value>2</param-value>  
   </init-param>  
   <init-param>  
     <param-name>detail</param-name>  
     <param-value>2</param-value>  
   </init-param>  
   <load-on-startup>2</load-on-startup>  
 </servlet>  
   
   
 <!--Standard Action Servlet Mapping -->  
 <servlet-mapping>  
   <servlet-name>action</servlet-name>  
   <url-pattern>*.do</url-pattern>  
 </servlet-mapping>  

3、在項目中建立自己的ActionForm

在項目中建立自己的ActionForm,繼承struts框架中已經寫好的ActionForm,在ActionForm設置用到的數據,並且要和我們界面上設置的名稱一致。因為我們在提交表單的時候,所有的請求都會放到ActionForm中。建立登錄的ActionForm,LoginActionForm.java代碼如下所示。

package com.bjpowernode.struts;  
import org.apache.struts.action.ActionForm;  
   
/** 
 * 登錄ActionForm,負責表單收集數據. 
 * 表單的屬性必須和ActionForm中的get和set的屬性一致. 
 * @author summer 
 * 
 */  
public class LoginActionForm extends ActionForm {  
   
    //用戶名。  
    private String username;  
    //密碼。  
    private String password;  
     
    //設置密碼。  
    public void setPassword(String password) {  
       this.password = password;  
    }  
    //得到用戶名。  
    public String getUsername() {  
       return username;  
    }  
    //設置用戶名。  
    public void setUsername(String username) {  
       this.username = username;  
    }  
    //得到密碼。  
    public String getPassword() {  
     
       return password;  
    }  
     
}  

4、建立自己的Action

建立自己的Action,同時繼承struts框架中的org.apache.struts.action.Action,重載父類的execute方法。在這里完成取出表單中的數據。通過CalActionFormcalForm= (CalActionForm)(CalActionForm)form;(struts框架中已經幫我們封裝好了,我們去使用就可以了)來取得表單中的值。經過判斷后,進行相應的操作,跳轉到相應的頁面。Action的功能是負責拿到表單數據和調用業務邏輯后進行頁面跳轉。建立登陸的Action類,LoginAction.java類,調用業務邏輯類UserManager的login方法。代碼如下所示。

packagecom.bjpowernode.struts;  
   
importjavax.servlet.http.HttpServletRequest;  
importjavax.servlet.http.HttpServletResponse;  
   
importorg.apache.struts.action.Action;  
importorg.apache.struts.action.ActionForm;  
importorg.apache.struts.action.ActionForward;  
importorg.apache.struts.action.ActionMapping;  
   
/** 
 *登錄Action 
 *負責取得表單數據,調用業務邏輯,返回轉向信息. 
 * 
 * @author summer 
 * 
 */  
public class LoginAction extends Action {  
   
      @Override  
      public ActionForward execute(ActionMapping mapping,ActionForm form,  
                    HttpServletRequest request, HttpServletResponse response)  
                    throws Exception {  
   
   
             LoginActionForm laf = (LoginActionForm)form;  
             String username = laf.getUsername();  
             String password = laf.getPassword();  
               
             UserManager userManager = newUserManager();  
             //傳遞用戶名和密碼  
             try  
             {  
                    userManager.login(username, password);  
                    request.setAttribute("username", username);  
                    return mapping.findForward("success");  
             }catch(UserNotFoundException e)  
             {  
                    e.printStackTrace();  
                    request.setAttribute("msg","用戶不能找到,用戶名稱=[" +username +"+]");  
             }catch(PasswordErrorException e)  
             {  
                    e.printStackTrace();  
                    request.setAttribute("msg","密碼錯誤");  
             }  
               
             return mapping.findForward("error");  
      }  
   
}  

5、建立struts-config.xml

作為Struts框架的核心描述,struts-config.xml可以說“一切盡在掌握”。它不但描述了MVC模型,定義所有視圖層和控制層之間的接口(ActionForm),與控制層和模型層的接口(Action)進行結合,而且可以定義一些附加組件,如國際化信息資源排至文件,標簽庫信息等。

仍然是站在巨人的肩膀上,將我們下載的struts  bin文件夾中的struts-config.xml文件復制到我們的項目的WEB-INF中,刪除struts-config.xml中的注釋部分。把Action和ActionForm配置起來。ActionForm放到<form-beans></form-beans>中,Action配置放到<action-mappings></action-mappings>中,struts-config.xml配置代碼如下所示。

<?xml version="1.0" encoding="ISO-8859-1" ?>  
   
<!DOCTYPE struts-config PUBLIC  
         "-//Apache Software Foundation//DTD Struts Configuration1.2//EN"  
         "http://jakarta.apache.org/struts/dtds/struts-config_1_2.dtd">  
   
   
<struts-config>  
    <form-beans>  
       <form-bean name="loginForm" type="com.bjpowernode.struts.LoginActionForm"/>  
    </form-beans>  
     
    <action-mappings>  
       <action path="/login"  
              type="com.bjpowernode.struts.LoginAction"  
              name="loginForm"  
              scope="request"  
              >  
              <forward name="success" path="/login_success.jsp"/>  
              <forward name="error" path="/login_error.jsp"/>  
       </action>  
    </action-mappings>    
</struts-config>  

其中form-beans元素中可以定義0個或1個以上的form-bean元素,每個form-bean被認為是一個ActionForm對象,name屬性表示form-bean元素的名稱,type屬性指定其類名和路徑。

Action-mappings元素用來包含零到多個action,其子元素action負責具體映射的詳細信息。在action-mapping元素中可以定義0個或1個以上的action元素。每個action元素接受path屬性定義的請求,並映射到type屬性所定義的具體action對象。在映射過程中,將name屬性定義的actionform一並傳過去,它有如下屬性:

Parameter,scope兩個屬性指定了傳送方式和范圍,scope常用的值有兩個“session”和“request”。

Validate屬性指定了是否需要actionform的驗證。

Forward元素,將請求success轉發到”/login_success.jsp頁面。

 

6、業務邏輯類UserManager和自定義異常類

代碼如下所示:

packagecom.bjpowernode.struts;  
   
public class UserManager {  
        
      public void login(String username,String password)  
      {  
             if(!"admin".equals(username))  
             {  
                    throw new UserNotFoundException();  
             }  
               
               
             if(!"admin".equals(password))  
             {  
                    throw new PasswordErrorException();  
             }  
      }  
   
}  

自定義異常類UserNotFoundException和PasswordErrorException代碼如下所示。

packagecom.bjpowernode.struts;  
   
public class UserNotFoundException extends RuntimeException {  
   
      public UserNotFoundException() {  
      }  
   
      public UserNotFoundException(Stringmessage) {  
             super(message);  
      }  
   
      public UserNotFoundException(Throwable cause) {  
             super(cause);  
      }  
   
      public UserNotFoundException(String message,Throwable cause) {  
             super(message, cause);  
      }  
   
}  
   
packagecom.bjpowernode.struts;  
   
public class PasswordErrorException extends RuntimeException {  
   
      public PasswordErrorException() {  
      }  
   
      public PasswordErrorException(String message) {  
             super(message);  
      }  
   
      public PasswordErrorException(Throwable cause) {  
             super(cause);  
      }  
   
      public PasswordErrorException(String message,Throwable cause) {  
             super(message, cause);  
      }  
   
}  

7、視圖jsp頁面調用。

登錄界面login.jsp,錯誤顯示界面login_error.jsp,登錄成功界面login_success.jsp。代碼如下所示。

<%@pagelanguage="java" contentType="text/html; charset=GB18030"  
   pageEncoding="GB18030"%>  
<!DOCTYPEhtml PUBLIC "-//W3C//DTDHTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">  
<html>  
<head>  
<meta http-equiv="Content-Type" content="text/html; charset=GB18030">  
<title>Inserttitle here</title>  
</head>  
<body>  
<form action="login.do" method="post">  
   用戶:<inputtypeinputtype="text" name="username"><Br>  
   密碼:<inputtypeinputtype="password" name="password"></br>  
   <input type="submit" value="登錄">  
</form>  
</body>  
</html>  

Login_success.jsp.

<%@page language="java"contentType="text/html;charset=GB18030"  
   pageEncoding="GB18030"%>  
<!DOCTYPE html PUBLIC "-//W3C//DTDHTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">  
<html>  
<head>  
<meta http-equiv="Content-Type" content="text/html; charset=GB18030">  
<title>Insert title here</title>  
</head>  
<body>  
  ${username},登錄成功!  
</body>  
</html>  

Login_error.jsp界面。

<%@page  language="java" contentType="text/html; charset=GB18030"  
   pageEncoding="GB18030"%>  
<!DOCTYPE html PUBLIC "-//W3C//DTDHTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">  
<html>  
<head>  
<meta http-equiv="Content-Type" content="text/html; charset=GB18030">  
<title>Insert title here</title>  
</head>  
<body>  
  <%--  
  <%=request.getAttribute("msg") %>  
  --%>  
    
  ${msg }  
</body>  
</html>  

就這樣我們實現了運用struts框架完成用戶登錄。就這樣從初步學習到簡單應用,隨着應用的次數增多,我們會對struts理解越來越深刻,並且感受struts框架給我們帶來的便捷。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM