天天看點

Struts随寫

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> {