Action動作類以及struts.xml配置解析

轉自:http://blog.csdn.net/i10630226

一、Action動作類(一般用**Action結尾)

struts2 的Action可以是POJO(Plain Old Java Object)
爲了讓用戶開發的Action更加規範struts2提供了一個Action接口

這裏寫圖片描述

通過method屬性指定Action執行方法

沒有指定method屬性,默認執行execute方法

<action name="addCustomer" class="xgp.struts.actions.CustomerAction" />
  • 1
  • 1

通過method屬性,指定調用Action相應方法處理請求

<action name="addCustomer" class="xgp.struts.actions.CustomerAction" method="add">
  • 1
  • 1

因爲指定了method=”add”,所以HelloAction的ass方法會被調用.

1、編寫動作類的三種方式

a、第一種方法是,動作類不實現、也不繼承任何的接口和類。即動作類是一個非常普通的JavaBean。

public class HelloAction {
    public String sayHello(){
        System.out.println("動作類執行了,訪問成功!");
        return "success";
    }
} 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

b、動作類實現com.opensymphony.xwork2.Action接口。可以使用常量

Action接口:

public static final String SUCCESS = "success"; //成功時轉向的視圖
public static final String NONE = "none";//執行成功後,不轉向的任何視圖。比如下載任務
public static final String ERROR = "error";//轉向錯誤視圖
public static final String INPUT = "input";//轉向輸入視圖。(回顯:驗證與轉換失敗,轉向原有頁面)
public static final String LOGIN = "login";//登錄視圖(用戶沒有登錄)
public String execute() throws Exception;// public 修飾符,String 返回值,無參數
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

c、繼承com.opensymphony.xwork2.ActionSupport(開發中建議)

Struts2爲Action接口提供了一個實現類 ActionSupport,定義了 表單域校驗、錯誤信息設置和獲得國際化信息相關一些方法

public class ActionSupport implements Action, Validateable, ValidationAware, TextProvider, LocaleProvider, Serializable {

    protected static Logger LOG = LoggerFactory.getLogger(ActionSupport.class);

    private final ValidationAwareSupport validationAware = new ValidationAwareSupport();

    private transient TextProvider textProvider;
    private Container container;

    public void setActionErrors(Collection<String> errorMessages) {
        validationAware.setActionErrors(errorMessages);
    }

    public Collection<String> getActionErrors() {
        return validationAware.getActionErrors();
    }

    public void setActionMessages(Collection<String> messages) {
        validationAware.setActionMessages(messages);
    }

    public Collection<String> getActionMessages() {
        return validationAware.getActionMessages();
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24

2、動作類中的動作方法

要求:
a、必須是public的
b、必須返回String類型的
c、必須沒有參數

3.動作類的生命週期

動作類每次訪問都會重新被實例化,是線程安全的。

public class HelloAction {

    public HelloAction() {
        System.out.println("執行構造函數HelloAction,實例化對象。");
    }

    public String sayHello(){
        System.out.println("動作方法sayHello執行了,訪問成功!");
        return "success";
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

測試結果:

這裏寫圖片描述

二、動作類中動作方法的調用

動作方法:動作類中的定義的處理業務有關的方法

實例:模擬一個curd的動作類

工程目錄如下:

這裏寫圖片描述

1、新建一個 curd.jsp

  <body>
    <a href="${pageContext.request.contextPath}/customer/addCustomer.action">增加用戶</a>
    <a href="${pageContext.request.contextPath}/customer/editCustomer.action">修改用戶</a>
    <a href="${pageContext.request.contextPath}/customer/findCustomer.action">查詢用戶</a>
    <a href="${pageContext.request.contextPath}/customer/delCustomer.action">刪除用戶</a>
  </body>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

2、在struts.xml中配置

如下圖所示:

這裏寫圖片描述

<struts>
    <constant name="struts.devMode" value="true" />
    <package name="p1" extends="struts-default" namespace="/customer">
        <action name="addCustomer" class="xgp.struts.actions.CustomerAction" method="add">
            <result name="success" type="dispatcher">/addCustomer.jsp</result>
            <result name="error" type="dispatcher">/error.jsp</result>
        </action>
        <action name="editCustomer" class="xgp.struts.actions.CustomerAction" method="edit">
            <result name="success" type="dispatcher">/editCustomer.jsp</result>
        </action>
        <action name="findCustomer" class="xgp.struts.actions.CustomerAction" method="find">
            <result name="success" type="dispatcher">/findCustomer.jsp</result>
        </action>
        <action name="delCustomer" class="xgp.struts.actions.CustomerAction" method="del">
            <result name="success" type="dispatcher">/delCustomer.jsp</result>
        </action>
    </package>
</struts>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

3、建立動作處理類CustomerAction

package xgp.struts.actions;

import xgp.struts.service.BusinessService;
import xgp.struts.serviceImpl.BusinessServiceImpl;

import com.opensymphony.xwork2.ActionSupport;

public class CustomerAction extends ActionSupport{

    private BusinessService bs = new BusinessServiceImpl();
    public String add(){
        //調用Service添加方法
        try {
            bs.add();
            return SUCCESS;
        } catch (Exception e) {
            return ERROR;
        }
    }

    public String edit(){
        bs.edit();
        return SUCCESS;
    }

    public String find(){
        bs.find();
        return SUCCESS;
    }

    public String del(){
        bs.del();
        return SUCCESS;
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36

4、建立相應的業務接口BusinessService和實現類BusinessServiceImpl
BusinessService

package xgp.struts.service;

public interface BusinessService {
    public void add();
    public void edit();
    public void del();
    public Object find();

}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

BusinessServiceImpl

package xgp.struts.serviceImpl;

import xgp.struts.service.BusinessService;

public class BusinessServiceImpl implements BusinessService{

    @Override
    public void add() {
        System.out.println("Serviece的add方法執行成功!");

    }

    @Override
    public void edit() {
        System.out.println("Serviece的edit方法執行成功!");

    }

    @Override
    public void del() {
        System.out.println("Serviece的del方法執行成功!");

    }

    @Override
    public Object find() {
        System.out.println("Serviece的find方法執行成功!");
        return null;
    }

}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32

結果如下:

這裏寫圖片描述

1、使用通配符配置Action

在配置<action...>元素時,允許在指定name屬性時,使用模式字符串(用"*"代表一個或多個任意字符)

在class、method屬性及<result>子元素中通過 {N} 形式代表前面地N個* 匹配子串

這裏寫圖片描述

例如上面的案例中struts.xml我們可以改寫如下:


<!-- 使用通配符:*
         {2}:匹配第2個星花的內容
          -->
          <!-- http://localhost:8080/xgp.struts/customer/add_Customer.action
            第一個*: add
            第二個*:Customer
           -->
<action name="*_*" class="xgp.struts.actions.{2}Action" method="{1}">
    <result name="success" type="dispatcher">/{1}{2}.jsp</result>
</action>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

2、使用Action的動態方法調用(官方不建議使用)

動態方法調用:DMI
http://localhost:8080/xgp.struts/customer/add_Customer!add

希望執行CustomerAction的add動作方法(動態方法調用)
動態方法調用:Struts2框架默認是禁止的。可以通過配置一個常量打開它:

<constant name="struts.enable.DynamicMethodInvocation" value="true"></constant>
  • 1
  • 1

通過url動態指定調用Action哪個方法而無需配置<action>的method屬性, 通過 !方法名 指定調用Action哪個方法

<a href="${pageContext.request.contextPath}/customer/customer!add.action">添加用戶</a><br/>
<a href="${pageContext.request.contextPath}/customer/customer!edit.action">修改用戶</a><br/>
<a href="${pageContext.request.contextPath}/customer/customer!del.action">刪除用戶</a><br/>
  • 1
  • 2
  • 3
  • 4
  • 1
  • 2
  • 3
  • 4

3、配置默認Action和 配置Action默認處理類

用戶可以爲每個package定義一個默認的Action,如果訪問路徑在package沒有匹配<action> 就會執行默認action

<default-action-ref name="defaultAction"></default-action-ref>
<action name="defaultAction">
    <result name="success" type="dispatcher">/whatareuwant.jsp</result>
</action>
  • 1
  • 2
  • 3
  • 4
  • 1
  • 2
  • 3
  • 4

如果配置<action> 沒有指定class屬性,就會執行Action的默認處理類,在struts-default.xml中.
指定默認的動作處理類

 <!-- 指定默認的動作:當用戶訪問的動作在本包中沒有找到時執行的動作 -->
        <default-action-ref name="defaultAction"></default-action-ref>
        <!-- 指定默認的動作處理類 -->
         <default-class-ref class="xgp.struts.actions.DefaultAction"></default-class-ref>
        <action name="customer" class="xgp.struts.actions.CustomerAction">
            <result name="success" type="dispatcher">/success.jsp</result>
        </action>
        <action name="defaultAction">
            <result name="success" type="dispatcher">/whatareuwant.jsp</result>
        </action>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

三、在動作類中訪問ServletAPI

Struts2的Action沒有與任何Servlet API耦合,便於測試.這是他的優點之一.

1、三大實現方法

1、ActionContext

  • getContext() 返回ActionContext實例對象
  • get(key) 相當於 HttpServletRequest的getAttribute(String name)方法
  • put(String,Object) 相當於HttpServletRequest的setAttribute方法
  • getApplication() 返回一個Map對象,存取ServletContext屬性
  • getSession() 返回一個Map對象,存取HttpSession屬性
  • getParameters() 類似調用HttpServletRequest的getParameterMap()方法
  • setApplication(Map) 將該Map實例裏key-value保存爲ServletContext的屬性名、屬性值
  • setSession(Map) 將該Map實例裏key-value保持爲HttpSession的屬性名、屬性值

2、方式二:(簡單,推薦使用)使用ServletActionContext

static PageContext getPageContext()
static HttpServletRequest getRequest()
static HttpServletResponse getResponse()
static ServletContext getServletContext()
  • 1
  • 2
  • 3
  • 4
  • 1
  • 2
  • 3
  • 4

該方案可避免Action類實現XxxAware接口,但Action依然與Servlet API直接耦合
開發中優先使用ActionContext 這樣可以避免耦合

package com.itheima.actions;

import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.jsp.PageContext;

import org.apache.struts2.ServletActionContext;
import org.apache.struts2.interceptor.ServletRequestAware;

import com.opensymphony.xwork2.ActionSupport;

public class ServletAPIAction1 extends ActionSupport{

    //打印當前應用名稱到控制檯上
    //獲取ServletAPI有關類的實例
    //方式一:
    public String execute() throws Exception {
        //實際上利用ThreadLocal這個類
        //ServletActionContext:記住
        HttpServletRequest request = ServletActionContext.getRequest();
        System.out.println(request.getContextPath());
        PageContext pc = ServletActionContext.getPageContext();
        HttpServletResponse response = ServletActionContext.getResponse();
        response.getWriter().write(request.getContextPath());//自己輸出
        ServletContext sc = ServletActionContext.getServletContext();
        System.out.println(sc.getRealPath("/"));
        return NONE;
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31

3、方式三:(麻煩)實現接口,訪問Action時完成注入

ServletContextAware
void setServletContext(javax.servlet.ServletContext context)

ServletRequestAware
void setServletRequest(javax.servlet.http.HttpServletRequest request)

ServletResponseAware
void setServletResponse(javax.servlet.http.HttpServletResponse response)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

動作類實現特定的接口。就必須實現特定的方法,調用動作方法前,框架會把響應的對象給注入進來。

package com.itheima.actions;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.struts2.interceptor.ServletRequestAware;
import org.apache.struts2.interceptor.ServletResponseAware;

import com.opensymphony.xwork2.ActionSupport;
//獲取ServletAPI有關類實例的方式二
public class ServletAPIAction2 extends ActionSupport implements ServletRequestAware,ServletResponseAware{
    private HttpServletRequest request;
    private HttpServletResponse response;
    //該方法會在調用動作方法之前先執行:把當前的HttpServletRequest對象給你注入進來
    public void setServletRequest(HttpServletRequest request) {
        this.request = request;
    }

    public void setServletResponse(HttpServletResponse response) {
        this.response = response;
    }
    @Override
    public String execute() throws Exception{

        //要使用HttpServletRequest對象
        //System.out.println(request.getContextPath());
        response.getWriter().write(request.getContextPath());
        return NONE;
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31

原理:是一個攔截器給你注入進來的。struts-default.xml

<interceptor name="servletConfig" class="org.apache.struts2.interceptor.ServletConfigInterceptor"/>
  • 1
  • 1

一看源碼便知。
配置struts.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 name="struts.devMode" value="true" />
    <package name="p1" extends="struts-default">
        <!-- 因爲包繼承了struts-default,默認使用struts-default.xml中定義的那個默認的攔截器棧:defaultStack
            在執行動作方法之前:defaultStack中的組員都會攔截你的動作調用
            包含:一個叫做servletConfig的攔截器。
         -->

        <!-- 演示在動作類中獲取Servlet有關的類的實例:HttpServletRequest HttpServletResponse HttpSession ServletContext等
        Struts2已經將ServletAPI和動作類進行解耦,這是他的優點之一
         -->
        <action name="showContextPath1" class="com.itheima.actions.ServletAPIAction1">
            <result name="success" type="dispatcher">/success.jsp</result>
        </action>
        <action name="showContextPath2" class="com.itheima.actions.ServletAPIAction2" method="execute">
            <result name="success" type="dispatcher">/success.jsp</result>
        </action>
    </package>
</struts>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24

2、局部和全局結果視圖

result元素:指定動作類的動作方法執行完後的結果視圖.
屬性:
- name:字符串,與動作方法返回的值一致。默認是success
- type:指定處理結果的結果類型的別名。(struts-default.xml有定義,共10個)。默認值是dispatcher

Action處理完用戶請求後,將返回一個普通字符串整個普通字符串就是一個邏輯視圖名,Struts2 根據邏輯視圖名,決定響應哪個結果。

Struts2處理結果使用<result>元素配置

  • 局部結果:將<result>作爲<action>子元素配置
  • 全局結果:將<result>作爲<global-results>元素的子元素配置

配置<result>元素通常需要指定兩個屬性

  • name 該屬性指定配置邏輯視圖名
  • type 該屬性指定結果類型

當多個action中都使用到了相同result,這時我們應該把result定義爲全局結果。struts1中提供了全局forward,struts2中也提供了相似功能:

<package ....>
    <global-results>
        <result name="message">/message.jsp</result>
    </global-results>
</package>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 1
  • 2
  • 3
  • 4
  • 5

注:局部的會覆蓋全局

Struts1中應用範圍內action的實例 action是單實例(執行時,現在緩存中查找實例,有用,沒有創建新的實例)Struts2中 應用範圍內action的實例,每個請求都會創建一個action實例Servlet屬於單實例多線程的應用,實例只在初始化時被加載多實例比單實例的優點,不會產生併發問題,但執行速度不如單實例

如下:

<struts>
    <constant name="struts.devMode" value="true" />

        <package name="mydefault" extends="struts-default" abstract="ture">
            <global-results>
                <result name="success" type="dispatcher">/success.jsp</result>
            </global-results>
        </package>

        <package name="p1" extends="mydefault">
        <action name="action1" class="xgp.struts.actions.Demo1Action">
            <!-- <result name="success" type="dispatcher">/success.jsp</result> -->
        </action>
        <action name="action2" class="xgp.struts.actions.Demo2Action">
            <!-- <result name="success" type="dispatcher">/success.jsp</result> -->
        </action>
    </package>

    <package name="p2" extends="mydefault">
            <action name="action3" class="xgp.struts.actions.Demo3Action">
                <!-- <result name="success" type="dispatcher">/success.jsp</result> -->
            </action>
    </package>

</struts>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25

這裏寫圖片描述

3、Struts2提供的結果視圖 (共10個)

<result-type name="dispatcher" class="org.apache.struts2.dispatcher.ServletDispatcherResult" default="true"/>
<result-type name="chain" class="com.opensymphony.xwork2.ActionChainResult"/>
<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" />
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

1. chain:從一個動作轉發到另外一個動作

同一個包內的動作轉發

    <package name="p3" namespace="/result" extends="struts-default">
        <!--  action1的結果是另外一個Action的請求:一個動作轉發到了另外一個動作
            演示:同包內的動作轉發-->
        <action name="action1">
            <result name="success" type="chain">action2</result>
        </action>
        <action name="action2">
            <result>/success.jsp</result>
        </action>
    </package>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

不同包之間的動作轉發

    <package name="p3" namespace="/result" extends="struts-default">
         <action name="action1">
            <result name="success" type="chain">
                <param name="namespace">/user</param> 給chain的實際處理類注入參數
                <param name="actionName">action2</param>
            </result>
        </action>
    </package>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

2. dispatcher:從一個動作轉發到另外一個JSP

dispatcher 結果類型是最常用的結果類型, 也是 struts 框架默認的結果類型
該結果類型有一個 location 參數, 它是一個默認參數

這裏寫圖片描述

dispatcher 結果類型將把控制權轉發給應用程序裏的某個資源

3. redirect:從一個動作重定向到一個JSP
最明顯的是地址欄發生變化。

<action name="action2">
    <result type="redirect">/success.jsp</result>
</action>
  • 1
  • 2
  • 3
  • 1
  • 2
  • 3

4. redirectAction:從一個動作重定向到另外一個動作
action1先將動作重定向到action2,然後action2在轉發到success.jsp,地址欄應該顯示的是action2.

<action name="action1">
    <result name="success" type="redirectAction">action2</result>
</action>
<action name="action2">
    <result>/success.jsp</result>
</action>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

5. plainText:以純文本的形式顯示JSP

<package name="p4" namespace="/user" extends="struts-default">
    <action name="action2">
        <result type="plainText">/success.jsp</result>
    </action>
</package>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 1
  • 2
  • 3
  • 4
  • 5

6. stream:文件下載

<package name="p5" extends="struts-default">
        <action name="download" class="xgp.struts.actions.DownLoadAction" method="download">
            <result name="success" type="stream">
                <!-- 配置輸入流 -->
                <param name="inputName">imageInputStream</param>
                <!-- 告知瀏覽器響應正文的MIME類型 -->
                <param name="contentType">application/octet-stream</param>
                <!-- 告知瀏覽器用下載的方式打開 -->
                <param name="contentDisposition">attachment;filename=26.jpg</param>
                <!-- 下載時使用的緩存大小 -->
                <param name="bufferSize">1024</param>
            </result>
        </action>
    </package>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

DownLoadAction類

package com.itheima.actions;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;

import javax.servlet.ServletContext;

import org.apache.struts2.ServletActionContext;

import com.opensymphony.xwork2.ActionSupport;
//文件下載;結果類型stream的使用
public class DownLoadAction extends ActionSupport {

    private InputStream imageInputStream;

    public InputStream getImageInputStream() {
        return imageInputStream;
    }

    public void setImageInputStream(InputStream imageInputStream) {
        this.imageInputStream = imageInputStream;
    }

    public String download() throws Exception{
        //得到文件的真實路徑
        ServletContext sc = ServletActionContext.getServletContext();
        String filePath = sc.getRealPath("/WEB-INF/classes/26.jpg");
        //構建輸入流
        imageInputStream = new FileInputStream(filePath);
        //用stream結果視圖輸出
        //返回邏輯視圖
        return SUCCESS;
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36

結果顯示

這裏寫圖片描述

4、自定義結果視圖

目標:用一個叫做image的視圖,輸入隨機驗證碼圖片 CAPTCHA,我們首先可以看dispatcher的聲明;

public class org.apache.struts2.dispatcher.ServletDispatcherResult extends org.apache.struts2.dispatcher.StrutsResultSupport

public abstract class org.apache.struts2.dispatcher.StrutsResultSupport implements com.opensymphony.xwork2.Result

可以看到dispatch的實現類是繼承StrutsResultSupport,而StrutsResultSupport又實現了Resul接口。多以我麼可以

1、編寫一個類實現com.opensymphony.xwork2.Result,或者繼承org.apache.struts2.dispatcher.StrutsResultSupport,這裏定義一個類,實現com.opensymphony.xwork2.Result接口

package xgp.struts.actions;

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.util.Random;

import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletResponse;

import org.apache.struts2.ServletActionContext;

import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.Result;


public class CaptchaResult implements Result {

    private int width;
    private int height;

    public int getWidth() {
        return width;
    }
    public void setWidth(int width) {
        this.width = width;
    }
    public int getHeight() {
        return height;
    }
    public void setHeight(int height) {
        this.height = height;
    }
    public void execute(ActionInvocation arg0) throws Exception {
        /*int width=120,height=25;*/
        //1.在內存生成一個圖片
        BufferedImage img = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
        //2.得到畫筆
        Graphics g = img.getGraphics();
        //3.畫一個矩形框
        g.setColor(Color.BLUE);
        g.drawRect(0, 0, width, height);
        //4.填充背景
        g.setColor(Color.YELLOW);
        g.fillRect(1, 1, width-1, height-1);
        //5.畫一些干擾線條
        g.setColor(Color.GRAY);
        Random random = new Random();
        for(int i=1;i<=20;i++)
             g.drawLine(random.nextInt(width), random.nextInt(height), random.nextInt(width), random.nextInt(height));
        //6.畫字符串隨機的
        g.setColor(Color.RED);
        //設置字體
        g.setFont(new Font("宋體",Font.BOLD|Font.ITALIC,20));
        for(int i=1;i<=4;i++)
            g.drawString(random.nextInt(10)+"", i*20,20);



        //7.輸出
        HttpServletResponse response = ServletActionContext.getResponse();
        response.setContentType("image/jpeg");
        ImageIO.write(img, "jpg", response.getOutputStream());

    }

}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69

2、自定義的結果視圖,(必須先聲明後才能使用)

<package name="p6" extends="struts-default">
    <result-types>
        <result-type name="captcha" class="xgp.struts.actions.CaptchaResult"></result-type>
    </result-types>
    <action name="genCaptcha">
        <result name="success" type="captcha">
            <param name="width">300</param>
            <param name="height">400</param>
        </result>
    </action>       
</package>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

3、就可以使用了,編寫視圖頁面login.jsp

<body>
    <form action="">
        用戶名:<input type="text" name="username"/><br />
        驗證碼:<input type="text" name="code" /><img alt="驗證碼" src="${pageContext.request.contextPath}/genCaptcha.action">
    </form>
  </body>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

運行結果
這裏寫圖片描述

如果想在多個包中用,可以將package聲明爲abstract ,然後別的包繼承自這個包即可。

階段性小結

這裏寫圖片描述

(function () { ('pre.prettyprint code').each(function () { var lines = (this).text().split(\n).length;var numbering = $('
    ').addClass('pre-numbering').hide(); (this).addClass(hasnumbering).parent().append( numbering); for (i = 1; i
    發表評論
    所有評論
    還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
    相關文章