了解Struts2内部:结果配置

时间:2013-09-06 05:16:21

标签: java struts2

为了理解struts2如何加载其配置,我想显示将要呈现的JSP的路径。给出以下非常小的struts.xml:

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

    <package name="base" namespace="/">
        <result-types>
            <result-type name="dispatcher" class="org.apache.struts2.dispatcher.ServletDispatcherResult" default="true"/>
        </result-types>
        <action name="test" class="com.kenmcwilliams.badwebapp.action.Test">
            <result>/WEB-INF/content/test.jsp</result>
        </action>
    </package>
</struts>

我希望能够在操作中记录“/WEB-INF/content/test.jsp”。鉴于以下行动:

package com.quaternion.badwebapp.action;

import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.interceptor.PreResultListener;
import java.util.logging.Level;
import java.util.logging.Logger;

public class Test extends ActionSupport {
    //used for a sanity test on JSP
    public String getMessage() {
        return "From test";
    }

    @Override
    public String execute() throws Exception {
        System.out.println("ActionContext.getContext().getActionInvocation().getResultCode(): " + ActionContext.getContext().getActionInvocation().getResultCode());
        ActionInvocation ai = ActionContext.getContext().getActionInvocation();
        ai.addPreResultListener(new PreResultListener() {
            @Override
            public void beforeResult(ActionInvocation invocation, String resultCode) {
                try {
                    System.out.println("PreResultListener resultCode: " + resultCode);
                    System.out.println("PreResultListener result: " + invocation.getResult());
                } catch (Exception ex) {
                    Logger.getLogger(Test.class.getName()).log(Level.SEVERE, null, ex);
                }
            }
        });
        return SUCCESS;
    }
}

在我的控制台上有三个打印语句产生以下输出:

INFO:   ActionContext.getContext().getActionInvocation().getResultCode(): null
INFO:   PreResultListener resultCode: success
INFO:   PreResultListener result: null

从测试结果“invocation.getResult()”和结果代码为之前调用PreResultListener但之前的PreResultListener中设置了结果代码,但是结果仍然返回null!

来自getResult()方法的JavaDoc:

  

如果之前已执行ActionInvocation且结果为   {@link ActionChainResult}的实例,这个方法将走下去   ActionChainResult链,直到找到非链结果,即   将被退回。 如果没有ActionInvocation的结果   之前执行,将创建并填充Result实例   结果参数。

很明显,结果实例不是正在创建。

那么如何在此操作中显示“/WEB-INF/content/test.jsp”?这不适用于典型的struts2使用,我想测试一个配置提供程序,对于该操作的结果构造有问题,希望了解为什么这不起作用也会让我解决这个问题。

3 个答案:

答案 0 :(得分:4)

问题是你想从动作调用中获得结果,你不应该。动作调用结果供内部使用,应该受到保护。

要获得结果,您应该咨询ActionConfig并从那里获得结果。

ActionInvocation invocation = ActionContext.getContext().getActionInvocation();
ActionProxy proxy = invocation.getProxy();
ActionConfig config = proxy.getConfig();
Map<String, ResultConfig> results = config.getResults();
ResultConfig resultConfig = results.get(Action.SUCCESS);
String lastFinalLocation = null;
Map<String, String> params = resultConfig.getParams();
if (resultConfig.getClassName().equals("org.apache.struts2.dispatcher.ServletDispatcherResult")) {
  lastFinalLocation = params.get("location");
}
System.out.println("location: " + lastFinalLocation);

答案 1 :(得分:2)

有几件事:

  1. 在您尝试打印+ getResultCode()的那一刻,还没有这样的代码存在 - 记住它是通过返回结果字符串来确定结果的动作。因此,您需要在invocation.invoke()部分之后在该操作中的任何拦截器中打印出来。

  2. getResultCode()将返回结果字符串(成功,错误),而不是相应的路径。

答案 2 :(得分:1)

ActionContext.getContext().getActionInvocation().invokeActionOnly()将返回字符串(成功,输入,错误等)。