1. 程式人生 > >分享知識-快樂自己:初始 Struts2 (基本概念)及 搭建第一個Demo

分享知識-快樂自己:初始 Struts2 (基本概念)及 搭建第一個Demo

表單 控制器 title dtd eth -name 技術 mar 麻煩

1):struts2 的基本概念:

  1-1):Struts2 是什麽?

    1、Struts2是一個基於MVC設計模式的Web應用框架,它本質上相當於一個servlet,在MVC設計模式中,Struts2作為控制器(Controller)來建立模型與視圖的數據交互。

  2、Struts 2是Struts的下一代產品,是在 struts 1 WebWork 的技術基礎上進行了合並的全新的Struts 2框架。

    3、其全新的 Struts 2 的體系結構與 Struts 1 的體系結構差別巨大。Struts 2 以 WebWork 為核心,采用攔截器的機制來處理用戶的請求,這樣的設計也使得業務邏輯控制器能夠與ServletAPI

      完全脫離開,所以Struts 2可以理解為WebWork的更新產品。 雖然從 Struts 1Struts 2 有著太大的變化,但是相對於WebWork,Struts 2的變化很小。

  1-3):傳統jsp+servlet實現MVC的缺點:

    1、一個 servlet 對應一個邏輯方法,控制頁面的跳轉

    2、在 servlet 中獲取用戶提交的表單數據,手動封裝成對象比較麻煩

    3、servlet 的配置文件都在web.xml中,導致web.xml文件代碼多不易於維護

    4、傳統方式實現國際化麻煩

  1-4):主流的MVC框架:

    struts 1

框架,是最早出現的一個MVC框架,企業級開發中,在03-07年期間基本上壟斷了MVC框架的市場。

    但是,Struts1由於出現的早,核心設計思想跟不上時代,開發新功能難以勝任,目前基本上被淘汰,但是Struts這個名字已經深入人心,只要想學習MVC框架的人,首選就是Struts。

    JSF:是SUN官方的一個MVC框架,國內用的比較少,主要用在外包項目中。

    Struts 2 :該框架本來不是Apache公司的一個MVC框架,是OpenSymphony組織的一個MVC框架,本名叫WebWork,該框架出現的時間比較晚,設計架構比價適合web 2.0的開發規範。

    但是,該框架由於出現晚,並沒有多少知名度。後來,WebWork直接交由Apache維護,apache借助於Struts的名氣和WebWork的先進架構,直接把webWork框架改名為Struts2。

    Spring MVC:是Spring大框架中的一個MVC部分,是可以獨立存在的。設計思想完全按照Spring的註入思想設計,目前很多軟件中使用了Spring框架的企業MVC框架開始慢慢轉向Spring mvc

  1-5):Struts2 與 Struts1的對比:

    在Action實現類方面:

     1、Struts1 要求Action類繼承一個抽象基類;Struts1的一個具體問題是使用抽象類編程而不是接口。

     2、Struts2 Action類可以實現一個Action接口,也可以實現其他接口,使可選和定制服務成為可能。

     3、Struts2 提供一個ActionSupport基類 去實現常用的接口。即使Action接口不是必須實現的,只有一個包含execute方法的POJO類都可以用作Struts2的Action。

    線程模式方面:

     1、Struts1 Action 是單例模式並且必須是線程安全的,因為僅有Action的一個實例來處理所有的請求。

     2、單例策略限制了Struts1 Action能做的事,並且要在開發時特別小心。Action資源必須是線程安全的或同步的;Struts2 Action對象為每一個請求產生一個實例,因此沒有線程安全問題。

    Servlet依賴方面:

     1、Struts1 Action依賴於Servlet API,因為Struts1 Action的execute方法中有HttpServletRequest和HttpServletResponse方法。

     2、Struts2 Action 不再依賴於ServletAPI,從而允許Action脫離Web容器運行,從而降低了測試Action的難度。

       當然,如果Action 需要直接訪問HttpServletRequest和HttpServletResponse參數,Struts2 Action仍然可以訪問它們。但是,大部分時候,Action都無需直接訪問

  1-6):MVC設計模式:

    模型 :Model:實體類,也就是把數據庫表的字段映射為你的對象的各個屬性封裝數據,進行業務處理,返回處理結果

    視圖 :View:層用於與用戶的交互,通常用JSP來實現,展示界面

    控制器 :Controller:是Model與View之間溝通的橋梁,可以分派用戶的請求並選擇恰當的視圖以用於顯示,同時可以解釋用戶的輸入並映射為模型層可執行的操作。

  回顧MVC執行原理:

  技術分享圖片

2):搭建第一個Demo:

Struts2 執行原理圖:

技術分享圖片技術分享圖片

工作流程:

1、客戶端初始化一個指向Servlet容器(例如Tomcat)的請求

2、這個請求經過一系列的過濾器(Filter)

3、接著FilterDispatcher被調用,FilterDispatcher詢問ActionMapper來決定這個請求是否需要調用某個Action

4、如果ActionMapper決定需要調用某個Action,FilterDispatcher把請求的處理交給ActionProxy

5、ActionProxy通過Configuration Manager詢問框架的配置文件,找到需要調用的Action類

6、ActionProxy創建一個ActionInvocation的實例 ( 代理 )

7、ActionInvocation實例使用命名模式來調用,在調用Action的過程前後,涉及到相關攔截器(Intercepter)的調用

8、一旦Action執行完畢,ActionInvocation負責根據struts.xml中的配置找到對應的返回結果返回結果通常是一個需要被表示的JSP或者FreeMarker的模版, 在表示的過程中可以使用Struts2框架中繼承的

 標簽;也可能是另外的一個Action鏈,在這個過程中需要涉及到ActionMappe

Demo 目錄結構:

技術分享圖片

Web.XML:

<!DOCTYPE web-app PUBLIC
"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd" >

<web-app>
<display-name>Archetype Created Web Application</display-name>

<!--Struts2 核心過濾器-->
<filter>
<filter-name>struts</filter-name>
<filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>struts</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>

</web-app>

POM 文件:

  <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.source>1.7</maven.compiler.source>
        <maven.compiler.target>1.7</maven.compiler.target>
    </properties>

    <dependencies>

        <!--測試JAR-->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.11</version>
        </dependency>
        <!--javaee.jar包是支持javaweb編程的基礎jar包,跟javase編程需要jre一樣!-->
        <dependency>
            <groupId>javaee</groupId>
            <artifactId>javaee-api</artifactId>
            <version>5</version>
        </dependency>
        <!--Struts2-core核心-->
        <dependency>
            <groupId>org.apache.struts</groupId>
            <artifactId>struts2-core</artifactId>
            <version>2.3.4.1</version>
        </dependency>
        <!--xwork 的核心包,最主要的功能是 支持了過濾器(interceptor)。-->
        <dependency>
            <groupId>org.apache.struts.xwork</groupId>
            <artifactId>xwork-core</artifactId>
            <version>2.3.4.1</version>
        </dependency>
</dependencies>

Fristaction:類

package com.gdbd.action;

import com.opensymphony.xwork2.Action;

/**
 * 第一天第一次
 * Action:零散屬性自動裝配:
 * 所謂的自動裝配無非就是,在你表單提交的時候 name名字 與 Action屬性名一致。底層自動做了映射
 *
 * @author asus
 */
public class Fristaction implements Action {

    private String messages;
    private String userName;
    private String userPwd;
  ...省略 Get Set 方法
/*** * 默認執行方法 * @return * @throws Exception */ @Override public String execute() throws Exception {return "index"; } public String login() { System.out.println("攜帶參數:" + userName + "++" + userPwd + "-成功進入!!!!!!!!!!!!!"); if ("1".equals(userName) && "1".equals(userPwd)) { return "login"; } else { return "index"; } } }

說明:

實現Action 接口 重寫execute() 默認執行的方法

Fristaction 類中我們還寫了幾個屬性值,這幾個屬性值是用來演示 在我們提交表單的時候,name 屬性名 與 Fristaction類中的字段名一致 就可以達到自動映射效果

FristactionBean:類

package com.gdbd.action;
import com.gdbd.bean.UserInfo;
import com.opensymphony.xwork2.Action;

/**
 * 封裝Bean對象自動裝配
 * 提交表單的時候,使用對象名點屬性
 * @author asus
 */
public class FristactionBean implements Action {

    private String messages;
    private UserInfo userInfo;
  
  ...省略 Get Set 方法
/*** * 默認執行方法 * @return * @throws Exception */ @Override public String execute() throws Exception {return "index"; } public String login() { System.out.println("攜帶參數:" + userInfo.getUserName()+"++"+userInfo.getUserPwd() + "-成功進入!!!!!!!!!!!!!"); if ("1".equals(userInfo.getUserName()) && "1".equals(userInfo.getUserPwd())) { return "login"; } else { return "index"; } } }
package com.gdbd.bean;
import java.io.Serializable;
/**
 * user 實體類
 * @author asus
 */
public class UserInfo implements Serializable {

    private String userName;
    private String userPwd;
  ...省略 Get Set 方法
}

說明:

FristactionBean 類中植入了一個類對象,就是說我們在 實現 Action 接口的類中要是植入大量的 字段 肯定是不符合規範的。所以我們把他封裝成了對象,在表單提交的時候我們需要 name 通過對象名點屬性的方式

FristactionBeanModelDriven:類

package com.gdbd.action;

import com.gdbd.bean.UserInfo;
import com.opensymphony.xwork2.Action;
import com.opensymphony.xwork2.ModelDriven;

/**
 * 封裝Bean對象自動裝配
 * 實現ModelDriven 接口可以不使用對象點 屬性名封裝值
 * @author asus
 */
public class FristactionBeanModelDriven implements Action,ModelDriven<UserInfo> {

    private String messages;
    private UserInfo userInfo=new UserInfo();
  ...省略 Get Set 方法/***
     * 默認執行方法
     * @return
     * @throws Exception
     */
    @Override
    public String execute() throws Exception {return "index";
    }

    public String login() {
        System.out.println("攜帶參數:" + userInfo.getUserName()+"++"+userInfo.getUserPwd() + "-成功進入!!!!!!!!!!!!!");
        if ("1".equals(userInfo.getUserName()) && "1".equals(userInfo.getUserPwd())) {
            return "login";
        } else {
            return "index";
        }
    }

    @Override
    public UserInfo getModel() {
        return userInfo;
    }
}

說明:

實現 ModelDriven<UserInfo> 接口 並傳入要封裝的對象

FristactionBeanModelDriven 類中同樣植入了一個類對象,必須事先創建實例,在我們提交表單的時候 就可以不用 對象名 點 屬性了。

struts.xml:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC  "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
        "http://struts.apache.org/dtds/struts-2.0.dtd">
<struts>
    <!--
           package:包,用於對Action進行封裝
           name:包名,根元素下可以有多個包,彼此不能重名
           extends:繼承,用於指定繼承的包,相當於將繼承包下的配置信息復制到當前包
           namespace:命名空間,用於規定Action的訪問路徑,必須“/”開頭
      -->
    <package name="default" namespace="/" extends="struts-default">
        <!--action:業務控制器,用於註冊業務控制器組件
           name:action名稱,用於規定Action的訪問路徑
           class:業務控制器組件,用於指定業務控制器對應的類
           method:方法,用於指定訪問當前action時要調用的方法
           *請求URL:http://ip:port/projectName/namespace/ActionName.action
       -->
        <action name="index" class="com.gdbd.action.Fristaction">
            <!--result:輸出組件,用於轉發、重定向、直接輸出
               name:名稱,一個action下可以有多個result,彼此不能重名
               默認值轉發,元素內設置轉發的頁面
           -->
            <result name="index">/index.jsp</result>
        </action>
        <!--自動裝配Action 屬性值-->
        <action name="login" class="com.gdbd.action.Fristaction" method="login">
            <result name="login">/main.jsp</result>
            <result name="index">/index.jsp</result>
        </action>
        <!--封裝javaBean 自動封裝javaBean屬性值-->
        <action name="loginBean" class="com.gdbd.action.FristactionBean" method="login">
            <result name="login">/main.jsp</result>
            <result name="index">/index.jsp</result>
        </action>
        <!--封裝javaBean 實現ModelDriven接口不用點屬性值:自動封裝javaBean屬性值-->
        <action name="loginBeanModelDriven" class="com.gdbd.action.FristactionBeanModelDriven" method="login">
            <result name="login">/main.jsp</result>
            <result name="index">/index.jsp</result>
        </action>

    </package>

</struts>

index.jsp:

<%@ taglib prefix="s" uri="/struts-tags" %>
<%--
  Created by IntelliJ IDEA.
  User: asus
  Date: 2018/11/13
  Time: 12:11
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" isELIgnored="false" %>
<html>
<head>
    <title>第一天第一次測試</title>
</head>
<body>
<a href="index?messages=123">點擊我進行測試哦</a>
<h1>xxx--<s:property value="messages"/>--xxx</h1>
<fieldset>
    <legend>Action:零散屬性自動封裝</legend>
    <s:form name="form1" method="post" action="login">
        用戶名:
        <s:textfield name="userName"></s:textfield>
        <br/>
        密碼:
        <s:password name="userPwd"></s:password>
        <s:submit value="登陸"></s:submit>
    </s:form>
</fieldset>
<br/>
<fieldset>
    <legend>Action:封裝javaBean自動封裝值</legend>
    <s:form name="form2" method="post" action="loginBean">
        用戶名:
        <s:textfield name="userInfo.userName"/>
        <br/>
        密碼:
        <s:password name="userInfo.userPwd"/>
        <s:submit value="登陸"></s:submit>
    </s:form>
</fieldset>
<br/>
<fieldset>
    <legend>Action:封裝javaBean 實現ModelDriven接口不用點屬性值:自動封裝javaBean屬性值</legend>
    <s:form name="form3" method="post" action="loginBeanModelDriven">
        用戶名:
        <s:textfield name="userName"/>
        <br/>
        密碼:
        <s:password name="userPwd"/>
        <s:submit value="登陸"></s:submit>
    </s:form>
</fieldset>
</body>
</html>

main.jsp:

<%@ taglib prefix="s" uri="/struts-tags" %>
<%--
  Created by IntelliJ IDEA.
  User: asus
  Date: 2018/11/13
  Time: 12:11
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" isELIgnored="false" %>
<html>
<head>
    <title>第一天第一次測試</title>
</head>
<body>
<h1>成功</h1>
</body>
</html>

源碼下載地址:https://github.com/MlqBeginner/BlogGardenWarehouse/blob/master/StrutsDay01.rar

--歡迎評論:若有不足之處多多指教

Face your past without regret. Handle your present with confidence.Prepare for future without fear. keep the faith and drop the fear.

面對過去無怨無悔,把握現在充滿信心,備戰未來無所畏懼。保持信念,克服恐懼!一點一滴的積累,一點一滴的沈澱,學技術需要不斷的積澱!

分享知識-快樂自己:初始 Struts2 (基本概念)及 搭建第一個Demo