什麼是MVC
1.Model模型
模型的職責是負責業務邏輯,包含兩部分:業務數據和業務處理邏輯.好比實體類,
DAO,Service都屬於模型層
2.View視圖
視圖的職責是顯示界面和用戶交互(收集用戶信息)。屬於視圖的類是不包含業務
邏輯和控制邏輯的JSP
3.Controller控制器
控制器是模型層和視圖層之間的橋樑,用於流程控制。好比咱們以前項目中的ActionServlet
寫Struts2所須要的控制器配置文件struts.xml很是重要,該文件寫請求與各個Action的對應關係,
前端控制器會根據配置信息調用對應的Action(Java類)去處理請求
注意事項:
a.在編寫struts.xml放在src目錄中,而部署後該文件位於WEB-INF/classes中
b.一樣的,.properties文件也放在src下,部署後也在WEB-INF/classes/下
c.程序一啓動,struts.xml就會被加載到內存,並非現讀的
d.程序一啓動,struts.xml就會被加載到內存,並非現讀的.
Struts2提供的方便之處
1.數據的自動封裝(輸入屬性)
根據頁面組件的name屬性,自動給Action中的屬性賦值
2.數據的自動傳遞
Action中的屬性在JSP頁面能夠直接用EL表達式拿到,即自動調用某屬性的get方法
Struts2對EL表達式的支持
EL表達式是默認訪問page,request,session,application範圍的數據
在Strust2中也可使用EL表達式訪問Action對象的屬性.訪問順序是page,request,
root棧(action),session,appliction.當EL從request中獲取不到信息後,會去
ValueStack對象的root棧獲取,緣由是:Struts2重寫了HttpServletReqeust的方法。
Struts2的工做流程:
1.全部請求提交給前端控制器(FC)
2.根據配置信息肯定要調用的Action
3.建立一個ValueStack對象(每一個請求都有一個獨立的VS對象)
4.建立Action對象,把Action對象放在VS棧頂,將VS對象存到request中,存儲的key爲
"struts.valueStack"
5.控制器調用Action對象接收請求參數,並在方法根據輸入屬性算出輸出屬性
6.在調用Action以前或以後調用一系列Interceptor
7.根據Action返回的字符串肯定Result(10種類型)
8.調用Result對象,將VS中的數據按照特定的格式輸出
9.不少狀況下,Result將轉發JSP,JSP頁面用Tags取出數據並顯示
10.請求處理完後,將ValueStack對象和Action對象銷燬。
在Action中訪問Session和Application
1)利用ActionContext,返回Map類型
ActionContext context=ActionContext.getContext();
Map<String,Object> session=context.getSession()
session.put("usernmae":"chang");
Map<String,Object> rquest=(Map)context.get("request");
Map<String,Object> app=context.getApplication();
注意事項 :不推薦使用ActionContext訪問Session的方式,困爲這種方式的
「侵入性」較強。ActionContext是Struts2的API,若是使用其餘框架代替目前的Struts2
框架,而咱們實際項目中的Action數量是很是大的,每一個類修改的話,會很是麻煩。
推薦使用實現SessionAware接口的方式
2)ServletActionContext返回的是Servlet使用類型
HttpServletRequest httpreq=ServletActionContext.getRequest()
HttpSession httpsession=httpreq.getSession();
ServlerContext httpapp=ServletActionContext.getServletContext();
3)由Action中實現Aware接口,由框架底層將對象注入給Action變量
RequestAware:Map類型的request
SessionAware:Map類型的session
ApplicationAware:Map類型的application
ServletRequestAware:http
ActionContext與ServletActionContext獲取Session的異同
1.ActionContext
咱們在Action中取得request請求參數"username",
ActionContext cont=ActionContext.getContext();
Map params=cont.getParameters();
String username=(String)params.get("username");
static ThreadLocal actionContext=new ActionContextThreadLocal();
ActionContextThreadLocal是實現ThreadLocal的一個內部類,ThreadLocal
能夠命名爲"線程局部變量",它爲每個使用該變量的線程提供一個變量值的
副本,使每個線程均可以獨立地改變本身的副本,而不會和其餘線程的副本
衝突,這樣,咱們ActionContext裏的屬性只會在對應的當前請求線程中可見,
從而保證它是線程安全的.
經過ActionContext取得HttpSession: Map session=ActionContext.getContext().getSession();
2.ServletActionContext
ServletActionContext,這個類直接繼承了咱們上面介紹的ActionContext,它提供了直接
與Servlet相關對象訪問的功能,它能夠取得的對象有 :
1)javax.servlet.http.HttpServletRequest:HTTPservlet請求對象
2)javax.servlet.http.HttpServletResponse:HTTPservelt響應對象
3)javax.servlet.ServletContext:Servlet上下文信息
4)javax.servlet.ServletConfig:Servlet配置對象
5)javax.servlet.jsp.PageContext:Http頁面上下文
如何從ServletActionContext裏取得Servlet相關對象
a.取得HttpServletRequest對象
HttpServletRequeste request=ServletActionContext.getRequest();
b.取得HttpSession對象:
HttpSession session=ServletActionContext.getRequeset.getSession();
3.ServletActionContext和ActionContext聯繫
ServletActionContext和ActionContext有着一些重複的功能,在咱們的Action中,該
如何抉擇呢?
若是ActionContext可以實現咱們的功能,那最好不要使用ServletActionContext,讓咱們的
Action儘可能不要直接去訪問Servlet的相關對象
注意:在使用ActionContext時有一點要注意:不要在Action的構造函數裏使用ActionContext.getContext,
由於這個時候ActionContext裏的一些值也許沒有設置,這裏經過ActionContext取得的值也許是
null,一樣,HttpServletRequest req=ServletActionContext.getRequest()也不要放在構造
函數中,至於緣由,由於前面講到的static ThreadLocal actionContext=new
ActionContextThreadLocal(),從這裏咱們能夠看出ActionContext是線程安全的。而ServletActionContext
繼承自ActionContext,因此ServletActionContext也線程安全,...
4.struts2中得到request,response和session
a.非IOc方式
1.使用org.apache.struts2.ActionContext類,經過它的靜態方法getContext()獲取當前
Action的上下文對象
ActionContext ctx=ActionContext.getContext();
ctx.put("he":"li");//request.setAttribute("he":"li");
Map session=ctx.getSession()
HttpServletRequeset request=ctx.get(org.apache.struts2.StrutsStatic.HTTP_REQUEST);
HttpServletResponse response=ctx.get(org.apache.struts2.StrutsStatics.HTTP_RESPONSE);
這裏的session是Map對象,在Struts2中底層的session都被封裝成了Map類型,咱們能夠直接操做
這個Map對象進行對session的寫入和讀寫操做,而不用直接操做HttpSession對象
2.使用org.apache.struts2.ServletActionContext類
b.IOC方式(即便用Struts2 Aware攔截器)
要使用IOC方式,咱們首先告訴IOC容器(Container)想取得某個對象的意願,經過實現相應的接口
作到這點
public class UserAction extends ActionSupport implements SessionAware,ServletRequestAware,
ServletResponseAware
{
private HttpServletRequeset request;
private HttpServletResponse response;
public void setServletRequest(HttpServletRequest request)
{
}
}
用LoginAction繼承BaseAction
public BaseAction implements SessionAware{
protected Map<String,Object> session;
public void setSession(Map<String,Object> session)
{
this.session=session;
}
}
該類實現了SessinoAware接口,表示Struts2在啓動BaseAction時,首先,建立出
該Action的對象,放入"棧頂",後調用BaseAction的setSession方法,把session傳入
給BaseAction對象(注意:若是是普通的Action,Struts2在啓動時僅建立出該Action的對象,
而後放入「棧頂」),由此,咱們定義了session屬性,以便在以後其餘的方法中使用,爲了讓
子類也能使用,因此訪問控制符爲protected.
按照這樣的機制,咱們可讓全部的Action( 如LoginAction)繼承實現了SessinAware接口
的BaseActino,當須要更換Struts2框架爲其餘框架時,只須要修改BaseAction便可(另外的框架
只要提供一個相似SessionAware接口的接口,由BaseAction繼承)
Action屬性注入
在<action>配置中,爲Action組件的屬性指針一個初始值,該值在建立Action對象時注入,
能夠將一些變化的參數值,利用該方法指定。
例如:pageSize,password,dir存儲路徑等
public class ParamAction{
private String param1;
private String param2;
...各自的get/set方法
}
<action name="param" class="com.isoftstone.ParamAction">
<param name="param1">abc</param>
<param name="param2">10</param>
</action>前端