1.什么是框架
什么是框架,框架從何而來,為什么使用框架?
1).框架(framework)——半成品:
- 1.是一系列jar包,其本質是對JDK功能的拓展.jar其實就是多份字節碼的集合.
- 2.框架是一組程序的集合,包含了一系列的最佳實踐,作用是解決某一個領域的問題.
不同類型的框架,解決不同領域的問題.
最佳實踐(Best Practice):實際上是無數程序員經歷過無數次嘗試之后,總結出來的處理特定問題的特定方法.
如果把程序員的自由發揮看作是一條通往成功的途徑,最佳實踐就是其中的最短路徑,能極大的解放生產力(提高效率).
2).最佳實踐三要素:
- 可讀性
- 可維護性
- 可拓展性.
簡單就是美:
- 消除重復
- 化繁為簡
- 簡單必須可讀,簡單必須可拓展
減少依賴,消除耦合
3).Web開發中的最佳實踐:分層開發模式(技術層面的"分而治之")
JavaEE開發根據職責的縱向劃分:表現層,業務層,持久層:
- 表現層(Predentation Layer):Web層/MVC層/UI層:MVC框架:負責處理與界面交互的相關操作——(EasyJWeb/Struts/Struts2/SpingMVC)
- 業務層(Business Layer):service層,負責復雜的業務邏輯計算和判斷——(Spring,一站式容器)
- 持久層(Persistent Layer):DAO層,負責將業務邏輯數據進行持久化存儲——(Hibernate/MyBatis)
2.MVC設計思想
1).思想:責任分離.
- M: 數據模型對象:封裝數據,封裝處理業務的功能.
- V: 視圖(界面):給用戶呈現界面,展現數據.
- C: 控制器: 接受請求/控制界面跳轉.
2).MVC框架的功能作用(WEB開發常見功能):
MVC令程序開發有章可循,撇開框架,但是表現層的困惑也就出來了.
表現層需要處理的功能:
- 設置編碼
- 接受請求參數
- 參數類型轉換
- 把參數封裝成對象
- 響應
- 驗證
- 文件上傳
- 國際化
- Token
- 自定義標簽.
3.前端控制器
1).什么是前端控制器:
前端控制器(Front Controller)/核心控制器:是J2EE中的的一個設計模式.
目的:針對有多個請求的共同操作做封裝.
2).前段控制器原理
4.mini MVC
5.Struts2簡介
1).Struts2的前世今生:
- 1.早期開發模型Servlet+JSP+JavaBean(Model2)顯得力不從心:流程凌亂、數據傳遞無序、缺乏輔助功能。
↓ - 2.MVC模式的輕量級Web應用框架:Apache Struts1很快風靡全球。
代碼結構劃分合理,實用工具框架(如驗證框架、國際化框架,標簽)等。
↓ - 3.時間推移,Struts1的缺點:
線程不安全、靈活性低、和ServletAPI耦合、頁面傳值麻煩等。
↓ - 4.異軍突起,SpringMVC和OpenSymphony的WebWork等。
↓ - 5.Apache Struts + OpenSymphony WebWork2 = Struts2
2).Struts2:基于MVC的輕量級的Web應用框架,
來源于Webwork2與Struts1.x完全不兼容
Struts2 是一個非常優秀的MVC框架,基于Model2 設計模型.
由傳統Struts1和WebWork兩個經典框架發展而來:Struts2框架=Struts2+XWork
3).Strust2 核心功能:
- 允許POJO(Plain Old Java Objects)對象作為Action.
- Action的execute 方法不再與Servlet API耦合,更易測試
- 支持更多視圖技術(JSP、FreeMarker、Velocity)
- 基于Spring AOP思想的攔截器機制,更易擴展
- 更強大、更易用輸入校驗功能
- 整合Ajax支持
等等
4).Struts2框架下目錄分析(struts-2.3.24-all.zip):
apps:該文件夾包含了基于struts2 的示例應用,這些示例應用對于學習者是非常有用的
docs:該文件夾下包含了struts2 相關文檔,包括struts2 快速入門、struts2的文檔以及API文檔等
lib:該文件夾下包含了Struts2框架和核心類庫,以及struts2第三方插件類庫
src: 該文件夾下包含了Struts2框架的全部源代碼
6.Struts2的HelloWorld
1).Struts2運行必要jar包:
- struts2-core-2.3.1.1.jar:Struts 2框架的核心類庫
- xwork-core-2.3.1.1.jar:Command模式框架,WebWork和Struts2都基于xwork
- ognl-3.0.3.jar:對象圖導航語言(Object Graph Navigation Language), struts2框架通過其讀寫對象的屬性
- freemarker-2.3.18.jar:Struts 2的UI標簽的模板使用FreeMarker編寫
- commons-logging-1.1.x.jar:ASF出品的日志包,Struts 2框架使用這個日志包來支持Log4J和JDK 1.4+的日志記錄。
- commons-fileupload-1.2.2.jar: 文件上傳組件,2.1.6版本后需要加入此文件
- commons-io-2.0.1.jar:傳文件依賴的jar包
- commons-lang-2.5.jar:對java.lang包的增強
2).開發Struts2的Hello程序:
1.準備Struts2依賴的jar文件.
注意:別拷貝Struts2中lib下所有的jar
Struts2根/apps下,解壓struts2-blank.war,拷貝其WEB-INF/lib中的所有的jar到自己的項目中.
2.在web.xml中配置前端控制器.StrutsPrepareAndExecuteFilter-(參閱struts2-blank項目的web.xml文件.)
3.準備Struts2的配置文件:struts.xml.從struts2-blank\WEB-INF\classes中拷貝到項目的source folader目錄.
4:定義一個POJO類:HelloAction,提供一個sayHello方法(公共無參數).
5.在struts.xml中,配置HelloAction.(把HelloAction交給Struts2管理).
6:部署項目,訪問Action:
訪問格式:http://ip:port/contextPath/namespace/actionName[.action]
http://localhost/pss/hello.action
7.Eclipse支持struts.xml語法提示
- 方式1:如果可以聯網,Eclipse工具就可以把struts.xml依賴的struts-2.3.dtd文件下載下來.
-
方式2:離線情況,手動的管理dtd文件.
(struts-2.3.dtd文件在struts2-core-2.3.24.jar文件中.)
關閉xml文件,再打開.
8.Struts2簡單執行流程
9.配置文件和常見的常量配置
1).文件拆分
在大部分應用里,隨著應用規模的增加,系統中Action的數量也會大量增加,導致struts.xml配置文件變得非常臃腫。為了避免struts.xml文件過于龐大、臃腫,提高struts.xml文件的可讀性,我們可以將一個struts.xml配置文件分解成多個配置文件,然后在struts.xml文件中包含其他配置文件。下面的struts.xml通過<include>元素指定多個配置文件:
struts.xml:
<struts>
<include file="struts-part1.xml"/>
<include file="struts-part2.xml"/>
</struts>
2).Struts2中的6大配置文件:
Struts2框架按照如下順序加載struts2配置:
前三個文件時框架自帶的,我們不能修改,只能使用.
- 1.default.properties 該文件保存在 struts2-core-2.3.7.jar 中 org.apache.struts2包里面:包含了Struts2的默認常量配置
- 2.struts-default.xml 該文件保存在 struts2-core-2.3.7.jar:包含了框架依賴的對象配置和結果類型,攔截器等配置.
- 3.struts-plugin.xml 該文件保存在Struts2框架的插件中:struts-Xxx-2.3.7.jar.由插件提供
前三個文件時框架自帶的,我們不能修改,只能使用.
后三個文件是我們可以修改操作的.
- 4.struts.xml 該文件是web應用默認的struts配置文件.重點.配置自定義的Action和其他信息.
- 5.struts.properties 該文件是Struts的默認配置文件-->可以修改default.properties 的常量配置(不用).
- 6.web.xml 該文件是Web應用的配置文件
如果多個文件配置了同一個struts2 常量,則后一個文件中配置的常量值會覆蓋前面文件配置的常量值.
注意:一般的,我們只在struts.xml中做常量配置.
<constant name="struts.action.extension" value="action,opensource,do,,"/>
3).常見的常量配置:
指定默認編碼集,作用于HttpServletRequest的setCharacterEncoding方法 和freemarker 、velocity的輸出
<constant name="struts.i18n.encoding" value="UTF-8"/>
該屬性指定需要Struts 2處理的請求后綴,該屬性的默認值是action,即所有匹配*.action的請求都由Struts2處理。如果用戶需要指定多個請求后綴,則多個后綴之間以英文逗號(,)隔開
<constant name="struts.action.extension" value="action,,"/>設置瀏覽器是否緩存靜態內容,默認值為true(生產環境下使用),開發階段最好關閉
<constant name="struts.serve.static.browserCache" value="false"/>當struts的配置文件修改后,系統是否自動重新加載該文件,默認值為false(生產環境下使用),開發階段最好打開
<constant name="struts.configuration.xml.reload" value="true"/>開發模式下使用,這樣可以打印出更詳細的錯誤信息
<constant name="struts.devMode" value="true" />:修改struts.xml之后,不要重啟Tomcat.默認的視圖主題
<constant name="struts.ui.theme" value="simple" />是否支持動態方法調用
<constant name="struts.enable.DynamicMethodInvocation" value="false"/>
10.package,action,result配置
1).<package>元素: 是<struts>根元素的子元素.
<package name="" extends="" namespace="" abstract=""></package>
用來對多個<action>元素分類管理,和Java中的package沒有關系.
常見的屬性:
name: 表示<package>元素的名字,但是要保證不同的<package>元素的name不同. 可以通過該名字被其他的包所指代.
extends: 表示當前<package>繼承哪一個<package>,一般都是:struts-default.
而struts-default其實就是struts-default.xml中<package>元素的名字.
繼承struts-default之后,就擁有了該<package>定義的所有資源.(結果返回類型,攔截器..,
如果當前<package>元素需要繼承多個<package>,可以以逗號分割即可.namespace: 表示命名空間,一般的以"/"打頭.命名一般以模塊名.如: /crm, /oa. 和<action>的name決定了一個Action類的訪問路徑.
abstract: 抽象的,缺省值是false. 若一個<package>的abstract="true",那么該<package>中就不能再定義<action>元素,只能用來繼承.
在開發中的最佳實踐:
2).<action>元素:是<package>元素的子元素.
當前某一個action類需要被外界訪問,此時才做配置.
專門用來配置Action對象的(有Action類不一定有action元素,可能某一個Action僅僅是作為父類而存在).
(有action元素,不一定非得有Action類(因為有默認的Action類).)
<action name="" class="" method=""/>
常見的屬性:
- name: action的名稱,在同一個<package>中,action的名字必須唯一. 和<package>的namespace共同決定了一個Action類的訪問路徑.
注意:action的name值不能以"/"打頭. - class:一個Action類的全限定名. 缺省值:ActionSupport類.
- method:當前Action動作訪問的方法, 缺省值:execute.
訪問路徑: http://ip:port/contextPath/namespace/action名[.action]
3).<result>元素:配置結果視圖.
<result name="" type=""></result>
- 局部結果視圖: <result>定義在<action>中.
- 全局結果視圖: <result>定義在<global-results>中,而<global-results>在<package>中
<package name="oa" extends="basePkg" namespace="/oa">
<global-results>
<result></result>
</global-results>
</package>
常見的屬性:
- name:Action方法返回的邏輯視圖名稱. 缺省值:success.
- type:結果的跳轉類型.該類型的值在struts-default.xml中已經預定義好了. 缺省值:dispatcher.
常見的type值(結果類型):- dispatcher: 表示從Action請求轉發到頁面(JSP).
- redirect: 表示從Action重定向到頁面(JSP).
- chain: 表示從Action請求轉發到另一個Action.
- redirectAction: 表示從Action重定向到另一個Action.
- stream: 表示返回流. 文件下載時使用.
<param name="">表示參數:name缺省值:location(地址)
先找當前Action的局部結果視圖:
- 1.找 到:跳轉
- 2.找不到: 繼續找當前<package>中的全局的結果視圖.
- 1.找 到:跳轉
- 2.找 不到:報錯.No result defined will.
11.Action類的三種編寫方式
第一種.使用公共的POJO類作為Action. 提供公共的無參數的Action方法.(不推薦).
缺點:
沒有一種方式約束Action方法必須是公共的無參數的.
Action方法的返回邏輯視圖名可以自定指定. 有時起名不規范. 比如:"ooxx".
解決方案:第二種.
第二種.定義一個類,實現于com.opensymphony.xwork2.Action接口.并覆寫execute方法即可.(不推薦)
Action接口中,不僅提供了Action方法的聲明,也提供了常用的邏輯視圖名稱:
public static final String SUCCESS = "success";
public static final String NONE = "none";
public static final String ERROR = "error";
public static final String INPUT = "input";
public static final String LOGIN = "login";
缺點:
不支持國際化,數據校驗,消息機制.
解決方案:第三種
第三種.定義一個類,繼承于com.opensymphony.xwork2.ActionSupport類.(推薦)
public class ActionSupport implements Action, Validateable, ValidationAware, TextProvider, LocaleProvider, Serializable {}
真實開發中,我們卻往往再提供一個BaseAction類.
ActionSupport.
--BaseAction(表示所有自定義Action類的基類,封裝了其他Action共同的代碼)
-----AAction.
-----BAction.
12.OGNL和ValueStack(值棧)
13.Action中多方法調用
Action中存在多個Action方法會造成<action>配置的臃腫.
解決方案:
方案1: DMI:動態方法調用 :官方不推薦.
格式: action名!方法名
比如: emp!edit emp!list
在Struts2新的版本中,默認的關閉了DMI.若我們需要使用DMI,就需要配置常量,啟用動態方法調用.
此時:<action/>元素不需要指定method屬性值.
<constant name="struts.enable.DynamicMethodInvocation" value="true"/>
方案2: 使用通配符的方式類配置: 通配符:(表示任意字符)
<action name="emp_*" class="com._520it.manymethod.EmployeeAction" method="{1}">
Action的名字: emp_Action方法: 比如:
emp_list,那么{1}的值就是list
emp_edit,那么{1}的值就是edit
兩個通配符:
<action name="*_*" class="com._520it.manymethod.{1}Action" method="{2}">
Action名字:Action類名_Action方法.
比如:Employee_list,表示調用的EmployeeAction中的list方法
比如:Department_edit,表示調用DepartmentAction中的edit方法.