5

In an effort to understand how struts2 loads its configuration I wanted to display the path to the JSP which would be rendered. Given the following very minimal 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>

I want to be able to log "/WEB-INF/content/test.jsp" from within the action. Given the following action:

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;
    }
}

There are three print statements which produce the following output on my console:

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

From testing both the result "invocation.getResult()" and the resultcode is null before the PreResultListener is called but within the PreResultListener the resultcode is set, yet the result still returns null!

From the JavaDoc of the getResult() method:

If the ActionInvocation has been executed before and the Result is an instance of {@link ActionChainResult}, this method will walk down the chain of ActionChainResult's until it finds a non-chain result, which will be returned. If the ActionInvocation's result has not been executed before, the Result instance will be created and populated with the result params.

Seems pretty clear that a result instance is not being created.

So how do I display "/WEB-INF/content/test.jsp" within this action? This is not for typical struts2 use, I'm want to test a configuration provider for which there is something wrong with the construction of the result for the action, hopefully understanding why this isn't working will let me fix that too.

4

3 回答 3

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);
于 2013-09-06T13:01:34.957 回答
2

有几件事:

  1. 在您尝试打印 + 的那一刻,getResultCode()尚不存在此类代码 - 请记住,该操作将通过返回结果字符串来确定结果。因此,您需要在该invocation.invoke()部分之后的任何拦截器中打印该操作。

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

于 2013-09-06T08:12:36.043 回答
1

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

于 2014-08-20T12:55:46.807 回答