Struts2(二)— Result結果配置、Servlet的API的訪問、模型驅動、屬性驅動

来源:https://www.cnblogs.com/gdwkong/archive/2018/02/13/8367055.html
-Advertisement-
Play Games

本文簡要的介紹類Struts2的Result結果配置、Servlet的API的訪問,以及模型驅動、屬性驅動基本使用示例。 ...


一.Result結果配置

1.全局和局部結果

​   平常我們設置跳轉頁面,是在action標簽裡面加上 result標簽來控制,這種設置的頁面跳轉,稱之為局部結果頁面但是我們有時候在很多個action裡面,針對不同的結果進行跳轉時,也有可能跳轉同一個頁面,那麼這個時候就可以配置全局結果頁面。

1.1局部結果
  • 在action裡面寫上的result跳轉的頁面,稱之為局部結果頁面配置

    <action name="demo01_*" class="com.pri.web.action.ActionDemo01" method="{1}">
         <result name="error">/error.jsp</result>
    </action>
1.2全局結果
  • 如果有多個action的結果跳轉的頁面是一樣的,那麼我們可以提取出來,做成全局結果頁面的配置. 全局頁面通過package標簽中配置global-results標簽來定義

    <package name="test" extends="struts-default" namespace="/">
        <global-results>
            <result name="error">/error.jsp</result>
        </global-results>
        ....
    </package>

優先順序: 局部>全局

1.3不同包裡面的全局結果的配置
<!--把全局的結果抽取到父包裡面  -->
<package name="base" extends="struts-default" abstract="true">
     <global-results>
          <!--全局的結果: 配置在package裡面的 特點:可以被當前包裡面所有的Action共用; 使用場景:不同的Action需要跳轉到相同的結果的時候eg: 錯誤頁面, msg頁面等  -->
          <result name="error">/msg.jsp</result>
     </global-results>
</package><package name="test" extends="base" namespace="/">
      <action name="demo01_fun01" class="com.pri.web.ActionDemo01" method="fun01">
      </action>
      <action name="demo02_fun02" class="com.pri.web.ActionDemo02" method="fun02">
      </action>
</package> 

2.結果的類型【常用】

​   根據前面學的servlet知識,我們知道伺服器響應給瀏覽器的時候,有三種類型:response響應JSON數據&請求轉發 & 重定向。 對於Struts2而言,無非就是Action跳轉(轉發重定向)到頁面,Action跳轉到Action....

  文檔位置 docs/docs/result-types.html

2.1Action跳轉頁面
  • 轉發(預設)
<result name="success" type="dispatcher">/index.jsp</result> 
  • 重定向
<result name="success" type="redirect">/index.jsp</result>
2.2Action跳轉Action
  • 轉發

    <action name="demo01_*" class="com.pri.web.action.ActionDemo01" method="{1}">
            <result name="success" type="chain">demo02_fun02</result>
    </action>
    <action name="demo02_*" class="com.pri.web.action.ActionDemo02" method="{1}">
    </action>
  • 重定向

    <action name="demo01_*" class="com.pri.web.action.ActionDemo01" method="{1}">
            <result name="success" type="redirectAction">demo02_fun02</result>
    </action>
    <action name="demo02_*" class="com.pri.web.action.ActionDemo02" method="{1}">
    </action>
2.3其它的結果

​      一般來說,我們平常的請求到來,我們要不就是跳轉到 頁面上 ,要不就是跳轉到下一個action 去。 但是除了這兩種結果之外,我們仍然還有一些其他結果類型可以控制.

​   比如: 我們可以返回一個文件數據給客戶端 (比如文件下載).再比如: 我們可以返回一個json字元串給來請求的頁面,而不是重新打開新的頁面 (有點像之前的Ajax請求,返回json數據)

2.3.1響應JSON數據【瞭解】
  • 導入struts-json-plugin-xxx.jar

  • Java代碼

  •  1 public class ActionDemo01 extends ActionSupport {
     2     private User json;
     3     
     4     public User getJson() {
     5         return json;
     6     }
     7  8     public String fun01(){
     9         json = new User();
    10         json.setName("張三");
    11         json.setAge(18);
    12         json.setPassword("123456");
    13         
    14         return "success";
    15     }
    16 }
    • 配置文件

    • <struts>
          <package name="test" extends="json-default" namespace="/">
              <action name="demo01" class="com.pri.web.action.ActionDemo01" method="fun01">
                  <result name="success" type="json">
                        <param name="root">json</param>
                 <!--這裡的name必須是root  至於這個json 是我們在action裡面的成員 變數 json(屬性)  -->
                   </result>
              </action>
          </package>
      </struts>

  註意:

    • ​ root:配置對象。action類中必須提供一個和root值相同的屬性名稱,且需要提供getter方法。
    • ​ package需要繼承json-default
    • ​ result的type值是json
2.3.2響應流(文件下載)【瞭解】
  • Action裡面的代碼

  •  1 public class ActionDemo01 extends ActionSupport {
     2     private InputStream stream;
     3     
     4     public void setStream(InputStream stream) {
     5         this.stream = stream;
     6     }
     7     public InputStream getStream() {
     8         return stream;
     9     }
    10     public String fun01() throws Exception{
    11         System.out.println("demo01 執行了...");
    12         stream = new FileInputStream("E:/data/Desktop/a.jpg");
    13         
    14         return "success";
    15     }
    16 }
  • 配置文件

    <struts>
        <package name="test" extends="struts-default" namespace="/">
            <action name="demo01" class="com.pri.web.action.ActionDemo01"
                method="fun01">
                <result name="success" type="stream">
                    <param name="contentType">image/jpeg</param>
                    <param name="inputName">stream</param>
                    <param name="contentDisposition">attachment;filename="b.jpg"</param>
                    <param name="bufferSize">1024</param>
                </result>
            </action>
        </package>
    </struts>

註意:

  • ​ contentType:下載文件類型
  • ​ contentDisposition:下載到客戶端時,客戶端文件名稱
  • ​ bufferSize:讀文件的緩存大小
  • ​ inputName:對應要輸出到客戶端流聲明的名稱,也就是說需要和Action裡面聲明的變數名要一致

二、Struts2中的Servlet的API的訪問

​      客戶端與服務端交互時,通常會帶參數過來,伺服器也會回寫數據給客戶端。在此過程中,參與著請求,和響應,以及會話。servlet在此過程中提供了HttpServletRequest作為獲取請求數據的方案,HttpServletResponse作為響應的方案,HttpSession負責了會話方案。Struts其實是基於servlet實現的web框架,他需要遵循規則提供請求,響應和會話的API供開發人員使用,因此Struts針對這一問題提供了自己的一套API封裝,提供了多種方式的訪問。

1.ActionContext

1.1概述

​    ActionContext是Action的上下文,Struts2自動在其中保存了一些在Action執行過程中所需的對象,比如session, parameters等。Struts2會根據每個執行HTTP請求的線程來創建對應的ActionContext,即一個線程有一個唯一的ActionContext。

1.2使用
  • 獲得(創建)ActionContext

    ActionContext context = ActionContext.getContext();
  • 獲得請求參數

    Map<String, Object> parameters = context.getParamters();

    ​相當於Servlet中的request.getParamters()方法,只能獲得所有的請求參數

2.ServletActionContext

2.1概述

​   ServletActionContext繼承ActionContext,因此比ActionContext功能要強大。ServletActionContext提供了多個靜態方法。

2.2使用
  • 獲得Request對象

    HttpServletRequest request = ServletActionContext.getRequest();
  • 獲得Response對象

    HttpServletResponse response = ServletActionContext.getResponse();
  • 獲得ServletContext

    ServletContext servletContext = ServletActionContext.getServletContext();

3.實現介面的方式

  • 編寫Action,讓Action使用實現特定的介面的方式訪問Servlet的API,有如下介面可以實現
    • ​ ServletContextAware
    • ​ ServletRequestAware
    • ​ ServletResponseAware
    • ​ SessionAware
    • ​ ApplicationAware
  • Eg:

  •  1 public class ActionDemo03 extends ActionSupport implements ServletRequestAware {
     2     private HttpServletRequest request;
     3     public String fun03() throws IOException{
     4         HttpServletRequest request = ServletActionContext.getRequest();
     5         String username = request.getParameter("username");
     6         String password = request.getParameter("password");
     7         System.out.println(username+":"+password);
     8         return NONE;
     9     }
    10 11     @Override
    12     public void setServletRequest(HttpServletRequest request) {
    13         this.request = request;
    14     }
    15 }

三、獲得請求參數

1.獲得零散數據

1.1使用上面介紹的Struts2中的Servlet的API獲取
  • ActionContext

    //1.創建ActionContext對象
    ActionContext context = ActionContext.getContext();
    //2.獲得所有的請求參數
    Map<String, Object> parameters = context.getParamters();
  • ServletActionContext

    //1.獲得request對象
    HttpServletRequest request = ServletActionContext.getRequest();
    requet.getParameter(String key);
    requet.getParameterValues(String key);
    requet.getParameterMap();
1.2屬性驅動【常用】
  • 頁面

    <h1>01使用屬性驅動</h1>
    <form method="post" action="${pageContext.request.contextPath }/demo01">
        用戶名:<input type="text" name="username"/><br/>
        密    碼:<input type="password" name="password"/><br/>
        <input type="submit"/>
    </form>
  • Action.java

    public class ActionDemo01 extends ActionSupport {
        private String username;//和表單裡面的name屬性值要一致,並且提供set方法
        private String password;//和表單裡面的name屬性值要一致,並且提供set方法
        public void setUsername(String username) {
            this.username = username;
        }
    ​
        public void setPassword(String password) {
            this.password = password;
        }
        public String fun01(){
            System.out.println(username+":"+password);
            return NONE;
        }
    }

2.獲得封裝後的數據(對象)

2.1屬性驅動
  • 頁面

    <h1>01使用屬性驅動方式</h1>
    <form method="post" action="${pageContext.request.contextPath }/demo01">
        用戶名:<input type="text" name="user.username"/><br/>
        密    碼:<input type="password" name="user.password"/><br/>
        <input type="submit"/>
    </form>
  • Action.java

  •  1 public class ActionDemo01 extends ActionSupport {
     2     //1. User類裡面的欄位屬性需要和表單裡面的name屬性一致, 且提供無參構造
     3     //2. user需要set和get方法
     4     private User user;
     5     public User getUser() {
     6         return user;
     7     }
     8     public void setUser(User user) {
     9         this.user = user;
    10     }
    11 12     public String fun01(){
    13         System.out.println(user.toString());
    14         return NONE;
    15     }
    16 }
2.2模型驅動【常用】
  • 頁面

    <h1>02使用模型驅動方式</h1>
    <form method="post" action="${pageContext.request.contextPath }/demo02">
        用戶名:<input type="text" name="username"/><br/>
        密    碼:<input type="password" name="password"/><br/>
        <input type="submit"/>
    </form>

Action.java

 1 public class ActionDemo02 extends ActionSupport implements ModelDriven<User> {
 2     
 3     private User user;
 4     
 5     public String fun02(){
 6         System.out.println(user.toString());
 7         return NONE;
 8     }
 9     @Override
10     public User getModel() {
11         if(user == null){
12             user = new User();
13         }
14         return user;
15     }
16 }

結論:我們在實際開發裡面,

  • ​ 如果要獲得單個(零散)的數據,我們通常用屬性驅動
  • ​ 如果要獲得封裝後的數據, 我們通常用模型驅動
2.3封裝到集合

​   封裝到集合,一般我們會在批量添加 、批量更新場景下見到。也就是說頁面上同一個請求,這時候提交過來多份數據,如果我們是批量添加用戶的話,可能會提交過來多個用戶,那麼這個時候,我們就需要把他們封裝到List集合或者Map集合中去。 刨去批量操作、我們比較少用這種封裝到集合的知識點。

2.3.1封裝到list
  • 頁面

    <h1>01封裝到list</h1>
    <form method="post" action="${pageContext.request.contextPath }/demo01">
        用戶名:<input type="text" name="list[0].username"/><br/>
        密    碼:<input type="password" name="list[0].password"/><br/>
        用戶名:<input type="text" name="list[1].username"/><br/>
        密    碼:<input type="password" name="list[1].password"/><br/>
        <input type="submit"/>
    </form>
  • Action.java

    public class ActionDemo01 extends ActionSupport {
        
        private List<User> list;
        
        public List<User> getList() {
            return list;
        }
    ​
        public void setList(List<User> list) {
            this.list = list;
        }
    ​
        public String fun01(){
            System.out.println(list.toString());
            return NONE;
        }
    }
2.3.2封裝到Map
  • 頁面

    <h1>02封裝到map</h1>
    <form method="post" action="${pageContext.request.contextPath }/demo02">
        用戶名:<input type="text" name="map['user1'].username"/><br/>
        密    碼:<input type="password" name="map['user1'].password"/><br/>
        用戶名:<input type="text" name="map['user2'].username"/><br/>
        密    碼:<input type="password" name="map['user2'].password"/><br/>
        <input type="submit"/>
    </form>
  • Action.java

  • public class ActionDemo02 extends ActionSupport {
        
        private Map<String, User> map;
        public Map<String, User> getMap() {
            return map;
        }
    ​
        public void setMap(Map<String, User> map) {
            this.map = map;
        }
    ​
        public String fun02(){
            Set<Entry<String, User>> entrySet = map.entrySet();
            for (Entry<String, User> entry : entrySet) {
                System.out.println(entry.getKey()+":"+entry.getValue().toString());
            }
            return NONE;
        }

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • //輸入框 input { outline: none; } //按鈕 button::-moz-focus-inner { border: none; } ...
  • 筆者在這裡附上一段代碼,請讀者思考一下程式的運行結果: 運行結果如下: 不知道讀者有沒有猜對呢?哈哈,可能很多讀者會認為第一行的console.log(a);會輸出undefine ,因為大家都知道變數提升與函數提升,而Javascript編譯器執行代碼也是逐行執 行,當js文件首先載入到記憶體時,編 ...
  • 確定盒子的基線的規則 1.1 確定inline-block的基線 The baseline of an 'inline-block' is the baseline of its last line box in the normal flow, unless it has either no in ...
  • 純CSS3打造自行車 廢話不想多說,我們直接上圖和代碼最實際。 我們先來看看效果圖吧,看了效果圖之後你們就會有動力去打造屬於你們自己的自行車啦 怎麼樣,帥不帥呀,快來打造帥帥的自行車吧 代碼如下,複製即可用,不過這是我的自行車,你們可不能盜取我的自行車哦 你們打造好你們的自行車了嗎?還沒有的小伙伴們 ...
  • 使用JS實現大風車! 下麵附上效果圖: 最後附上源碼,複製即可用: 如果有錯誤的地方,請聯繫我改正!謝謝!!! ...
  • 和資料庫打交道的程式員繞不開的話題就是: 事務 ,作為一個簡化訪問資料庫的應用程式的編程模型。通過使用事務,應用程式可以忽略某些潛在的錯誤場景和併發問題,由資料庫負責處理它們。而並非每個應用程式都需要事務,有時削弱事務性擔保或完全放棄事務,可以獲得更高的性能或更高的可用性。怎麼樣更好的理解資料庫中的 ...
  • gets() 與 scanf() 函數相處呢有點小尷尬的,就是 gets() 在 scanf() 後邊就愛搗亂。為什麼呢,先瞭解它們兩者之間的異同: 同: 都是可以接受連續的字元數據 併在字元結束後自動加上 '\0',標誌結束接受 異: scanf 不能接受空格、製表符Tab、回車等,遇空格時就結束 ...
  • 引言:CSP(http://www.cspro.org/lead/application/ccf/login.jsp)是由中國電腦學會(CCF)發起的"電腦職業資格認證"考試,針對電腦軟體開發、軟體測試、信息管理等領域的專業人士進行能力認證。認證對象是從事或將要從事IT領域專業技術與技術管理人 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...