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