1. 程式人生 > >Struts2第四篇【請求資料自動封裝、Action得到域物件】

Struts2第四篇【請求資料自動封裝、Action得到域物件】

前言

前三篇的Struts博文基本把Struts的配置資訊講解完了…..本博文主要講解Struts對資料的處理

一般地,我們使用Servlet的時候都是分為幾個步驟的:

  1. 得到web層的資料、封裝資料
  2. 呼叫service層的邏輯業務程式碼
  3. 將資料儲存在域物件中,跳轉到對應的JSP頁面

現在問題來了,我們自己編寫的Action類是沒有request、response、Session、application之類的物件的….我們是怎麼得到web層的資料、再將資料存到域物件中的呢??

請求資料封裝

前面已經說過了,Struts預先幫我們完成了對資料封裝的功能,它是通過params攔截器來實現資料封裝的

            <interceptor name="params" class="com.opensymphony.xwork2.interceptor.ParametersInterceptor"/>

register.jsp

首先,我們填寫表單頁面的資料,請求Action處理資料


<form action="${pageContext.request.contextPath}/date01" method="post">
    使用者名稱:<input type="text" name="username"><br>
密碼:<input type="text" name="psd"><br> 年齡:<input type="text" name="age"><br> 生日:<input type="text" name="birthday"><br> <input type="submit" value="註冊"><br> </form>

Action封裝基本資訊

在Action設定與JSP頁面相同的屬性,併為它們編寫setter方法


    private
String username; private String psd; private int age; private Date birthday; public void setUsername(String username) { this.username = username; } public void setPsd(String psd) { this.psd = psd; } public void setAge(int age) { this.age = age; } public void setBirthday(Date birthday) { this.birthday = birthday; }

我們直接在業務方法中訪問這些變數,看是否能得到表單的值。

這裡寫圖片描述

Action封裝物件

一般地,我們註冊的時候,都是在Servlet上把基本資訊封裝到物件上…那麼在Struts怎麼做呢?

  • 建立一個User類,基本的資訊和JSP頁面是相同的。
package qwer;

import java.util.Date;

/**
 * Created by ozc on 2017/4/27.
 */
public class User {

    private String username;
    private String psd;
    private int  age;
    private Date birthday;

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPsd() {
        return psd;
    }

    public void setPsd(String psd) {
        this.psd = psd;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public Date getBirthday() {
        return birthday;
    }

    public void setBirthday(Date birthday) {
        this.birthday = birthday;
    }
}
  • 在Action中定義User物件出來,並給出setter和getter方法….值得注意的是:基本資訊只要setter就夠了,封裝到物件的話,需要setter和getter
public class ccAction extends ActionSupport {

    private User user;

    public User getUser() {
        return user;
    }

    public void setUser(User user) {
        this.user = user;
    }

    public String register() {

        System.out.println(user.getUsername());
        System.out.println(user.getPsd());
        System.out.println(user.getAge());
        System.out.println(user.getBirthday());

        return "success";
    }


}

  • 在JSP頁面,提交的name要寫成user.username之類的
<form action="${pageContext.request.contextPath}/register" method="post">
    使用者名稱:<input type="text" name="user.username"><br>
    密碼:<input type="text" name="user.psd"><br>
    年齡:<input type="text" name="user.age"><br>
    生日:<input type="text" name="user.birthday"><br>
    <input type="submit" value="註冊"><br>
</form>

這裡寫圖片描述

得到域物件

Struts怎麼把資料儲存在域物件中呢???Struts提供了三種方式

一、得到Servlet API

我們可以通過ServletActionContext得到Servlet API

由於每個使用者擁有一個Action物件,那麼底層為了維護使用者拿到的是當前執行緒的request等物件,使用ThreadLocal來維護當前執行緒下的request、response等物件…



        //通過ServletActionContext得到Servlet API
        javax.servlet.ServletContext context = ServletActionContext.getServletContext();
        HttpServletRequest request = ServletActionContext.getRequest();
        HttpSession session = request.getSession();
        HttpServletResponse response = ServletActionContext.getResponse();

二、ActionContext類

我們還可以通過ActionContext類來得到request、response、session、application被Struts封裝的Map集合

        //得到ActionContext 物件
        ActionContext context = ActionContext.getContext();
        Map<String, Object> session = context.getSession();
        Map<String, Object> application = context.getApplication();

        //這是request的Map
        Map<String, Object> request = context.getContextMap();

三、實現介面

當web容器發現該Action實現了Aware介面,會把相對應的資源通過Aware介面注射進去,實際上就是一種IOC。

Aware實際就是一種攔截器,攔截程式碼在執行Action之前執行、將資源注射到Action中

實現SessionAware, RequestAware, ApplicationAware介面,它就要在程式中實現三個方法:



    private Map<String, Object> request;
    private Map<String, Object> session;
    private Map<String, Object> application;


    @Override
    public void setApplication(Map<String, Object> map) {
        this.application = map;
    }

    @Override
    public void setRequest(Map<String, Object> map) {

        this.request = map;
    }

    @Override
    public void setSession(Map<String, Object> map) {
        this.session = map;
    }

通過這些方法,我們就可以得到對應的Map物件…..

小總結

那麼,我們有三種方法可以得到Servlet對應的物件,那麼該使用哪一種呢???

分析:

  • 第一種方法:需要匯入Servlet的包,與Struts耦合了
  • 第二種方法:只能在業務方法中使用ActionContext類得到對應的Map物件,如果有多個方法,那麼每個方法都需要寫類似的程式碼
  • 第三種方法:可以在類上定義成員變數,以至於整個類都能使用。但是需要實現類、實現對應的方法

如果我們需要使用到物件的其他方法,類似getContextPath()之類的,那麼只能使用第一種

如果我們就按照平常的開發,我們就使用第二種【獲取簡單,沒有耦合】

至於第三種,當我們將來可能開發BaseAction的時候,就使用它!