自定義結果類型(result的type屬性)

需求:

自定義一個結果類型,用於自動生成驗證碼,生成驗證需要藉助一個第三方工具validatecode.jar,當然也可以自己實現

分析:

要想實現一個自定義的結果類型,那麼,我們可以參考struts2官方是如何實現現有的結果類型的。我們在struts.xml中定義package元素的時候,一般會繼承一個struts-default.xml的文件,這個文件中包含了struts2裏的很多核心內容,結果類型也在其中。我們可以在struts2的核心jar包中找到這個文件,打開來參考一下。我這裏以struts2-core-2.3.15.3.jar爲例:

struts核心包解壓

用解壓軟件打開這個jar包,在根目錄下,就可以找到這個struts-default.xml文件,再次打開這個文件,找到我們要的result-types定義的地方:

<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-types>

以上可以看出,struts2提供了這些結果類型。
我們現在要自定義一個結果類型,那麼,就可以參照這裏的結果類型進行定義,我們以默認的結果類型dispatcher爲例,我們看到它的實現類爲org.apache.struts2.dispatcher.ServletDispatcherResult
在myeclipse中,ctrl+shift+t 找到這個類

這裏寫圖片描述

分析這個類,我們看到,這個類主要有兩點,繼承了一個類爲StrutsResultSupport,實現了裏面的deExecute()方法,在方法中,實現了視圖的輸出

這裏寫圖片描述

於是,我們得出,我們的自定義結果類型也可以如此來實現。

返回結果的使用,這裏就不綴述了,既然找到方法了,那麼,下面就開始動手吧。

詳細步驟:

我們新建一個頁面,這個頁面只是爲了顯示驗證碼,就不再做任何的業務了。
在這個頁面中,我們生成驗證碼是訪問的一個action,最核心的就只有這一句:

驗證碼:

<input/><img alt="驗證碼" src="${pageContext.request.contextPath}/verifycode.action">

既然要訪問這個action,那麼我們就來寫這個action,這個action沒有任何寫的,就是一個普通的action,裏面的getCode()方法直接返回success

package demo.action;

import com.opensymphony.xwork2.ActionSupport;

/**
 * 驗證碼獲取Action
 * @author Minhellic
 *
 */
public class VerifyCodeAction extends ActionSupport {

    /**
     * 這裏直接返回,驗證碼通過返回的type來獲取
     * @return
     */
    public String getCode() {
        return SUCCESS;
    }

}

這樣做的目的就是在使用時,直接使用result的type屬性來指定我們自定義的返回結果類型,用這個返回結果類型來輸出驗證碼。所以,下一步就是要定義我們的重頭戲:自定義返回結果類型:

我們來定義好我們的返回結果類型:繼承類StrutsResultSupport,實現裏面的deExecute()方法,在方法中,實現視圖的輸出
在自定義CodeResult中,我們可以提供一些參數,併爲這些參數都提供setter方法,那麼在使用的時候,就可以在struts.xml中的Action > result 下,使用param標籤注入值,這樣使用我們的返回結果類型更加靈活

package demo.results;

import java.awt.image.BufferedImage;

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

import org.apache.struts2.ServletActionContext;
import org.apache.struts2.dispatcher.StrutsResultSupport;

import cn.dsna.util.images.ValidateCode;

import com.opensymphony.xwork2.ActionInvocation;

/**
 * 自定義Result:
 * 1.直接或間接地實現接口com.opensymphony.xwork2.Result,這裏採用的是繼承StrutsResultSupport類
 * 2.重寫doExcute()方法,在該方法中實現視圖的輸出
 * @author Minhellic
 *
 */
public class CodeResult extends StrutsResultSupport {

    private int width = 120;//驗證碼寬
    private int height = 80;//驗證碼高
    private int codeCount = 4;//驗證碼字符數
    private int lineCount = 100;//干擾線條數

    /*
     * 爲每個屬性添加set方法,以方便可以在struts.xml中的Action > result 下,使用param標籤注入值
     */
    public void setWidth(int width) {
        this.width = width;
    }

    public void setHeight(int height) {
        this.height = height;
    }

    public void setCodeCount(int codeCount) {
        this.codeCount = codeCount;
    }

    public void setLineCount(int lineCount) {
        this.lineCount = lineCount;
    }

    /**
     * 重寫父類的方法,以向頁面輸出驗證碼
     */
    @Override
    protected void doExecute(String arg0, ActionInvocation arg1)
            throws Exception {
        //借用第三方工具包ValidateCode.jar生成驗證碼
        ValidateCode vc = new ValidateCode(width, height, codeCount, lineCount);
        BufferedImage bi = vc.getBuffImg();

        //得到響應並輸出
        HttpServletResponse response = ServletActionContext.getResponse();
        ImageIO.write(bi, "jpeg", response.getOutputStream());
    }

}

OK,現在自定義的返回結果類型CodeResult已經有了,那麼就是使用了

在struts.xml中,使用result-types標籤來引用自定義的返回結果類型

<!-- 引用自定義的返回類型 -->
        <result-types>
            <result-type name="code" class="demo.results.CodeResult"></result-type>
        </result-types>

然後,在定義action的result時,就可能指定type爲自定義的返回結果類型了,同時,由於我們自定義返回結果類型時,還提供了一些參數,那麼,也可以使用param標籤對這些參數進行注入

<!-- action定義 -->
        <action name="verifycode" class="demo.action.VerifyCodeAction" method="getCode">
            <!-- 在result中,使用type屬性指定返回的類型爲自定義的code,如果不指定,會是dispatcher -->
            <result name="success" type="code">
                <!-- 由於自定義的返回類型中,對這些屬性提供了set方法,所以這裏可以使用param標籤注入值 -->
                <param name="width">300</param>
                <param name="height">30</param>
                <param name="codeCount">5</param>
                <param name="lineCount">30</param>
            </result>
        </action>

完整的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>

    <package name="demo" extends="struts-default">

        <!-- 引用自定義的返回類型 -->
        <result-types>
            <result-type name="code" class="demo.results.CodeResult"></result-type>
        </result-types>

        <!-- action定義 -->
        <action name="verifycode" class="demo.action.VerifyCodeAction" method="getCode">
            <!-- 在result中,使用type屬性指定返回的類型爲自定義的code,如果不指定,會是dispatcher -->
            <result name="success" type="code">
                <!-- 由於自定義的返回類型中,對這些屬性提供了set方法,所以這裏可以使用param標籤注入值 -->
                <param name="width">300</param>
                <param name="height">30</param>
                <param name="codeCount">5</param>
                <param name="lineCount">30</param>
            </result>
        </action>
    </package>

</struts>

最後,一定不要忘記在web.xml中註冊struts2哈

  <!-- struts2的核心過濾器 -->
  <filter>
    <filter-name>struts2</filter-name>
    <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>

最後,部署到tomcat,驗證一下結果:
這裏寫圖片描述

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