Struts2轉發類型

 

Action中result的各種轉發類型,

<action name="helloworld" class="cn.itcast.action.HelloWorldAction">
 <result name="success">/WEB-INF/page/hello.jsp</result>
</action>
result配置類似於struts1中的forward,但struts2中提供了多種結果類型,常用的類型有: dispatcher(默認值)、 redirect 、 redirectAction 、 plainText。

在result中還可以使用${屬性名}表達式訪問action中的屬性,表達式裏的屬性名對應action中的屬性。如下:
<result type="redirect">/view.jsp?id=${id}</result>

下面是redirectAction 結果類型的例子,如果重定向的action中同一個包下:
<result type="redirectAction">helloworld</result>
如果重定向的action在別的命名空間下:
<result type="redirectAction">
 <param name="actionName">helloworld</param>
 <param name="namespace">/test</param>
</result>
plaintext:顯示原始文件內容,例如:當我們需要原樣顯示jsp文件源代碼 的時候,我們可以使用此類型。
<result name="source" type="plainText ">
 <param name="location">/xxx.jsp</param>
 <param name="charSet">UTF-8</param><!-- 指定讀取文件的編碼 -->


2.多個Action共享一個視圖--全局result配置

當多個action中都使用到了相同視圖,這時我們應該把result定義爲全局視圖。struts1中提供了全局forward,struts2中也提供了相似功能:
<package ....>
 <global-results>
  <result name="message">/message.jsp</result>
 </global-results>
</package>

3.爲Action的屬性注入值

Struts2爲Action中的屬性提供了依賴注入功能,在struts2的配置文件中,我們可以很方便地爲Action中的屬性注入值。注意:屬性必須提供setter方法。
public class HelloWorldAction{
 private String savePath;

 public String getSavePath() {
  return savePath;
 }
 public void setSavePath(String savePath) {
  this.savePath = savePath;
 }
       ......
}

<package name="itcast" namespace="/test" extends="struts-default">
 <action name="helloworld" class="cn.itcast.action.HelloWorldAction" >
  <param name="savePath">/images</param>
  <result name="success">/WEB-INF/page/hello.jsp</result>
 </action>
</package>
上面通過<param>節點爲action的savePath屬性注入“/images”


4.指定需要Struts 2處理的請求後綴

前面我們都是默認使用.action後綴訪問Action。其實默認後綴是可以通過常量”struts.action.extension“進行修改的,例如:我們可以配置Struts 2只處理以.do爲後綴的請求路徑:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC
    "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
    "
http://struts.apache.org/dtds/struts-2.0.dtd">
<struts>
    <constant name="struts.action.extension" value="do"/>
</struts>

如果用戶需要指定多個請求後綴,則多個後綴之間以英文逗號(,)隔開。如:
 <constant name="struts.action.extension" value="do,go"/>

5.細說常量定義

常量可以在struts.xml或struts.properties中配置,建議在struts.xml中配置,兩種配置方式如下:
在struts.xml文件中配置常量
<struts>
    <constant name="struts.action.extension" value="do"/>
</struts>

在struts.properties中配置常量
struts.action.extension=do

因爲常量可以在下面多個配置文件中進行定義,所以我們需要了解struts2加載常量的搜索順序:
struts-default.xml
struts-plugin.xml
struts.xml
struts.properties
web.xml
如果在多個文件中配置了同一個常量,則後一個文件中配置的常量值會覆蓋前面文件中配置的常量值.

6.常用的常量介紹

<!-- 指定默認編碼集,作用於HttpServletRequest的setCharacterEncoding方法 和freemarker 、velocity的輸出 -->
    <constant name="struts.i18n.encoding" value="UTF-8"/>
    <!-- 該屬性指定需要Struts 2處理的請求後綴,該屬性的默認值是action,即所有匹配*.action的請求都由Struts2處理。
    如果用戶需要指定多個請求後綴,則多個後綴之間以英文逗號(,)隔開。 -->
    <constant name="struts.action.extension" value="do"/>
    <!-- 設置瀏覽器是否緩存靜態內容,默認值爲true(生產環境下使用),開發階段最好關閉 -->
    <constant name="struts.serve.static.browserCache" value="false"/>
    <!-- 當struts的配置文件修改後,系統是否自動重新加載該文件,默認值爲false(生產環境下使用),開發階段最好打開 -->
    <constant name="struts.configuration.xml.reload" value="true"/>
    <!-- 開發模式下使用,這樣可以打印出更詳細的錯誤信息 -->
    <constant name="struts.devMode" value="true" />
     <!-- 默認的視圖主題 -->
    <constant name="struts.ui.theme" value="simple" />
    <!– 與spring集成時,指定由spring負責action對象的創建 -->
    <constant name="struts.objectFactory" value="spring" />
 <!–該屬性設置Struts 2是否支持動態方法調用,該屬性的默認值是true。如果需要關閉動態方法調用,則可設置該屬性爲false。 -->
<constant name="struts.enable.DynamicMethodInvocation" value="false"/>
 <!--上傳文件的大小限制-->
<constant name="struts.multipart.maxSize" value=“10701096"/>

7.爲應用指定多個struts配置文件

在大部分應用裏,隨着應用規模的增加,系統中Action的數量也會大量增加,導致struts.xml配置文件變得非常臃腫。爲了避免struts.xml文件過於龐大、臃腫,提高struts.xml文件的可讀性,我們可以將一個struts.xml配置文件分解成多個配置文件,然後在struts.xml文件中包含其他配置文件。下面的struts.xml通過<include>元素指定多個配置文件:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC
    "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
    "
http://struts.apache.org/dtds/struts-2.0.dtd">
<struts>
 <include file="struts-user.xml"/>
 <include file="struts-order.xml"/>
</struts>

通過這種方式,我們就可以將Struts 2的Action按模塊添加在多個配置文件中。

8.動態方法調用
如果Action中存在多個方法時,我們可以使用!+方法名調用指定方法。如下:
public class HelloWorldAction{
 private String message;
 ....
 public String execute() throws Exception{
  this.message = "我的第一個struts2應用";
  return "success";
 }
 
 public String other() throws Exception{
  this.message = "第二個方法";
  return "success";
 }
}
假設訪問上面action的URL路徑爲: /struts/test/helloworld.action
要訪問action的other() 方法,我們可以這樣調用:
/struts/test/helloworld!other.action
如果不想使用動態方法調用,我們可以通過常量struts.enable.DynamicMethodInvocation關閉動態方法調用。
<constant name="struts.enable.DynamicMethodInvocation" value="false"/>


9. 使用通配符定義action

<package name="itcast" namespace="/test" extends="struts-default">
 <action name="helloworld_*" class="cn.itcast.action.HelloWorldAction" method="{1}">
  <result name="success">/WEB-INF/page/hello.jsp</result>
 </action>
</package>
public class HelloWorldAction{
 private String message;
 ....
 public String execute() throws Exception{
  this.message = "我的第一個struts2應用";
  return "success";
 }
 
 public String other() throws Exception{
  this.message = "第二個方法";
  return "success";
 }
}

要訪問other()方法,可以通過這樣的URL訪問:/test/helloworld_other.action

10. 接收請求參數

採用基本類型接收請求參數(get/post)
在Action類中定義與請求參數同名的屬性,struts2便能自動接收請求參數並賦予給同名屬性。
請求路徑:
http://localhost:8080/test/view.action?id=78
public class ProductAction {
      private Integer id;
      public void setId(Integer id) {//struts2通過反射技術調用與請求參數同名的屬性的setter方法來獲取請求參數值
             this.id = id;
      }
      public Integer getId() {return id;}
  }
採用複合類型接收請求參數
請求路徑:
http://localhost:8080/test/view.action?product.id=78
 public class ProductAction {
   private Product product;
   public void setProduct(Product product) {  this.product = product;  }
   public Product getProduct() {return product;}
}
Struts2首先通過反射技術調用Product的默認構造器創建product對象,然後再通過反射技術調用product中與請求參數同名的屬性的setter方法來獲取請求參數值。


11.關於struts2.1.6接收中文請求參數亂碼問題

struts2.1.6版本中存在一個Bug,即接收到的中文請求參數爲亂碼(以post方式提交),原因是struts2.1.6在獲取並使用了請求參數後才調用HttpServletRequest的setCharacterEncoding()方法進行編碼設置 ,導致應用使用的就是亂碼請求參數。這個bug在struts2.1.8中已經被解決,如果你使用的是struts2.1.6,要解決這個問題,你可以這樣做:新建一個Filter,把這個Filter放置在Struts2的Filter之前,然後在doFilter()方法裏添加以下代碼

public void doFilter(...){
 HttpServletRequest req = (HttpServletRequest) request;
 req.setCharacterEncoding("UTF-8");//應根據你使用的編碼替換UTF-8
 filterchain.doFilter(request, response);
}


12.自定義類型轉換器

java.util.Date類型的屬性可以接收格式爲2009-07-20的請求參數值。但如果我們需要接收格式爲20091221的請求參數,我們必須定義類型轉換器,否則struts2無法自動完成類型轉換。

import java.util.Date;
public class HelloWorldAction {
 private Date createtime;

 public Date getCreatetime() {
  return createtime;
 }

 public void setCreatetime(Date createtime) {
  this.createtime = createtime;
 }
}

13.自定義類型轉換器
public class DateConverter extends DefaultTypeConverter {
                @Override  public Object convertValue(Map context, Object value, Class toType) {
 SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMdd");
 try {
  if(toType == Date.class){//當字符串向Date類型轉換時
   String[] params = (String[]) value;// Request.getParameterValues()
   return dateFormat.parse(params[0]);
  }else if(toType == String.class){//當Date轉換成字符串時
   Date date = (Date) value;
   return dateFormat.format(date);
  }
 } catch (ParseException e) {}
 return null;
 }
}
將上面的類型轉換器註冊爲局部類型轉換器:
在Action類所在的包下放置ActionClassName-conversion.properties文件,ActionClassName是Action的類名,後面的-conversion.properties是固定寫法,對於本例而言,文件的名稱應爲HelloWorldAction-conversion.properties 。在properties文件中的內容爲:
屬性名稱=類型轉換器的全類名
對於本例而言, HelloWorldAction-conversion.properties文件中的內容爲:
createtime= cn.itcast.conversion.DateConverter

15.自定義全局類型轉換器
將上面的類型轉換器註冊爲全局類型轉換器:
在WEB-INF/classes下放置xwork-conversion.properties文件 。在properties文件中的內容爲:
待轉換的類型=類型轉換器的全類名
對於本例而言, xwork-conversion.properties文件中的內容爲:
java.util.Date= cn.itcast.conversion.DateConverter

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章