Java框架之Struts2(二)

来源:http://www.cnblogs.com/1693977889zz/archive/2017/12/21/8076434.html
-Advertisement-
Play Games

一、Action 配置說明 訪問的時候 : http://localhost:8080/Struts2-02/addUser 註意 1) action 沒有寫 class 屬性 2) action 沒有寫 method 屬性 3) result 沒寫 name 屬性 那它們的值是怎麼得到的呢? 實際 ...


一、Action 配置說明

//請求的直接轉發
<package name="packageUser" namespace="" extends="struts-default">
    <action name="addUser">
    <result>success.jsp</result>
    </action>    
</package>

訪問的時候 : http://localhost:8080/Struts2-02/addUser

註意

1) action 沒有寫 class 屬性

2) action 沒有寫 method 屬性

3) result 沒寫 name 屬性

那它們的值是怎麼得到的呢? 實際上,它們都是有預設值的,在每個action被執行的時候,它都會被反射成一個java對象,// struts2中的action是多實例的

action 配置中,各項的預設值

1) 如果不寫class 它的預設值是  ActionSupport

2) 如果不指定 method 它的預設值是 execute   

3) 如果不指定result 的name  預設是 success

上面的寫法,相當於

<action name="addUser" class="com.opensymphony.xwork2.ActionSupport" method="execute" >
<result name="success" >success.jsp</result>
</action>    

二、result 的配置說明

在 struts2-core-2.3.16.3.jar  -> 下的 struts-default.xml 文件中有如下聲明:

<package name="struts-default" abstract="true">
    <result-types>
        <result-type name="chain" class="com.opensymphony.xwork2.ActionChainResult"/>
        <result-type name="dispatcher" class="org.apache.struts2.dispatcher.ServletDispatcherResult" default="true"/>
        <result-type name="freemarker" class="org.apache.struts2.views.freemarker.FreemarkerResult"/>
        <result-type name="httpheader" class="org.apache.struts2.dispatcher.HttpHeaderResult"/>
        <result-type name="redirect" class="org.apache.struts2.dispatcher.ServletRedirectResult"/>
        <result-type name="redirectAction" class="org.apache.struts2.dispatcher.ServletActionRedirectResult"/>
        <result-type name="stream" class="org.apache.struts2.dispatcher.StreamResult"/>
        <result-type name="velocity" class="org.apache.struts2.dispatcher.VelocityResult"/>
        <result-type name="xslt" class="org.apache.struts2.views.xslt.XSLTResult"/>
        <result-type name="plainText" class="org.apache.struts2.dispatcher.PlainTextResult" />
        <result-type name="postback" class="org.apache.struts2.dispatcher.PostbackResult" />
    </result-types>
        .... 
</package>

1) dispatcher(預設值)  //內部請求轉發,和過去servlet 中 forwart 一樣

2) redirect  //重定向 註意,重定向,是不可能定向到 WEB-INF 下的

3) redirectAction //重定向到某個Action上 ,最典型的應用,比如添加用戶以後,重定向到一個用戶查詢的action上

4) plainText //以文本的形顯示jsp或html

5) chain //用來處理Action鏈,一個action處理完後,轉發到下一個action

6) stream //向瀏覽器發送InputStream 對象,通常用來下載,還可以返回ajax數據

7) freemarker //處理 freemarker 模板

8) httpheader //控制特殊HTTP行為的結果類型 根據值棧返回自定義的HttpHeader,status指定響應狀態

9) velocity //處理Velocity模板  //Velocity是一個基於java的模板引擎

10) xslt // 處理XML/XLST模板

11)postback

//例子 使用 redirect方式在 url 後面傳值的例子
<package name="packageThree" namespace=""  extends="struts-default">
   <action name="usrEdit" class="cat.action.UserEditAction" method="execute" >
   <result name="success" type="redirect" >/test_redirect.jsp?userName=${userName}</result> 註意,這裡的 type 為redirect
   </action>
</package>
                    
//並且,在 UserEditAction 中:
public class UserEditAction {
   private String userName; //要生成get set 方法
   public String execute(){
          try {  
               userName=URLEncoder.encode("這是很久很久沒來的高睿","UTF-8");  //為了處理亂碼,這裡要URLEncoder
              } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
                                    }
               return "success";
}
//在test_redirect.jsp中,可以用 ${userName} 取出來值,但如果有中文將出現亂碼,可以如下處理
<% 
    String userName= request.getParameter("userName");
    userName=new String(userName.getBytes("iso8859-1"),"UTF-8");
    // userName=URLDecoder.decode(userName,"UTF-8");  實測不加也可以
        out.println(userName);
%
//例子 重定向到別的action 
<action name="redirectOtherActionTest">
<result type="redirectAction">otherActionName</result>    
</action>
                    
<action name="otherActionName">
<result>success.jsp</result>
</action>
//例子 重定向到別的包中的 action 
<action name="redirectOtherPackageActionTest">
<result type="redirectAction">
<param name="actionName">xxx</param>
<param name="namespace">/two</param>
</result>    
</action>

三、配置全局視圖

<global-results>
  <result name="g_error">/error.jsp</result> //這是包範圍內的全局視圖
</global-results>
         
<action name="userAdd" class="cat.action.UserAction" method="add" >
//這裡沒有配置 result 
</action>
         
public class UserAction extends ActionSupport {
       public String add(){
       return "g_error";  //全局視圖
       }
}

如果視圖要做成全局的怎麼辦 (跨包)

1) 聲明一個包 並繼承 struts-default ,把它交給別人繼承。在這個包里,聲明全局視圖

2) 用別的包來繼承它

//這個包是專門用來給別的包繼承的
     <package name="base" extends="struts-default" >
           <global-results>
               <result name="g_success">/success.jsp</result>
               <result name="g_eror">/error.jsp</result>
           </global-results>
    </package>
   
   <package name="packageUser" namespace="" extends="base">
          <action name="userAdd" class="cat.action.UserAction" method="add" > 
             //如果這裡也有一個 <result name="g_eror">/error.jsp</result> ,則會覆蓋全局視圖
          </action>
   </package>
        
        public class UserAction extends ActionSupport {
            public String add(){
                return "g_success";  //全局視圖
                }
      }

result 用來配置邏輯視圖與物理視圖之間的映射關係,視圖資源不一定是JSP頁面,目前的視圖資源有:

Velocity

FreeMarker

JFreeChart

報表 JasperReports

XSLT

四、為 Action 的屬性註入值

public class NumZhuRuAction {
            private String compName;  //公司名稱
            private String money;  //公司現金
            
              ...  get set 方法
            
                public String execute(){
                    return "success";
                }
        }

     <package name="packageUser" namespace="" extends="base">
        <action name="numZhuRuAction" class="cat.action.NumZhuRuAction" method="execute">
            <param name="compName">海康公司</param>
            <param name="money">100元</param>
            <result name="success">/zhuru_ok.jsp</result>
        </action>
   </package>

五、struts2 中的常用常量

指定 struts2 請求的尾碼,在前面,訪問請求地址都可以加上.action 尾碼。寫在web.xml中的過濾器 org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter 是Struts 2框架的核心控制器,它負責攔截由  <url-pattern>杠*</url-pattern>指定的所有用戶請求,當用戶請求到達時,該Filter會過濾用戶請求。預設情況下,如果用戶請求的路徑以.action結尾,該請求將被轉入Struts2框架處理,否則該請求將略過Struts2 框架的處理。

可以通過配置常量,來指定這個請求的尾碼  struts.action.extension

<constant name="struts.action.extension" value="do,action,cat"></constant>  可以指定多個

常量可以在struts.xml或struts.properties中配置,建議在struts.xml中配置,兩種配置方式如下:

--struts.xml

<struts>
   <constant name="struts.action.extension" value="do"/>
</struts>

 --struts.properties 文件中

struts.action.extension=do

通常,struts2按如下搜索順序載入struts2常量:

struts-default.xml //struts-core-2.3.25.2.jar 中

struts-plugin.xml //struts2-convention-plugin-2.1.6.jar ?

struts.xml

struts.properties //它在哪兒? 在src下手工建一個就行了 裡面放上 struts.action.extension=cat,dog 則會覆蓋 struts.xml 中的配置

web.xml

如果在多個文件中配置了同一個常量,則後一個文件中配置的常量值會覆蓋前面文件中配置的常量值

Struts2常用的常量  svn  極限開發,可以在幫助文檔中的 home.html 中的指南下找到。struts2 的常量,也叫 struts2 的屬性,主要用來控制整個struts2 的運行特性。

--<constant name="struts.i18n.encoding" value="UTF-8" />//指定預設編碼集 作用於HttpServletRequest的SetCharaterEncoding方法和 freemarker,velocity(模板技術) 輸出

--<constant name="struts.action.extension" value="do" /> //指定請求尾碼 ,多個用逗號分開

--<constant name="struts.serve.static.browserCache" value="false" /> //指定瀏覽器是否緩存靜態內容,預設值為true(生產環境下使用),開發階段最好關閉

jsp——servlet——class 好:提高執行效率0.05s 0.7s  不好:不能及時的反應程式上的變化

--<constant name="struts.Configuration.xml.reload" value="true" /> //指定struts配置文件修改後,系統是否自動重新載入該文件,預設為false(生產環境下用),開發除階段最好打開

--<constant name="struts.devMode" value="true" /> //開發模式下使用,這樣可以列印出更詳細的錯誤信息

--<constant name="struts.ui.theme" value="simple" /> //指定預設的視圖主題(Struts2  中有一些標簽使用了視圖主題 後面會有介紹)

--<constant name="struts.objectFacvtory" value="spring" /> //指定創建Action 對象明的工廠類(本例:與 spring集成時,指定由sping負責Action的創建)

--<constant name="struts.enable.DynamicMethodInvocation" value="false" /> //指定Struts2 是否支持動態方法調用,預設值是 false

--<constant name="struts.mutipart.maxSzie" value="10701096" /> //設定上傳文件的大小(不是指一個,是指一組)

--<constant name="struts.multipart.saveDir" value="" />  設置上傳言語件的臨時目錄

六、Struts2的處理流程

用戶請求  ---->

--->StrutsPreparedAndExecuteFilter   //配置在web.xml中的過濾器

--->Interceptor  //struts2內置的一些攔截器或用戶自定義的攔截器

--->Action //用戶定義的業務處理類,

--->Result //視圖

--->jsp / html /其他

StrutsPrepareAndExceuteFilter 是Struts 框架的核心控制器, 它負責攔截由<url-pattern>杠*</url-pattern> 指定的用戶請求   

當用戶請求到達時,該filter 會過濾用戶請求,預設情況下,如果用戶請求的路徑不帶尾碼, 或以.action結尾,則這時請求被轉入到Struts2 框架進行處理,否則Sttuts2將略過該請求。

當請求進入Struts2框架處理時會先經過一系列的攔截器, 然後再到Action與Struts1不同,Struts 2 對用戶的每一次請示都會創建一個Action,所以Struts2中的Action是線程安全的管理方式,是一個常見的面試題(線程安全)Struts1 創建Action 中,會放到緩存里去(單例)。

附:可以在action的構造函數中,輸出內容,觀察到每次訪問,都會引起構造函數的調用。

//為應用指定多個struts 配置文件
                
//在主文件中  <include file="good_conf.xml" />
                 
//新建一個 配置文件,名稱為 good_conf.xml
<?xml version="1.0" encoding="UTF-8" ?>
    <!DOCTYPE struts PUBLIC
    "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
    "http://struts.apache.org/dtds/struts-2.3.dtd">
<struts>
 <package name="package_xxx" extends="base">
  <action name="hellowGoods" >
   <result name="success">/goods_add.jsp</result>
  </action>
 </package>
</struts>

七、動態方法調用和使用通配符定義Action

//動態方法調
<constant name="struts.enable.DynamicMethodInvocation" value="true" />
   <action name="userAction" class="cat.action.UserAction" >  
       <result name="add_success">/add_success.jsp</result>
       <result name="del_success">/del_success.jsp</result>
       <result name="update_success">/update_success.jsp</result>
   </action>

訪問的時候: 在! 後面傳要被調用的方法名

http://localhost:8080/Struts2-02/userAction!delUser(不推薦 使用)

//使用通配符的方式
<action name="userActionNew_*" class="cat.action.UserAction" method="{1}">
   <result name="xxx_success">/{1}_success.jsp</result>  // 這裡可以寫成 {1}.jsp
</action>

http://localhost:8080/Struts2-02/userActionNew_updateUser
http://localhost:8080/Struts2-02/userActionNew_addUser
http://localhost:8080/Struts2-02/userActionNew_delUser

附: 可以在視圖中使用 ognl 表達式,以達到動態視圖的效果,如下

<result name="success">/WEB-INF/page/${某屬性}.jsp</result>

八、請求參數接收

1.採用基本類型接收請求參數(get/post)

在Action類中定義與請求參數同名的屬性,struts2便能自動接收請求參數並賦予給同名屬性。

請求路徑: http://localhost:8080/view.action?id=78

Public class HellowAction{
   private integer id; 生成get 和set 方法
//struts用反射技術處理,調用與請求參數同名的屬性的seeter方法來獲取請求參數值
}

2.採用複合類型接收請求參數

請求路徑 同上 http://localhost:8080/view.action?id=78

Public class ProductAction{
    private Product prod;
    public void setProd(Product prod){this.prod=prod}
    public Product getProd(){ return this.prod}
} 

struts2首先通過反射技術調用Product 的預設構造方法,創建出product對象,然後再通過反射技術調用product中與請示參數同名的屬性的setter方法來獲取請求參數值。

代碼實例:

1 建立Action類

public class ParamTestAction {
       private String userName; //為之生成get 和set方法
       private String password;
                
       public String execute() {    
       //if (this.userName.equals("admin") && this.password.equals("123")) { 
       if ("admin".equals(this.userName) && "123".equals(this.password)) {        //註意,這樣的技可以避免空指針異常
          return "success";
          } else {
            return "err";
          }
        }
}

2 在structs.xml中配置

<package name="packageSix" namespace="" extends="struts-default"> //註意,放在了預設的命名空間下,訪問就不用寫上/test了
  <action name="ParamTestAction" class="cat.action.ParamTestAction"    method="execute">
          <result name="success">/ParamSucc.jsp</result>
          <result name="err">/ParamErr.jsp</result>
  </action>
</package>

=====簡單類型

3 在ParamSucc.jsp中

<body>
  登錄成功
  ${userName }
  ${password }  
</body>

4 訪問,以get方式傳參

http://localhost:8080/Struts/ParamTestAction?userName=admin&password=1234

5 訪問,以 form表單的post方式傳參  在 Login.Jsp 中以form表單形式提交,結果同上

<form action="ParamTestAction" method="post">
      <input type="text" name="userName" /> 
      <input type="password"    name="password" />
      <input type="submit" value="提交" >
</form>

===採用複合類型

1 建立Action類 先創建包bean ,再裡面然添 UserInfo類,然後再創建Action

public class BeanParamAction {
      private UserInfo userInfo; //生成get和set方法
      public String execute() {
         if ("admin".equals(userInfo.getUserName())    && ("123".equals(userInfo.getPassword()))) {    
         return "success";
         } else {
         return "err";
         }
      }
}

2 在structs.xml中配置 可以發現,這裡的配置基本與上例相同

<action name="BeanParamAction" class="cat.action.BeanParamAction"    method="execute">
   <result name="success">/BeanParamSucc.jsp</result>
   <result name="err">/BeanParamErr.jsp</result>
</action>

3 在BeanParamSucc.jsp 中

<body>
  登錄成功  採用複合類型接收參數
  ${userInfo.userName}
  ${userInfo.password}
</body>

4 訪問,創建 BeanLogin.Jsp

<form action="BeanParamAction" method="post">
   <input type="text" name="userInfo.userName" />  //註意參數的傳法
   <input type="password"    name="userInfo.password" /> //註意參數的傳法
   <input type="submit" value="提交" >
</form>

5 訪問 http://localhost:8080/Struts/BeanLogin.jsp ,添加入數據進行驗證

需要註意的是:

1)struts2 是通過反射,給userInfo註入的,所以 UserInfo 類必須提供預設的構造函數

2)UserInfo中可以有多餘欄位   

九、訪問或添加request/session/application屬性

在struts2中 ,沒有繼承自HttpServlet , 方法,也沒有傳過來 request ,response 等參數。但假如我們想在作用域中傳值,怎麼處理?

struts2 有兩種處理方式

1.偽訪問  ActionContext

public String execute(){    
       ActionContext ctx=ActionContext.getContext();  //是struts2 提供的
       ctx.getApplication().put("app_key", "全局範圍內的值"); //相當於往 ServletContext 中放入
       ctx.getSession().put("session_key", "這是session內的值") ; //相當於往 session中放入
       ctx.put("request_key", "這是request中的值");
                
       //ctx.getSession() 等操作,得到的是 map集合
       return "success";
}
//success.jsp
<body>
  application : ${applicationScope.app_key}
  session:  ${sessionScope.session_key }
   request:  ${requestScope.request_key }
</body>

2.真訪問  ServletActionContext 方式一

public String testScope(){
       HttpServletRequest request =  ServletActionContext.getRequest();
       ServletContext application=ServletActionContext.getServletContext();
       HttpSession session=request.getSession();
                        
       request.setAttribute("requestKey", "用request對象設置的request的值");
       session.setAttribute("sessionKey", "用session對象設置的session的值");
       application.setAttribute("appKey", "用application 對象設置的 application的值");

       return "success";
       }
                
      application : ${applicationScope.appKey}  <br>
      session:  ${sessionScope.sessionKey } <br>
      request:  ${requestScope.requestKey } <br>

取得 作用域對象方式 二

(實現介面,由struts2 運行的時候註入)

public class BaseAction  extends ActionSupport implements ServletRequestAware,ServletContextAware,ServletResponseAware {
                        public HttpServletRequest request;
                        public ServletContext  servletContext;
                        public HttpServletResponse response;
                        public HttpSession session;
                        
                        public String execute(){
                            request.setAttribute("hahaha", "哈哈哈,這都是啥子");
                            return "success";     
                        }
                    
                        @Override
                        public void setServletResponse(HttpServletResponse response) {
                            this.response=response; 
                            
                        }
                    
                        @Override
                        public void setServletContext(ServletContext context) {
                            this.servletContext=context;
                        }
                    
                        @Override
                        public void setServletRequest(HttpServletRequest request) {
                            this.request=request;
                            this.session=request.getSession();
                        }    
                    }

說明:一般情況下,這個BaseAction是用來給別的Action進行繼承的。


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

-Advertisement-
Play Games
更多相關文章
  • 數據模型是開發軟體的最重要的部分,因為它們對應用程式有著深遠的影響:不僅是軟體的編寫方式,而且也影響我們如何解決的問題的方式。第二篇讀書筆記,我們聊一聊數據模型的設計。 1.數據模型的分層 作為一個開發者來說,在一個複雜的應用程式中,是存在很多 分層模型 的,但基本思想還是一樣的:每一層都提供了一個 ...
  • 基於cookie做用戶驗證時, 敏感信息不適合放在cookie中. a. Session原理 cookie是保存在用戶瀏覽器端的鍵值對 session是保存在伺服器端的鍵值對 首先生成一個隨機字元串, 並只將隨機字元串通過cookie保存在瀏覽器端 在隨機字元串對應的字典中, 設置相應的字典 1 c ...
  • #函數定義def f(): print('love Q')f()##參數#形參和實參def add(a,b): print(a+b)add(7,5)def print_info(name,age): print('name:%s' % name) print('age:%d' % age)print ...
  • 緩衝區,位元組將從中取出 作為一種數據源:將其與FilterInputStream對象相連以提供有用介面 字元串。底層實現實際使用的是StringBuffer 作為一種數據源:將其與FilterInputStream對象相連以提供有用介面 字元串,表示文件名、文件或FileDescriptor對象 作 ...
  • 1.1 文件處理 1.1.1 打開文件過程 在Python中,打開文件,得到文件句柄並賦值給一個變數,預設打開模式就為r f=open(r'a.txt','w',encoding='utf-8') print(f.writable()) f.write('1111\n') f.write('2222 ...
  • 1、操作日誌 logging.basicConfig:日誌的統一處理器,對日誌的輸出格式和方式做配置日誌級別等級CRITICAL > ERROR > WARNING > INFO > EDBUG level設定級別以及以上級別的才會列印,這裡註意大小寫! 列印日誌信息在控制台或輸出在一個文件示例: ...
  • java學習筆記之面向對象static,final關鍵字 一.static關鍵字 1.概述: static靜態的,被static修飾的成員屬於類,不屬於單個對象,被所有對象所共用,存在靜態區中,靜態的成員優先於對象載入到記憶體中。 2.statc修飾成員的使用方式:(被static修飾的成員變數有預設 ...
  • 剛入行沒多久就聽過‘負載均衡’的大名,到現在因為工作接觸的少,所以沒什麼太多的認識。但自己又對其非常的好奇,所以前兩天通過查資料,在自己的筆記本上就搭建了一個超簡單的案例(工作中沒有時間,晚上到家了條件又不夠,只能用自己的筆記本將就一下了,重在理解思想。。) 通俗點將,負載均衡就是因為訪問流量太大, ...
一周排行
    -Advertisement-
    Play Games
  • 前言 本文介紹一款使用 C# 與 WPF 開發的音頻播放器,其界面簡潔大方,操作體驗流暢。該播放器支持多種音頻格式(如 MP4、WMA、OGG、FLAC 等),並具備標記、實時歌詞顯示等功能。 另外,還支持換膚及多語言(中英文)切換。核心音頻處理採用 FFmpeg 組件,獲得了廣泛認可,目前 Git ...
  • OAuth2.0授權驗證-gitee授權碼模式 本文主要介紹如何筆者自己是如何使用gitee提供的OAuth2.0協議完成授權驗證並登錄到自己的系統,完整模式如圖 1、創建應用 打開gitee個人中心->第三方應用->創建應用 創建應用後在我的應用界面,查看已創建應用的Client ID和Clien ...
  • 解決了這個問題:《winForm下,fastReport.net 從.net framework 升級到.net5遇到的錯誤“Operation is not supported on this platform.”》 本文內容轉載自:https://www.fcnsoft.com/Home/Sho ...
  • 國內文章 WPF 從裸 Win 32 的 WM_Pointer 消息獲取觸摸點繪製筆跡 https://www.cnblogs.com/lindexi/p/18390983 本文將告訴大家如何在 WPF 裡面,接收裸 Win 32 的 WM_Pointer 消息,從消息裡面獲取觸摸點信息,使用觸摸點 ...
  • 前言 給大家推薦一個專為新零售快消行業打造了一套高效的進銷存管理系統。 系統不僅具備強大的庫存管理功能,還集成了高性能的輕量級 POS 解決方案,確保頁面載入速度極快,提供良好的用戶體驗。 項目介紹 Dorisoy.POS 是一款基於 .NET 7 和 Angular 4 開發的新零售快消進銷存管理 ...
  • ABP CLI常用的代碼分享 一、確保環境配置正確 安裝.NET CLI: ABP CLI是基於.NET Core或.NET 5/6/7等更高版本構建的,因此首先需要在你的開發環境中安裝.NET CLI。這可以通過訪問Microsoft官網下載並安裝相應版本的.NET SDK來實現。 安裝ABP ...
  • 問題 問題是這樣的:第三方的webapi,需要先調用登陸介面獲取Cookie,訪問其它介面時攜帶Cookie信息。 但使用HttpClient類調用登陸介面,返回的Headers中沒有找到Cookie信息。 分析 首先,使用Postman測試該登陸介面,正常返回Cookie信息,說明是HttpCli ...
  • 國內文章 關於.NET在中國為什麼工資低的分析 https://www.cnblogs.com/thinkingmore/p/18406244 .NET在中國開發者的薪資偏低,主要因市場需求、技術棧選擇和企業文化等因素所致。歷史上,.NET曾因微軟的閉源策略發展受限,儘管後來推出了跨平臺的.NET ...
  • 在WPF開發應用中,動畫不僅可以引起用戶的註意與興趣,而且還使軟體更加便於使用。前面幾篇文章講解了畫筆(Brush),形狀(Shape),幾何圖形(Geometry),變換(Transform)等相關內容,今天繼續講解動畫相關內容和知識點,僅供學習分享使用,如有不足之處,還請指正。 ...
  • 什麼是委托? 委托可以說是把一個方法代入另一個方法執行,相當於指向函數的指針;事件就相當於保存委托的數組; 1.實例化委托的方式: 方式1:通過new創建實例: public delegate void ShowDelegate(); 或者 public delegate string ShowDe ...