Struts2 學習記錄-1--Struts2中的配置文件

主要涉及3個配置文件:web.xml、struts.xml、struts.properties
html

1. web.xml

任何參與了web應用程序的請求與響應動做,都必須藉助web.xml文件來安裝這個框架。
struts2的web.xml配置能夠參考 官方文檔.
首先須要配置過濾器:前端

<filter>
    <filter-name>struts2</filter-name>
    <!-- struts 2.5及以上版本 -->
    <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>struts2</filter-name>
    <!-- 攔截全部用戶請求 -->
    <url-pattern>/*</url-pattern>
</filter-mapping>

若是java

<url-pattern>*.action</url-pattern>
<url-pattern>*.do</url-pattern>

則只處理以.do.action結尾的請求
經過以上配置就可使用struts2了。但除此以外,還能夠在filter之中配置以下內容:web

<init-param>
      <!-- 自動加載的系列配置文件 -->
      <param-name>config</param-name>
      <param-value>struts-default.xml,struts-plugin.xml,/WEB-INF/struts.xml </param-value>
</init-param>
<init-param>
    <!-- 配置Struts2框架要掃描的包,多個包用逗號分開。 -->  
    <param-name>actionPackages</param-name>  
    <param-value>org.apache.struts2.showcase.person</param-value>  </init-param>  
    <!-- 配置Struts2框架的配置提供者類,多個類用逗號分開 -->  
<init-param>  
    <param-name>configProviders</param-name>  
    <param-value>com.MyConfigurationProvider</param-value>  
</init-param>

或者設置某些屬性:spring

<filter>
   <filter-name>struts</filter-name>
   <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
   <init-param>
       <param-name>struts.devMode</param-name>
       <param-value>true</param-value>
   </init-param>
</filter>

2. struts.xml

Struts2框架的核心配置文件,主要負責管理struts2框架中的action映射和result以及常量屬性(或由struts.properties配置)。參考:
官方 Configuration Elements
Struts2 配置文件struts.xml和web.xml詳解
默認狀況下,Struts2的配置文件名稱爲struts.xml,且該文件放在src根目錄下(即/WEB-INF/classes目錄下、src/main/resources)。若是修改了名稱或位置,則須要清晰的進行配置,方法便是上文中的filter中的config配置:apache

<init-param>  
    <param-name>config</param-name>  
    <param-value>struts-default.xml,struts-plugin.xml,struts/struts.xml</param-value> 
</init-param>

struts-default.xml,struts-plugin.xml也必須加上,或者在struts.xml文件中添加include標籤將兩個文件包括進去。
或者採用下述配置(?)json

<init-param>  
    <param-name>filterConfig</param-name>  
    <param-value>classpath:struts2/struts.xml</param-value>  
</init-param>

struts.xml 配置示例服務器

<?xml version="1.0" encoding="UTF-8" ?>  
<!DOCTYPE struts PUBLIC
        "-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
        "http://struts.apache.org/dtds/struts-2.5.dtd">    
<struts>  
    <!-- 基礎配置:常量屬性 -->
    <constant name="struts.enable.DynamicMethodInvocation" value="false" />  
    <!-- 開發模式,在web服務器出錯時會盡可能打印出來 -->
    <constant name="struts.devMode" value="true" />
    <!-- 配置文件修改後是否自動從新部署到服務器,開發階段可設置爲true,不然須要不時重啓服務器。-->
    <constant name="struts.configuration.xml.reload" value="true" />    
    <!-- struts2是處理以.do和.action爲後綴的請求url的(默認是.action)-->
    <constant name="struts.action.extension" value="do,action"/>
    <!-- 包含其餘的struts2配置,file屬性是相對/WEB-INF/classes的路徑  -->
    <include file="Home.xml"/>
    <!-- 全局異常配置  -->
    <package name="main" namespace="/" extends="struts-default">
        <!--指定一個默認的Action,若是系統沒有找到指定的Action,就會指定來調用這個默認的Action -->
        <default-action-ref name="index" />  
        <global-results>
            <result name="error">/error.jsp</result>  
        </global-results>
        <global-exception-mappings>
            <exception-mapping exception="java.lang.Exception" result="error"/>
        </global-exception-mappings>  
    </package>
  
  <package name="employee" extends="struts-default" namespace="/employee">
  <!-- 設置整個包範圍內全部Action所要應用的默認攔截器信息。通常不用設置而使用框架默認的便可 -->
    <default-interceptor-ref name="crudStack"/>
      <action name="delete" method="delete"
        class="org.apache.struts2.showcase.action.EmployeeAction" >
        <result name="error">/empmanager/editEmployee.jsp</result>
        <result type="redirect">edit-${currentEmployee.empId}.action</result>
        <!-- 攔截器信息,通常也不設置 -->
        <interceptor-ref name="basicStack"/>
      </action>
  </package>
  <!-- 多繼承,json配置 -->
  <package name="employee" extends="struts-default, json-default" namespace="/employee"> 
    <action name="list" method="list" class="org.apache.struts2.showcase.action.EmployeeAction" >
        <result>/empmanager/listEmployees.jsp</result>
        <result type="json">
            <param name="root">employees</param>
        </result>
    </action>
  </package>
</struts>

特別地,對於返回json的配置(基於 struts2-json-plugin)(參考: stackoverflow例子json-pluginStruts2返回JSON對象的方法總結 ):session

public class Struts2Action extends ActionSupport {
    private String jsonString;
    public String execute() {
        Gson gson = new Gson();
        jsonString = gson.toJson(audioTaggingService.findTagsByName(q));
        return "success";
    }
    //沒有getter的屬性將不會出如今json中
    public String getJsonString() {
        return jsonString;
    }
    public void setJsonString(String jsonString) {
        this.jsonString = jsonString;
    }
}

配置xml。注意extends中必須出現json-default,能夠沒有struts-default(由於json-default繼承自它)。
root指明瞭要序列化爲json的對象。若是action類中只有一個屬性,能夠不設置root。app

<package name="json" extends="struts-default,json-default" >
  <action name="someJsonAction" class="com.something.Struts2Action">
     <result type="json">
        <param name="noCache">true</param>
        <param name="excludeNullProperties">true</param>
        <param name="root">jsonString</param>
     </result>
  </action>
</package>

附:返回json還有一種簡便的方法,即將生成好的json字符串寫入到response中去,返回給前端使用。對實體對象轉JSON有許多組件可用,如FastJSON,GSON等。

public static void writeJson(String json)
    {
        //每次調用都進行初始化
        HttpServletResponse response = ServletActionContext.getResponse();
        response.setContentType("application/json;charset=utf-8");
        try
        {
            response.getWriter().write(json);
            response.getWriter().flush();
            response.getWriter().close();
        }
        catch (IOException e)
        {    e.printStackTrace();    }
    }

3. struts.properties文件

本文件主要負責配置struts2中大量的屬性(struts.xml中的<constant name="" value="">)。
部分屬性:
struts.locale:默認 en_US,指定 locate 和 encoding schema
struts.il8n.encoding:設置默認編碼集,默認值爲 utf-8
struts.objectFactory:默認值 spring
struts.objectFactory.spring.autoWire:指定spring框架的自動裝配模式,默認值 name(默認根據name屬性裝配)。可選值爲:name/ type/auto/construtor
struts.multipart.parser 處理multipart/form-data的MIME類型請求框架,默認 jakarta,即 common-fileupload
struts.multipart.saveDir 保存上傳文件的臨時路徑
struts.multipart.maxSize容許上傳的最大字節數
struts.action.extension默認爲 action,爲了支持.do,可設置爲 "do,action"

4.註解式開發

依賴struts2-convention-plugin。註解與基於xml配置基本是一致的。
基本無需進行配置,或者只須要極其少許的配置(針對struts.xml)。
進行全局配置:配置一個名爲base,繼承自json-default的package,便於後續使用。

<package name="base" extends="json-default,struts-default">  
        <!-- 這裏能夠設置一些全局的返回值映射關係等 -->  
</package>

而後,在Action類代碼中使用註解:

//若struts.xml中沒有配置名爲 base 的包,則 「base」 須要寫成 "json-default"。若是不是json,則爲"struts-default"
@ParentPackage("base") 
@Namespace("/watson")  //命名空間
@Results({  
    @Result(name = "json",type="json", params={"root","msg"})  
})  //reuslt配置
public class JsonAction {  
    private Map<String, Object> msg;
    //msg必須有getter方法才能出如今JSON中
    public Map<String, Object> getMsg() {  
        return msg;  
    }
    @Action(value="json")  
    public String json() { 
        msg = new HashMap<String, Object>();          
        msg.put("user", user);  
        return "json";  
    }

基於方法的@Result註解

@Action(    value="login",  //表示action的請求名稱
            results={  //表示結果跳轉
            @Result(name="success",location="/success.jsp",type="redirect"), 
            @Result(name="login",location="/login.jsp",type="redirect"), 
            @Result(name="error",location="/error.jsp",type="redirect")  
            },
            //表示攔截器引用
            interceptorRefs={@InterceptorRef("defaultStack"), @InterceptorRef("timer")},
           //異常映射聲明 
           exceptionMappings={@ExceptionMapping(exception="java.lang.Exception",result="error")}
    ) 
    public String login() throws Exception {  
        int i = 1/0 ; 
        if ("admin".equals(user.getUsercode()) && "admin".equals(user.getUserpswd())) {
            Map session = ActionContext.getContext().getSession();  
            session.put("session_user", user);
            return "success";  
        } else {  
            return "login";  
        }  
    }

5.與Spring框架集成的配置

須要struts2-spring-plugin,參考: Struts2+Spring集成合並
<constant name="struts.objectFactory" value="spring" />

  1. 方案一,Struts2負責流程,Spring負責對象的建立;Action由Struts2框架負責建立;Service由Spring框架負責建立
    這種狀況下,只須要按要求分別配置好Struts2和Spring便可。或者根據須要修改struts.objectFactory.spring.autoWire等配置。
    這個時候使用註解開發,Action類無需使用Spring的@Controller註解,但需加上@Scope("prototype")設爲多例
  2. 方案二,Struts2負責流程,Spring負責對象的建立,Action和Service都由Spring框架負責建立。這是經常使用的集成合並方案
    主要看一下兩個框架核心配置文件的和第一種方案的寫法區別:
  • struts2.xml的寫法:
<struts>  
     <!-- 注意class的值,這裏是Spring中bean的id,是爲了在Spring中根據此值進行查找 --> 
     <!-- 寫完整包名錶明Action仍是由Struts管理,action都是多例! -->
    <package name="example" namespace="/user" extends="struts-default">  
        <action name="login" class="loginAction" method="login">  
            <result name="success" type="redirect">/success.jsp</result>  
            <result name="login" type="redirect">/login.jsp</result>  
        </action>
    </package>
</struts>  
</span>
  • spring配置文件 applicatinContext.xml的寫法:
<!--這裏的id對應上邊的class,這裏的class纔是真正的路徑,採用了Spring的根據name自動裝配的功能,固然也能夠咱們手動指定,
   這裏須要注意的是,action須要多例建立,而Spring默認爲單例建立的,因此須要指定scope="prototype"-->  
    <bean id="loginAction" class="com.ljh.action.LoginAction" autowire="byName" scope="prototype"></bean> 
    <bean id="userService" class="com.ljh.service.UserService" ></bean>  
</span>

若是都採用註解的方式,Action使用 @Controller註解
注:
struts2的單例多例問題

  1. Struts2會對每個請求,產生一個Action的實例來處理. ---多例
  2. Spring的Ioc容器管理的bean默認是單實例的. ---單例
相關文章
相關標籤/搜索