Struts2框架自學之路——Action獲取表單數據的方式以及表單數據的封裝

目錄

Action獲取表單數據的方式

  在使用servlet處理請求的過程中,可以通過request對象獲得表單提交過來的數據。採用struts2後將採用Action處理請求,而Action類中並沒有request對象,所以不能直接使用request對象獲取表單提交的數據。以下將講解如何在Action中獲取表單提交的數據。
  Action獲取表單提交的數據主要有三種方式:
(1)使用ActionContext類
(2)使用ServletActionContext類
(3)使用接口注入方式

通過ActionContext類獲取

  在Struts2中,提供了ActionContext類來訪問Servlet API,ActionContext是Action執行的上下文對象,在ActionContext中保存了Action執行所需要的所有對象,包括parameters、request、session、application等。在主要講解ActionContext中的一個方法:getParameters(),它用來返回一個包含所有HttpServletRequest參數信息的Map集合。
案例:
  form1.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>ActionContext接收表單數據</title>
</head>
<body>
<form action="${pageContext.request.contextPath}/form1.action" method="post">
    用戶名:<input type="text" name="username"/><br/>
    密 碼:<input type="password" name="password"/><br/>
    <input type="submit" value="提交">
</form>
</body>
</html>

  Form1Action.java

package com.wm103.form;

import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionSupport;
import java.util.Map;
import java.util.Set;

public class Form1Action extends ActionSupport {
    @Override
    public String execute() throws Exception {
        // 1. 獲取ActionContext對象
        ActionContext context = ActionContext.getContext();
        // 2. 獲取表單數據,其中Map集合中的key是表單name的屬性值,value是對應表單輸入項的值
        Map<String, Object> parameters = context.getParameters();
        Set<String> keys = parameters.keySet();
        for (String key: keys) {
            // 這裏是數組形式的原因是一個表單name屬性值可以對應多個value值,如複選框提交數據
            Object[] obj = (Object[]) parameters.get(key);
            System.out.println(key + ": " + Arrays.toString(obj));
        }
        return NONE;
    }
}

  struts.xml中的配置:

<package name="demo2" extends="struts-default" namespace="/">
        <action name="form1" class="com.wm103.form.Form1Action"></action>
</package>

使用ServletActionContext類獲取

  爲了直接訪問Servlet API,Struts2框架還提供了ServletActionContext類,該類包含了幾個常用的靜態方法,具體如下:
static HttpServletRequest getRequest() 獲取Web應用的HttpServletRequest對象;
static HttpServletResponse getResponse() 獲取Web應用的HttpServletResponse對象;
static ServletContext getServletContext() 獲取Web應用的ServletContext對象;
static PageContext getPageContext() 獲取Web應用的PageContext對象。
  這裏爲獲取表單數據,調用ServletActionContext中的靜態方法getRequest獲取request對象。如:
  Form2Action.java

package com.wm103.form;

import com.opensymphony.xwork2.ActionSupport;
import org.apache.struts2.ServletActionContext;
import javax.servlet.http.HttpServletRequest;

public class Form2Action extends ActionSupport {
    @Override
    public String execute() throws Exception {
        HttpServletRequest request = ServletActionContext.getRequest();
        String username = request.getParameter("username");
        String password = request.getParameter("password");
        System.out.println(username + ": " + password);
        return NONE;
    }
}

通過特定接口訪問

  (這種方式一般不使用。)
  爲了在Action中直接訪問Servlet API,Stuts2還提供了一系列接口,具體如下:

  • ServletRequestAware:實現該接口的Action可以直接訪問Web應用的HttpServletRequest實例;
  • ServletResponseAware:實現該接口的Action可以直接訪問Web應用的HttpServletResponse實例;
  • SessionAware:實現該接口的Action可以直接訪問Web應用的HttpSession實例;
  • ServletContextAware:實現該接口的Action可以直接訪問Web應用的ServletContext實例。
      這裏爲獲取表單數據,需要Action實現ServletRequestAction接口,如:
      Form3Action.java
package com.wm103.form;

import com.opensymphony.xwork2.ActionSupport;
import org.apache.struts2.interceptor.ServletRequestAware;
import javax.servlet.http.HttpServletRequest;

public class Form3Action extends ActionSupport implements ServletRequestAware {
    private HttpServletRequest request;

    @Override
    public void setServletRequest(HttpServletRequest httpServletRequest) {
        this.request = httpServletRequest;
    }

    @Override
    public String execute() throws Exception {
        String username = request.getParameter("username");
        String password = request.getParameter("password");
        System.out.println(username + ": " + password);
        return NONE;
    }
}

在Action中操作域對象

  在Servlet中有3個域對象,分別爲 request、session和servletContext。(pageContext域對象[page域]是在JSP中的)。
  使用ServletActionContext操作域對象,如:
  DomainAction.java

package com.wm103.action;

import com.opensymphony.xwork2.ActionSupport;
import org.apache.struts2.ServletActionContext;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

public class DomainAction extends ActionSupport {
    @Override
    public String execute() throws Exception {
        // 1. 獲取request域對象
        HttpServletRequest request = ServletActionContext.getRequest();
        request.setAttribute("request", "requestValue");

        // 2. 獲取session域對象
        HttpSession session = request.getSession();
        session.setAttribute("session", "sessionValue");

        // 3. 獲取servletContext域對象
        ServletContext servletContext = ServletActionContext.getServletContext();
        servletContext.setAttribute("servletContext", "servletContextValue");

        return NONE;
    }
}

Action中原始方式封裝表單數據

   通過ServletActionContext對象獲取request對象,進而使用request對象獲取表單數據,將數據到的數據封裝到實體對象去。如:
   實體類 User.java

package com.wm103.entity;

/**
 * Created by DreamBoy on 2017/5/26.
 */
public class User {
    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;
    }

    @Override
    public String toString() {
        return "User{" +
                "username='" + username + '\'' +
                ", password='" + password + '\'' +
                '}';
    }
}

  Form4Action.java

package com.wm103.form;

import com.opensymphony.xwork2.ActionSupport;
import com.wm103.entity.User;
import org.apache.struts2.ServletActionContext;
import javax.servlet.http.HttpServletRequest;

/**
 * Created by DreamBoy on 2017/5/26.
 */
public class Form4Action extends ActionSupport {
    @Override
    public String execute() throws Exception {
        HttpServletRequest request = ServletActionContext.getRequest();
        String username = request.getParameter("username");
        String password = request.getParameter("password");

        User user = new User();
        user.setUsername(username);
        user.setPassword(password);
        System.out.println(user);
        return NONE;
    }
}

Struts2中表單數據的封裝

  在實際開發中,我們需要在Action獲取到表單數據,並對錶單數據進行封裝,封裝到一個JavaBean中,然後將JavaBean傳遞給業務層。這些封裝的操作Struts2框架提供了實現方式。如下。

屬性封裝

  在Struts2中可以直接在Action中定義各種Java基本數據類型的字段,使這些字段與表單數據相對應,並利用這些字段進行數據傳遞。
  實現步驟如下:
(1)在Action成員變量中定義變量,且變量名稱與表單輸入項的name屬性值一致;
(2)在Action中生成與這些變量對應的set方法。
  案例如下:
  Data1Action.java

package com.wm103.data;

import com.opensymphony.xwork2.ActionSupport;

public class Data1Action extends ActionSupport {
    // 1. 定義變量,且變量的名稱與表單輸入項中的name屬性值一致
    private String username;
    private String password;

    // 2. 生成變量對應的set方法(這裏把getter和setter方法都生成了)
    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;
    }

    @Override
    public String execute() throws Exception {
        System.out.println(this.username + ": " + this.password);
        return NONE;
    }
}

  注:使用屬性封裝只能獲取表單數據到Action屬性中,並不能把數據直接封裝到實體類對象裏面。

模型驅動封裝(重點)

  使用模型驅動封裝的方式,我們可以直接把表單數據封裝到實體類對象。
  模型驅動:通過實現ModelDriven接口來接收請求參數,Action類必須實現ModelDriven接口,並且要重寫getModel()方法,這個方法返回的就是Action所使用的數據模型對象。
  實現步驟:
(1)讓Action類實現接口ModelDriven;
(2)在Action類中創建實體類對象成員;
(3)實現接口中getModel方法,並返回上述提及的實體類對象。
  案例如下:
  Data2Action.java

package com.wm103.data;

import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.ModelDriven;
import com.wm103.entity.User;

public class Data2Action extends ActionSupport implements ModelDriven<User> {
    // 創建實體類對象
    // 注意:要求表單輸入項的name屬性值與實體類屬性名稱一致,否則表單數據無法封裝到實體對象的屬性中去。
    private User user = new User();
    @Override
    public User getModel() {
        return user;
    }

    @Override
    public String execute() throws Exception {
        System.out.println(this.user.getUsername() + ": " + this.user.getPassword());
        return NONE;
    }
}

使用模型驅動和屬性封裝時需要注意的問題
  在一個Action中,獲取表單數據可以使用屬性封裝,也可以使用模型驅動封裝,但是不能同時使用這兩種方式獲取同一個表單數據。如果同時使用,那麼將執行模型驅動封裝數據。


表達式封裝

  使用表達式封裝也可以把表單數據封裝到實體類對象中去。表達式封裝也可以歸類於屬性封裝。
  實現步驟:
(1)在Action中聲明實體類對象;
(2)在Action中爲該實體類對象生成實體類變量的set和get方法;
(3)在表單中提交項的name屬性值中寫表達式形式,表達式的內容爲 實體類對象的名稱.實體類對象的屬性名
  案例如下:
  Data3Action.java

package com.wm103.data;

import com.opensymphony.xwork2.ActionSupport;
import com.wm103.entity.User;

public class Data3Action extends ActionSupport {
    // 1. 聲明實體類對象
    private User user;
    // 2. 生成實體類變量的set和get方法
    public User getUser() {
        return user;
    }

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

    @Override
    public String execute() throws Exception {
        System.out.println(this.user);
        return NONE;
    }
}

  在struts.xml中Action的配置:

<package name="demo2" extends="struts-default" namespace="/">
    <action name="data3" class="com.wm103.data.Data3Action"></action>
</package>

  測試頁面 data3.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>表達式封裝</title>
</head>
<body>
<form action="${pageContext.request.contextPath}/data3.action" method="post">
    用戶名:<input type="text" name="user.username"/><br/>
    密 碼:<input type="password" name="user.password"/><br/>
    <input type="submit" value="提交">
</form>
</body>
</html>

比較表達式封裝和模型驅動封裝

  • 相同點:使用表達式封裝和模型驅動封裝都可以把數據封裝到實體類對象中。
  • 不同點:
    • 使用模型驅動只能把數據封裝到一個實體類對象中。在一個Action中不能使用模型驅動把數據封裝到不同的實體類對象裏面。
    • 使用表達式封裝可以把數據封裝到不同的實體類對象中。

Struts2封裝數據到集合中

封裝數據到List集合

  將表單提交的數據存儲到List集合中,實現步驟如下(類似表達式封裝):
(1)在Action中聲明List集合對象;
(2)在該Action中生成List對象的get和set方法;
(3)在表單的提交項name屬性中填寫表達式,表達式的格式爲 List集合對象的名稱[下標].List集合中存儲的對象的屬性名稱
  案例如下:
  ListAction.java

package com.wm103.data;

import com.opensymphony.xwork2.ActionSupport;
import com.wm103.entity.User;
import java.util.List;

public class ListAction extends ActionSupport {
    private List<User> list;

    public List<User> getList() {
        return list;
    }

    public void setList(List<User> list) {
        this.list = list;
    }

    @Override
    public String execute() throws Exception {
        System.out.println(list);
        return NONE;
    }
}

  在struts.xml中Action的配置:

<package name="demo2" extends="struts-default" namespace="/">
    <action name="list" class="com.wm103.data.ListAction"></action>
</package>

  list.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>封裝數據到List集合</title>
</head>
<body>
<form action="${pageContext.request.contextPath}/list.action" method="post">
    用戶名1:<input type="text" name="list[0].username"/><br/>
    密 碼1:<input type="password" name="list[0].password"/><br/>
    <br/><br/>
    用戶名2:<input type="text" name="list[1].username"/><br/>
    密 碼2:<input type="password" name="list[1].password"/><br/>
    <input type="submit" value="提交">
</form>
</body>
</html>

封裝數據到Map集合

  將表單提交的數據存儲到Map集合中,實現步驟如下(類似表達式封裝):
(1)在Action中聲明Map集合對象;
(2)在該Action中生成Map對象的get和set方法;
(3)在表單的提交項name屬性中填寫表達式,表達式的格式爲 Map集合對象的名稱['自定義鍵值對的key值'].Map集合中存儲的對象的屬性名稱
  案例如下:
  MapAction.java

package com.wm103.data;

import com.opensymphony.xwork2.ActionSupport;
import com.wm103.entity.User;

import java.util.Map;

public class MapAction extends ActionSupport {
    private Map<String, User> map;

    public Map<String, User> getMap() {
        return map;
    }

    public void setMap(Map<String, User> map) {
        this.map = map;
    }

    @Override
    public String execute() throws Exception {
        System.out.println(map);
        return NONE;
    }
}

  在struts.xml中Action的配置:

<package name="demo2" extends="struts-default" namespace="/">
    <action name="map" class="com.wm103.data.MapAction"></action>
</package>

  map.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>封裝數據到Map集合</title>
</head>
<body>
<form action="${pageContext.request.contextPath}/map.action" method="post">
    用戶名1:<input type="text" name="map['key01'].username"/><br/>
    密 碼1:<input type="password" name="map['key01'].password"/><br/>
    <br/><br/>
    用戶名2:<input type="text" name="map['key02'].username"/><br/>
    密 碼2:<input type="password" name="map['key02'].password"/><br/>
    <input type="submit" value="提交">
</form>
</body>
</html>
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章