1.Struts的原理或業務流程
漂亮回答面試官struts2的原理
①.工作原理
在Struts2架構中的處理大概分為以下幾個步驟
1 用戶端初始化一個指向Servlet容器(例如Tomcat)的請求
2 這個請求經過一系列的過濾器(Filter)(這些過濾器中有一個叫做ActionContextCleanUp的可選過濾器,這個過濾器對于Struts2和其他架構的內建很有幫助,例如:SiteMesh Plugin)
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中的配置找到對應的傳回結果。傳回結果通常是(但不總是,也可 能是另外的一個Action鍊)一個需要被表示的JSP或者FreeMarker的模版。在表示的過程中可以使用Struts2 架構中繼承的标簽。在這個過程中需要涉及到ActionMapper
②工作流程
1、用戶端浏覽器發出HTTP請求. 2、根據web.xml配置,該請求被FilterDispatcher接收
3、根據struts.xml配置,找到需要調用的Action類和方法, 并通過IoC方式,将值注入給Aciton
4、Action調用業務邏輯元件處理業務邏輯,這一步包含表單驗證。
5、Action執行完畢,根據struts.xml中的配置找到對應的傳回結果result,并跳轉到相應頁面
6、傳回HTTP響應到用戶端浏覽器
看到網友的對Struts2的原理總結,我自己也總結以便後續的面試,以下是我的疑問
1、客服端發起一個請求,通過HTTP協定指向Tomcat容器,tomcat拿到請求她幹了什麼?
2、我們web.xml配置
<filter>
<filter-name>struts2</filter-name>
<filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>struts2</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
我們從web配置檔案中可以看到org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter,這個Filter這個類有什麼用?
這個 /* 是攔截所有的請求,他攔截了請求做了什麼處理? <url-pattern>/*</url-pattern>
3.我們struts.xml配置
<struts>
<package name="default" namespace="/" extends="struts-default">
<action name="hello">
<result>
/Hello.jsp
</result>
</action>
</package>
</struts>
2.什麼地方會出現Action
①.前端送出的form表單
<form action="test/login" method="post">
使用者:<input type="text" name="username"><br>
密碼:<input type="password" name="password"><br>
<input type="submit" value="登陸"><br>
</form>
是以可以了解為action就是獲得資料傳回資料的方法。
在SSH架構中攔截器調用中url->web.xml->struts.xml->action->service->biz->dao
②.struts.xml中會配置action攔截url,執行相關操作
其中struts.xml中會配置攔截器action,這裡package中繼承不同,在其後的result中的type也不同
<action name="RoleAction_*" class="roleAction" method="{1}">
<result name="roleListPage">/roleList.jsp</result>
<result name="addRolePage">/editRole.jsp</result>
<result name="roleListAction" type="redirectAction">
<param name="namespace">/</param>
<param name="actionName">RoleAction_findAllRoles</param>
</result>
<result name="editRolePage">/editRole.jsp</result>
</action>
<action name="Login_*" class="action.LoginAction" method="{1}">
<result type="json" name="success">
<!-- 此處将reslut的值傳回給用戶端,root的值對應要傳回的值的屬性result
注意:root為固定寫法,否則不會把result的值傳回給用戶端 -->
<!--<param name="root">username</param>-->
<!--此時傳回為null,隻有指定值-->
</result>
</action>
<!-- <package name="default" namespace="/" extends="struts-default,json-default"> -->
1.method中
{1}
是通配符,和前面的name中
*
所比對,達到簡寫的目的。
2.result中name為method中的return傳回結果,跳轉到相應頁面。
3.需要在result中使用json時,需繼承 json-default.xml,沒有的話需要導入jar依賴包。
4.如果type為json,傳回資料就為json格式,為action.java中private中含有get方法的所有取值。
{“id”:0,”password”:”123”,”registerTime”:null,”remarks”:null,”username”:”123”}
③action.java
action.java獲得前端接受的資料,傳回對應結果,或跳轉相應頁面
action實作方式有4種:
Action的四種實作方式參考
1.普通的POJO類,注意實作execute方法
public class LoginAction {
//私有屬性
private String username;
private String password;
//struts2的攔截器機制 getter setter 方法負責解析使用者請求參數 并且将請求參數值賦給action對應的屬性
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
//普通的execute方法
public String execute() throws Exception {
if("test".equals(getUsername())&&"123".equals(getPassword())){
return "success";
}else{
return "error";
}
}
}
2.實作Action接口
public class LoginAction1 implements Action
//私有屬性
private String username;
private String password;
//struts2的攔截器機制 getter setter 方法負責解析使用者請求參數 并且将請求參數值賦給action對應的屬性
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
//execute方法,和方式一比較“success”變為SUCCESS ERROR變為ERROR
public String execute() throws Exception {
if("test".equals(getUsername())&&"123".equals(getPassword())){
return SUCCESS;
}else{
return
3.繼承ActionSupport
public class LoginAction2 extends ActionSupport
//私有屬性
private String username;
private String password;
//struts2的攔截器機制 getter setter 方法負責解析使用者請求參數 并且将請求參數值賦給action對應的屬性
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
//execute方法和方式二比較沒變
public String execute() throws Exception {
if("test".equals(getUsername())&&"123".equals(getPassword())){
return SUCCESS;
}else{
return
public class User implements Serializable{
/**
*
*/
private static final long serialVersionUID = 1L;
//私有的請求參數
private String username;
private String password;
//私有的處理結果
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public User() {
super();
}
public User(String username, String password) {
super();
this.username = username;
this.password = password;
}
@Override
public String toString() {
return "User [username=" + username + ", password=" + password + "]";
}
}
public class LoginAction3 implements Action,ModelDriven<User> {
//定義用于封裝請求參數和處理結果的Model
private User user=new User();
//execute方法和方式二比較沒變
public String execute() throws Exception {
if("test".equals(user.getUsername())&&"123".equals(user.getPassword())){
return SUCCESS;
}else{
return ERROR;
}
}
//重寫getModel方法
@Override
public User getModel() {
return
/**
* 書寫BaseAction讓其餘Action繼承
*/
public abstract class BaseAction<T> extends ActionSupport implements
ModelDriven<T>, Preparable {
private static final long serialVersionUID = 1L;
public BaseAction() {
try {
/**
* BaseAction主要幹什麼?
* 接受前端送出的form input
* input必須和entity中字段名相同
*/
ParameterizedType type = (ParameterizedType) this.getClass().getGenericSuperclass();
Class<T> clazz = (Class<T>) type.getActualTypeArguments()[0];
model = (T) clazz.newInstance();
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("來到BaseAction");
}
protected T model;
@Override
public void prepare() throws Exception {
}
@Override
public T getModel() {
return
public class LoginAction extends BaseAction<UserinfoEntity> {