1 Struts2與Struts1的聯(lián)系與區(qū)別 為什么要用Struts2 struts1與struts2都是mvc框架的經(jīng)典實(shí)現(xiàn)模式。 Struts2不是從Struts1升級而來,而是有WebWork改名而來,而WebWork只是Xwork加了很多WEB攔截器而已? 區(qū)別: 1.核心控制器改成了過濾器(過濾器比Servlet的級別要高,,因?yàn)槌绦蜻\(yùn)行時是先進(jìn)入過濾器再進(jìn)入Servlet) 2.struts1要求業(yè)務(wù)類必須繼承Action或dispatchAction,,struts2不強(qiáng)制這么做,只需要提供一個pojo類,。 3.綁定值到業(yè)務(wù)類時struts1是通過ActionForm,,struts2是通過模型或?qū)傩则?qū)動直接綁定到Action屬性。 4.struts1嚴(yán)重依賴于Servlet(因?yàn)樘^于依賴于api的HttpServletRequest與HttpServletResponse的兩個參數(shù)),, struts2就則脫離了Servlet的API,。 5.管理Action時struts1是單例模式,struts2是每個請求產(chǎn)生一個實(shí)例,。 6.在表達(dá)式的支持上struts2不僅有jstl,,還有功能更加強(qiáng)大的ognl表達(dá)式。 7.struts1的類型轉(zhuǎn)換是單向的(頁面到ActionForm),,struts2是雙向的(頁面到Action再到頁面回顯) 8.校驗(yàn),,struts1沒有針對具體方法的校驗(yàn),struts2提供了指定某個方法進(jìn)行效驗(yàn),,還有框架校驗(yàn),。 9.struts2提供了攔截器,利用攔截器可以在訪問Action之前或之后增加如權(quán)限攔截等功能,。 10.struts2提供了全局范圍,,包范圍,Action范圍的國際化資源文件管理實(shí)現(xiàn),。 11.struts2支持多種視圖類型,,如:jsp,freemaker,,velocity,,源代碼等,。 具體區(qū)別可以看圖形,點(diǎn)擊這里 2.Struts2的核心是什么,體現(xiàn)了什么思想 ? ?Struts2的核心是攔截器,基本上核心功能都是由攔截器完成,攔截器的實(shí)現(xiàn)體現(xiàn)了AOP(面向切面編程)思想? 3 為何繼承ActionSupport 答: 因?yàn)锳ctionSupport實(shí)現(xiàn)了Action接口,提供了國際化,,校驗(yàn)功能,。 ActionSupport實(shí)現(xiàn)了國際化功能:因?yàn)樗峁┝艘粋€getText(String key)方法實(shí)現(xiàn)國際化,該方法從資源文件上獲取國際化信息。 Action接口提供了五個常量(success,error,login,input,none),。 4 Struts2 如何定位action中的方法 答: 1 感嘆號定位方法(動態(tài)方法),。 2 在xml配置文件中通過配置多個action,使用action的method指定方法,。 3 使用通配符(*)匹配方法,。 5 模型驅(qū)動與屬性驅(qū)動是什么 模型驅(qū)動使用時注意什么問題 答:模型驅(qū)動與屬性驅(qū)動都是用來封裝數(shù)據(jù)的。 1.模型驅(qū)動:在實(shí)現(xiàn)類中實(shí)現(xiàn)ModelDriven 通過這個實(shí)例拿到封裝進(jìn)來的值,,拿返回值的時候使用工具進(jìn)行值拷貝,。 2.屬性驅(qū)動:在實(shí)現(xiàn)類里定義屬性,生成get與set方法,,通過屬性來拿值,。 注意:模型驅(qū)動使用時注意的是在使用前先把屬性類實(shí)例化,否則會出現(xiàn)空指針錯誤,,拿返回對象的值需要用拷貝內(nèi)存因?yàn)榈刂钒l(fā)生改變,。 模型驅(qū)動不可以使用局部類型轉(zhuǎn)換器。 3.Struts2是怎樣進(jìn)行值封裝的,? struts2的值封裝實(shí)際上是采用了ognl表達(dá)式. struts2的攔截器經(jīng)過模型驅(qū)動時會先判斷action是否實(shí)現(xiàn)了ModelDriven,,如果是則拿到模型的實(shí)例放在了棧的頂部, 到屬性驅(qū)動的時候會從棧里面把棧頂?shù)膶?shí)例給取出來,,從頁面?zhèn)鬟M(jìn)來的值放在一個map集合當(dāng)中,, 通過map集合進(jìn)行迭代會通過ognl技術(shù)把值封裝到實(shí)例中。 6 Struts2如何進(jìn)行校驗(yàn) 編程校驗(yàn) 1 繼承ActionSupport,,重寫validate方法(針對所有方法)(服務(wù)器端編程,不推薦),。 2 validateXxx方法(Xxx代表的是方法名,針對某個方法進(jìn)行效驗(yàn)),。 3 如果有錯誤就把錯誤信息放在FieldError中,,并且跳轉(zhuǎn)到指定的錯誤業(yè)務(wù)類,沒有就會進(jìn)行action方法的調(diào)用,。 2 校驗(yàn)框架 每個Action類有一個校驗(yàn)文件,,命名 Action類名-validation.xml,且與Action類同目錄,這是對action里面所有的方法進(jìn)行校驗(yàn)。 對Action里面的指定方法做校驗(yàn)使用Action的類名-訪問路徑_方法名-validation.xml,。 如:StudentAction-student_add-validation.xml 在效驗(yàn)文件里又分為兩種: 字段校驗(yàn):字段用什么校驗(yàn)器來校驗(yàn),。 非字段校驗(yàn):是用校驗(yàn)器校驗(yàn)什么字段。 通俗點(diǎn)講:字段校驗(yàn):校驗(yàn)誰,,用什么方法,。 非字段校驗(yàn):用什么校驗(yàn),校驗(yàn)誰 ,。 ? 7 談?wù)凷truts2 的國際化 答: 在struts2中是使用了攔截器來實(shí)現(xiàn)國際化,。 struts2的國際化分為三部分: 1.Action范圍,這種范圍是用Action的實(shí)現(xiàn)類的類名來作為前綴__語言名稱_國家地區(qū)名(大寫).properties. 2.包范圍,,包范圍是用package作為前綴__語言名稱_國家地區(qū)名(大寫).properties,。 3.全局范圍,全局范圍的前綴默認(rèn)的是application,,可以通過xml配置文件配置常量(使用constant標(biāo)簽注冊i18l攔截器)來指定前綴,, 前綴__語言名稱_國家地區(qū)名(大寫).properties。 國際化實(shí)現(xiàn)的原理:通過i18n攔截器獲得請求參數(shù)request——locale的值(zh或者是en)并把當(dāng)前的值轉(zhuǎn)化為locale對象,, 把locale對象存在ww_trans_i18n_locale的session作用域中,,根據(jù)struts2的請求處理流程, 攔截器只會在進(jìn)入action的時候才會調(diào)用,,所有我們一般把對jsp的訪問轉(zhuǎn)化為對action的訪問。 8 OGNL是什么你在項(xiàng)目中如何使用它 OGNL是:對象圖形導(dǎo)航語言,。 原ognl是單個對象的,,在struts2的應(yīng)用是多個對象的,struts2的類型轉(zhuǎn)換也是通過ognl來實(shí)現(xiàn)的,。 Struts2中默認(rèn)的表達(dá)式語言就是ognl,,struts2的取值設(shè)值都是通過ognl來實(shí)現(xiàn)的,struts2要依靠它的標(biāo)簽才可以使用ognl。 相對于jstl或者其他表達(dá)式語言,,它有如下優(yōu)勢: 1 能夠調(diào)用對象實(shí)例的方法 2 能夠調(diào)用類的靜態(tài)方法 3 操作集合對象 4 訪問Ognl上下文 取值時ognl有三個參數(shù):1 表達(dá)式,,2 ognl的上下文(map),3 對象實(shí)例(值棧),。 如果表達(dá)式帶#號是從上下文中(map)拿值,,否則是從值棧中拿值。 設(shè)值時有四個參數(shù):1 表達(dá)式,,2 ognl的上下文(map),,3 對象實(shí)例,4 設(shè)入的值 如果表達(dá)式帶#號是把值設(shè)入上下文中(map),,否則是把值設(shè)入值棧中,。 在struts2中 ognl的實(shí)現(xiàn)關(guān)系:ActionConetxt。 ognl 3個常用的符號 # $ % # 1 構(gòu)造map,list集合,。 2 取ognl上下文的值,。 3 用來過濾集合。 $ 1 在校驗(yàn)框架中取資源文件中的值,。 2 可以在配置文件中傳遞參數(shù),。 % 使用百分號可以進(jìn)行轉(zhuǎn)義。 9 Strust2如何訪問Servlet API 答: 1:通過ActionContext可以獲得request,,application,,session三個作用域(struts2實(shí)際上是通過適配器來把servlet的api轉(zhuǎn)換為一個map, 并把這些map放在ActionContext里面),。 2:通過ActionContext的子類ServletActionContext去獲取原滋原味的API,。 3:可以通過實(shí)現(xiàn)ServletRequestAware接口,重寫里面的setServletRequest方法可以獲得request,,實(shí)際上是通過set的依賴注入,。 10 什么是攔截器 說說Struts2用攔截器來干什么 說出6個攔截器來 答: 在訪問類的某個方法或者屬性之前執(zhí)行,攔截的是Action的請求,,進(jìn)行攔截然后在方法的執(zhí)行前或者之后加入某些操作,, 如:國際化,權(quán)限,,效驗(yàn)等與源代碼無關(guān)的操作,。 國際化,表單重復(fù)提交,,類型轉(zhuǎn)換,,自動裝配,數(shù)據(jù)封裝,異常處理,,模型驅(qū)動,,請求參數(shù),處理類型轉(zhuǎn)換錯誤,,日志攔截器,。 如何實(shí)現(xiàn)自定義攔截器? 答:可以繼承MethodFilterInterceptor重寫doIntercept方法指定某個方法進(jìn)行攔截,,或者繼承AbstractInterceptor,,重寫intercept方法, 在xml配置文件中定義自定義攔截器,然后注入到攔截器棧中,,再把攔截器引用到action中,。 在把攔截器注入攔截器棧時配置標(biāo)簽,使用name屬性配置excludeMethods表示不攔截指定方法,。 在配置文件中配置includeMethods指定攔截某個方法,。 可以配置到某個action單獨(dú)使用,,也可以配置到包下面的所有action使用。 需要注意什么,? 答:注意要把默認(rèn)的攔截器棧重新引用,,否則會被覆蓋。 11 項(xiàng)目中遇到什么問題 答: 1.表單重復(fù)提交,。 在頁面使用標(biāo)簽 2.國際化必須經(jīng)過Action 原因:因?yàn)閲H化是通過i18攔截器來實(shí)現(xiàn)的,而攔截器是在訪問Action的時候才執(zhí)行,。 解決方式:在對jsp的訪問之前進(jìn)行對action的訪問,。 3.使用模型驅(qū)動拿返回值的時候地址內(nèi)存不一樣,會拿不到值,。 原因:因?yàn)閟truts2最開始是把創(chuàng)建action的實(shí)例放到ActionContext的棧頂,,后來把創(chuàng)建模型驅(qū)動的實(shí)例放到棧頂, 而通過struts2的標(biāo)簽去取值會取棧頂?shù)膶?shí)例,,而此時拿到的還是最開始的創(chuàng)建的那個實(shí)例,,所以為空。 解決方式:利用原型進(jìn)行對象拷貝,,使用拷貝工具,,BeanUtils或者是propertyUtils。 4.在頁面使用轉(zhuǎn)發(fā)會報404錯,。 原因:struts2使用的是filter機(jī)制, 解決方式:可以通過過濾器改變請求地址, 5.用字符串的時候需要用雙引號而不是單引號,單引號在外,雙引號在內(nèi),。 7.當(dāng)效驗(yàn)出錯時,要跳轉(zhuǎn)到相應(yīng)的頁面,。 解決方式:使用通配符來解決,。 ...... 這些問題都可以自己根據(jù)實(shí)際情況總結(jié) 12 ActionContext是用來干什么的 答:ActionContext是Action的上下文。 通過ActionContext這個類來可以獲得:request,,application,,session,Locale,、ValueStack,ConversionErrors 1 可以獲得servlet的api:request,,application,session,。 2 進(jìn)行國際化:獲得語言環(huán)境 Locale,。 3 收集錯誤信息:ConversionErrors,。 4 有個值棧來裝action實(shí)例與創(chuàng)建的模型驅(qū)動的實(shí)例:ValueStack。 5 ActionContext是線程安全的-用本地線程實(shí)現(xiàn)的,。 13 Struts2是如何實(shí)現(xiàn)mvc的:struts2的底層視圖默認(rèn)是freemaker,。 什么mvc? M:模型,,V:視圖,,C:控制器 在struts2中分別對應(yīng)什么? M(模型):除核心控制器外都屬于模型,,實(shí)現(xiàn)業(yè)務(wù)的類(service層與dao層),。 V(視圖):result,type,dispatcher默認(rèn)的(jsp,freemaker,,velocity,,源代碼等)。 C(控制器):核心控制器與業(yè)務(wù)控制器,。 mvc解決什么問題,? 解決了數(shù)據(jù)封裝,類型轉(zhuǎn)換,,數(shù)據(jù)效驗(yàn),,國際化,異常處理等問題,。 14.為什么要繼承默認(rèn)的包,? ? ? ?因?yàn)樵赟trtus2里面默認(rèn)有很多的常量,攔截器,還有一些bean,如果繼承默認(rèn)的包,這些默認(rèn)值和常量就會繼承過來,? 15 .常見的有那些有十幾種結(jié)果集類型, 常見的結(jié)果集類型有dispatcher,redirect,redirectAction,stream等 默認(rèn)的是dispatcher,值得是轉(zhuǎn)發(fā) redirect指重定向, redirectAction是重定向到一個Action stream是返回一個流,一般用在文件下載上面 16 開發(fā)項(xiàng)目時struts2在頁面怎樣拿值,? 從值棧中或者是ognl的上下文 17.怎么樣用Struts2進(jìn)行文件的上傳或者下載 ? ?Struts2里面已經(jīng)提供了默認(rèn)的攔截器來處理上傳,只要在jsp用了s:file標(biāo)簽,把s:from的enctype 屬性設(shè)置為 multipart/form-data,然后在action里面定義三個字段 File file ,String [file]ContentType,String [file]?FileName即可,如果有多個文件上傳,那么就用List 下載用了resust為stream的類型,然后在action定義四個屬性,默認(rèn)的有個是InputStream 的類型叫inputStream的,從硬盤上面讀取文件到這個流賦值即可. 18.簡單講下struts里面的標(biāo)簽,說不少于5個 s:iterater ?s:property s:form s:url s:if 等等 19.默認(rèn)struts2里面的標(biāo)簽取值都是從那里取值的 默認(rèn)都是從OGNL值棧里面取值的? 21.ValueStack分為那兩部分,組成部分是什么,分別怎么訪問 ?分為對象棧和ContextMap ,對象棧里面放入的是Action及其用戶定義的對象,在前臺可以直接訪問,在contextMap里面放入的是Servlet對象轉(zhuǎn)化后map,譬如requestMap,sessionMap,訪問的時候前面加#即可.? 22.標(biāo)簽 它們都可以從值棧里面取值,但是el表達(dá)式只能取屬性有g(shù)et set方法的簡單數(shù)據(jù)類型,如果要取得數(shù)組的一些方法等復(fù)雜數(shù)據(jù)對象類型,那么就要用s:property標(biāo)簽 23 struts2的請求處理流程 答: 1.客戶端發(fā)送請求,。 2.經(jīng)過一系列的過濾器(如:ActionContextCleanUp、SiteMesh等)到達(dá)核心控制器(FilterDispatcher),。 3.核心控制器通過ActionMapper決定調(diào)用哪個Action,,如果不是調(diào)用Action就直接跳轉(zhuǎn)到j(luò)sp頁面。 4.如果ActionMapper決定調(diào)用了某個Action,,核心控制器就把請求的處理交給一個代理類(ActionProxy),。 5.代理類通過配置管理器(Configuration Manager)找到配置文件(struts.xml)找到需要調(diào)用的Action類。 6.代理類還要創(chuàng)建一個Action的調(diào)度器(ActionInvocation),。 7.由調(diào)度器去調(diào)用Action,,當(dāng)然這里還涉及到一些相關(guān)的攔截器的調(diào)用。 8.Action執(zhí)行完后,,這個調(diào)度器還會創(chuàng)建一個Result返回結(jié)果集,,返回結(jié)果前還可以做一些操作(結(jié)果集前的監(jiān)聽器)。 21.struts2源碼與設(shè)計模式(講完設(shè)計模式再回顧,暫不面試) 答: 命令模式(發(fā)生.do請求封裝成action調(diào)用execute方法),,代理模式(訪問action時核心控制器把請求交給代理類(ActionProxy)去訪問Action就是代理模式),, 責(zé)任鏈模式(訪問action時經(jīng)過一系列的攔截器就使用了責(zé)任鏈模式),,適配器(把Servlet的API通過適配器轉(zhuǎn)換成Map,把Map放入ActionContext中),, 組合模式(攔截器棧和攔截器就使用到組和模式),。 源碼: 服務(wù)器啟動的時候容器會創(chuàng)建FilterDispatcher實(shí)例,進(jìn)入dispatcher.init()方法,,在init方法里面會初始化sturts2的一系列的配置文件,, 然后向服務(wù)器發(fā)送請求,進(jìn)入doFilter方法,,在里面通過調(diào)用dispatcher.serviceAction方法,進(jìn)入到Dispatcher里面的serviceAction方法,, 在這里就會把servlet的api轉(zhuǎn)換為map,并把它一個個的放在ActionContext中,,在這里還會創(chuàng)建ActionProxy的實(shí)例去調(diào)用execute方法,, 到StrutsActionProxy的execute方法,通過DefaultActionInvocation的實(shí)例去調(diào)用invoke方法,,在invoke方法里面會進(jìn)行判斷攔截器是否存在,, 如果存在就會調(diào)用intercept方法,在攔截器類(Intercept)中會通過DefaultActionInvocation實(shí)例調(diào)用里面的invock方法,它們會形成遞歸調(diào)用,, 當(dāng)攔截器不存在的時候就會進(jìn)入invokeActionOnly方法,,判斷有沒有返回結(jié)果前的監(jiān)聽器preResultListener如果有則進(jìn)去一個個執(zhí)行, 最后調(diào)用 executeResult()方法,,創(chuàng)建result返回,,執(zhí)行execute方法,并返回視圖,。 |
|