Struts2をやってみる (3) - <result>のtypeに関して
struts.xmlにて
<action name="..." class="...">
    <result name="success">/WEB-INF/jsp/index.jsp</result>
</action>
っていうような記述を行う訳ですが、そこのtypeに指定する値でレスポンス方式を変えたり出来る模様。んまぁまだアノテーション利用な部分まで進んでないので(ry
で結構たくさんある模様なのだけど
- redirect
 - redirectAction
 - plainText
 - stream
 
等を利用してみる
plainText
<?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.devMode" value="true" />
    <package name="sample" extends="struts-default" namespace="/sample">
        <action name="test1" class="sample.action.IndexAction" method="test1">
            <!-- 実体はorg.apache.struts2.dispatcher.PlainTextResult -->
            <result name="success" type="plainText">
                <!-- 指定しないとNPE -->
                <param name="charSet">utf-8</param>
            </result>
        </action>
    </package>
</struts>
的な設定して
package sample.action;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.http.HttpServletResponse;
import org.apache.struts2.ServletActionContext;
import com.opensymphony.xwork2.ActionSupport;
public class IndexAction extends ActionSupport {
    private static final long serialVersionUID = 1L;
    public String test1() throws IOException {
        HttpServletResponse response = ServletActionContext.getResponse();
        response.setContentType("text/plain; charset=utf-8");
        PrintWriter out = response.getWriter();
        out.println("ほげ");
        out.flush();
        out.close();
        return SUCCESS;
    }
}
redirect
<?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.devMode" value="true" />
    <package name="sample" extends="struts-default" namespace="/sample">
        <action name="test2" class="sample.action.IndexAction" method="doDefault">
            <!-- org.apache.struts2.dispatcher.ServletRedirectResult -->
            <result name="success" type="redirect">
                <!-- 指定しないとNPE -->
                <param name="location">/sample/index.action</param>
            </result>
        </action>
    </package>
</struts>
的な設定をしてActionSupport.SUCCESSがぶん投げられたら指定した所にリダイレクトされる。で継承するActionSupportには
- doDeafult -> ActionSupport.SUCCESSを返すだけ
 - input -> ActionSupport.INPUTを返すだけ
 
的なメソッドが定義されているので、必要であるならばこれらを使えばリダイレクトする目的な所をわざわざクラスにメソッドを定義してSUCCESSを返させるようにしなくても良いっぽい
stream
<?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.devMode" value="true" />
    <package name="sample" extends="struts-default" namespace="/sample">
        <action name="test3" class="sample.action.IndexAction" method="test3">
            <!-- org.apache.struts2.dispatcher.StreamResult -->
            <result name="success" type="stream">
                <!--
                参照するInputStreamの変数名を設定出来るっぽい。デフォルトはinputStream
                <param name="inputName">inputStream</param>
                 -->
            </result>
        </action>
        <action name="sample" class="sample.action.SampleAction">
            <result>/index.jsp</result>
        </action>
    </package>
</struts>
的な定義をしてクラス上に指定したinputNameと同様なInputStreamな変数(正確にはゲッターが必要?)を定義する事でInputStreamなレスポンスを出す事も出来る
package sample.action;
import java.io.BufferedInputStream;
import java.io.File;
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;
public class IndexAction extends ActionSupport {
    private static final long serialVersionUID = 1L;
    private InputStream inputStream;
    public String test3() throws FileNotFoundException {
        ServletContext context = ServletActionContext.getServletContext();
        File file = new File(context.getRealPath("/path/to/image.jpg"));
        inputStream = new BufferedInputStream(new FileInputStream(file));
        return SUCCESS;
    }
    public InputStream getInputStream() {
        return inputStream;
    }
}
的な感じでInputStreamを作ってやるだけで良い模様
追記
PlainTextResultに関しては主に静的なファイルをレンダリングしたい目的として使うのが妥当な模様。そういう場合にPrintWriterで処理してレスポンスを出したい場合には
<action name="..." class="...">
    <result name="none" />
</action>
という風にNONEなレスポンスを返せば良い模様。これが正しいのかは微妙