Struts2學習記錄1

1,Struts2.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>
<!-- constant:配置struts2的基本屬性,在struts2-core核心包的/org/apache/struts2/default.properties中找 -->
<!-- 亂碼解決 -->
<constant name="struts.i18n.encoding" value="UTF-8" />


<!-- 自定義擴展名,一下可以沒有,可以爲.do可以爲.action -->
<constant name="struts.action.extension" value="action,,do" />


<!-- 當配置文件更改後自動裝載 。同時要開啓開發者模式 -->
<!--true:是開發者模式。外部不可訪問;false:外部可以訪問 ,出錯時候友好的提示信息;實際發佈的時候選擇false,爲了安全 -->
<constant name="struts.devMode" value="true" />
<constant name="struts.configuration.xml.reload" value="true" />


<!-- 啓動動態方法action配置 -->
<constant name="struts.enable.DynamicMethodInvocation" value="false" />


<!-- 把struts的action對象交給spring容器管理 -->
<constant name="struts.objectFactory " value="spring" />


<!-- include這個是團隊開發模式使用的,多個xml文件的時候就使用 ,這樣每個人只要維護自己的配置文件即可 -->
<!-- <include file="直接指定擴展xml文件的路徑即可"/> -->




<!-- struts是基於包管理的 name隨便寫,namespace是指不同命名空間, extends必須是struts-default,直接或者間接繼承,簡介繼承就使用json-default 

從Struts-core核心包中可以看到json-default 繼承了struts-default,擴展了其中的過濾器配置
可以配置多個包,用於團隊開發 -->
<!-- 配置文件加載順序:struts-default.xml->struts-plugin.xml->struts.xml -->
<package name="default" namespace="/" extends="json-default">
<!-- 配置默認執行的action,當所請求的action不存在的時候默認執行的action-->
<default-action-ref name="default"/>

<!-- 配置默認執行的class ,當一個action沒有配置class的時候就是這個去處理,可以不指定,也有框架自己默認的-->
<default-class-ref class="com.yc.ssm.action.UserAction"/>

<!-- 配置全局結果集 -->
<global-results>
<result name="fail">/login.jsp</result>
</global-results>
<!-- 請求這個名字name是url請求名,不需要加後綴(.action)
CLASS是請求對用的action類的全類名
method配置處理請求的方法,默認爲execute方法
方法返回值類型必須是String,必須是public的
在action的配置中不配置class將由默認的action(ActionSupport類)來執行
-->
<action name="User_*" class="com.yc.ssm.action.UserAction" method="{1}">
<!-- name:匹配請求方法返回值,默認是success
type:結果處理類型
默認是dispatcher轉發;
      chain:是指action鏈,執行actionA後直接指定actionB,地址欄是第一個action
                     dispatcher:轉發,特點和Servlet一致,如果Request中有數據要顯示則用
            redirect:重定向,如果重定向到jsp頁面,可以直接重定向
            但是如果重定向到另一個action,需要注意是否配置action的後綴名
            redirectAction:重定向到另一個action,不用加action的後綴名,自動幫你加上了
            stream:以流的形式顯示-文件下載
            還有一些就不具體講了
-->
<result name="success" type="dispatcher">/page/index.jsp</result>
<result type="json" name="json">
<param name="contentType">
text/html
</param>
</result>
</action>

<action name="default">
<result>/404.jsp</result>
</action>
</package>
</struts>


2,web.xml中的配置

<!-- struts框架的核心(過濾器)其它過濾器都配置在它之前 -->
<filter>
<filter-name>struts2</filter-name>
<filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
<!-- struts core如果是2.5 的版本則要刪除ng -->
</filter>
<filter-mapping>
<filter-name>struts2</filter-name>
<url-pattern>/*</url-pattern>
<dispatcher>REQUEST</dispatcher>
<dispatcher>FORWARD</dispatcher>
</filter-mapping>

注:這個filter一定要放在其它的過濾器之後,不然就不會執行其它的過濾器了

3,Action類的官方推薦寫法

Struts2的Action是線程安全的,每次請求都將會創建一個新的action,

/**
 * ActionSupport:官方推薦繼承這個類(驗證) :其中的一些默認的配置

*ModelDriven:模型驅動,自動注入 

*UserBean:指需要注入的對象
 * @author shuang
 *
 */
@Controller
public class UserAction extends ActionSupport implements ModelDriven<UserBean>{

private UserBean userBean = new UserBean();

public UserBean getModel() {
return userBean;
}


使用以上寫法,在action類中就可以任意使用我們的實體類userBean對象,但是提交的數據的name一定要和實體類的屬性保持一致

4,最好的使用解耦和的方式獲取jsp內置對象

其一:ActionContext.getContext().getSession()獲取session對象

/**
 * ActionContext.getContext().getSession()一般使用這種解耦合的方式獲取內置對象
 * ActionContext是一個map結構的容器,是action的上下文,
 * 存放action執行過程中的數據信息,比如session的,Application的等
 * 每次請求的時候創建一個新的ActionContext
 * 而ActionContext採用了ThreadLocal的方式來存放ActionContext
 * 所以ActionContext是線程安全的
 * ActionContext是基於請求創建的,所以在非請求的線程中是不能訪問的,獲取也是爲空的
 * @return
 */

ActionContext:Struts2的ACtion不用依賴於web容器,本身只是一個普通的java類而已,但是在web開發中我們往往需要

獲得Request等對象,這時候就可以通過ActionContext,

ActionContext正如其名,是action執行的上下文,他內部有個map屬性,它存放了action執行時需要用到的對象,

在每次執行action之前都會創建新的ActionContext對象,所以ActionContext是線程安全的,新new的ActionContext是保存在

一個ThreadLocal變量中,即採用ThreadLocal模式,ThreadLocal變量爲每個線程提供獨立的變量值的副本,使得每個線程都可以獨立

的使用自己的副本,而不會和其他的線程發生衝突

通過ActionContext獲取的session,Request等並不是真的httpservletRequest等對象,而是將對象裏面的值重新包裝成了map對象

,這樣的封裝,我們及獲取了我們需要的值,同時避免了跟web容器直接打交道,實現了完全的解耦


ps:ThreadLocal:提供了線程局部變量,存放線程局部變量的一個容器,


以上測試可以知道ThreadLocal是線程安全的


ActionContext包含6大對象:

1,Application

2,request

3,session

4,attr(page->request->sesssion->application)括號中是取值順序

5,parameters

6,ValueStack(值棧)

ValueStack(值棧)

1、是ActionContext中的一個對象,值棧是棧結構(FILO:先進後出);

Struts2中值棧存放的數據是Action對象

注意:Action對象可以ValueStack,我們可以對象值棧進行操作,但是建議不是很熟就不要去操作了

5,包

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.yc</groupId>
<artifactId>spring-struts-mybatis</artifactId>
<packaging>war</packaging>
<version>0.0.1-SNAPSHOT</version>
<dependencies>
<!-- 單元測試 -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>


<!-- struts2框架 -->
<dependency>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-core</artifactId>
<version>2.3.28</version>
</dependency>
<!-- struts2使用json格式傳輸數據的時候使用的包 -->
<dependency>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-json-plugin</artifactId>
<version>2.3.16</version>
</dependency>


<!--struts2整合spring的插件包 -->
<dependency>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-spring-plugin</artifactId>
<version>2.5-BETA3</version>
</dependency>


<!-- spring框架的核心包 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>4.1.6.RELEASE</version>
<scope>runtime</scope>
</dependency>


<!-- spring框架支持數據訪問層的包 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>4.1.6.RELEASE</version>
<scope>runtime</scope>
</dependency>


<!-- spring框架支持表現層的包 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>4.1.6.RELEASE</version>
<scope>runtime</scope>
</dependency>
<!-- spring框架支持單元測試的包 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>4.1.6.RELEASE</version>
<scope>runtime</scope>
</dependency>


<!-- aspectj框架的包 -->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.8.9</version>
<scope>runtime</scope>
</dependency>


<!-- 日誌 -->
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-slf4j-impl</artifactId>
<version>2.5</version>
<scope>runtime</scope>
</dependency>


<!-- 日誌 -->
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.5</version>
<scope>runtime</scope>
</dependency>


<!--oracle 數據庫驅動包 -->
<dependency>
<groupId>com.oracle</groupId>
<artifactId>oracle-driver</artifactId>
<version>oracle11g</version>
<scope>runtime</scope>
</dependency>


<!-- 數據庫連接池的包 -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-dbcp2</artifactId>
<version>2.1.1</version>
<scope>runtime</scope>
</dependency>


<!-- mybatis框架核心包 -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.3.1</version>
<scope>runtime</scope>
</dependency>


<!-- mybatis與spring整合包 -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>1.3.0</version>
<scope>runtime</scope>
</dependency>


<!-- jstl包 -->
<dependency>
<groupId>jstl</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>


<!-- 郵件發送包 -->
<dependency>
<groupId>com.sun.mail</groupId>
<artifactId>javax.mail</artifactId>
<version>1.5.5</version>
</dependency>
<!-- gosn包 -->
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.6.2</version>
<scope>runtime</scope>
</dependency>
</dependencies>
<build>
<finalName>spring-struts-mybatis</finalName>
</build>
</project>


遇到的問題:取自網站

   在struts2中發現,調用action中的方法,方法會被執行兩次,後來發現調用的方法是get開頭的,把它改爲其他名稱開頭的後,就不會執行兩次了。繼續查找,發現調用的是返回json數據格式的action,如果是調用返回頁面的action就不會有這種問題。

     結合網上的搜索,總結了一下:

1.  json格式下, firefox中的yslow插件會發送第二個 HTTP GET 請求得到頁面的信息。.

2.  ajax模式下,調用的action方法不能爲get*方式命名,內中機理未知。

結論:action中方法最好不要以get開頭。

發佈了43 篇原創文章 · 獲贊 18 · 訪問量 7萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章