分享知識-快樂自己:初始 Struts2 (基本概念)及 搭建第一個Demo
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 1 到 Struts 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
但是,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