每个 action 方法都将返回一个 String 类型的值, Struts 将根据这个值来决定响应什么结果.
每个 action 声明都必须包含有数量足够多的 result 元素, 每个 result 元素分别对应着 action 方法的一个返回值.
result 元素可以有下面两个属性
name: 结果的名字, 必须与 Action 方法的返回值相匹配, 默认值为 success
type: 响应结果的类型. 默认值为 dispatcher

resultSet是什么 result s_默认值

resultSet是什么 result s_重定向_02

响应结果的类型

resultSet是什么 result s_重定向_03

结果类型:  dispatcher

 

dispatcher 结果类型是最常用的结果类型, 也是 struts 框架默认的结果类型

该结果类型有一个 location 参数, 它是一个默认参数

dispatcher 结果类型将把控制权转发给应用程序里的指定资源.
dispatcher 结果类型不能把控制权转发给一个外部资源. 若需要把控制权重定向到一个外部资源, 应该使用 redirect 结果类型

 

resultSet是什么 result s_默认值_04

源码解析:

public class ServletDispatcherResult extends StrutsResultSupport {
 
    public ServletDispatcherResult(String location) {
        super(location);
    }
 
    public void doExecute(String finalLocation, ActionInvocation invocation)  {
         
        PageContext pageContext = ServletActionContext.getPageContext();
 
        if (pageContext != null) {
            pageContext.include(finalLocation);
        } else {
            HttpServletRequest request = ServletActionContext.getRequest();
            HttpServletResponse response = ServletActionContext.getResponse();
//最终的实现还是Servlet的Api 转发请求的
            RequestDispatcher dispatcher = request.getRequestDispatcher(finalLocation);
  
            } 
            
            if (!insideActionTag && !response.isCommitted() && (request.getAttribute("javax.servlet.include.servlet_path" ) == null)) {
    //进行调用转发目标地址
                dispatcher. forward(request, response);
            } else {
                dispatcher.include(request, response);
            }
        }
    }
 
}

配置文件的中的参数由父类 属性继承得到StrutsResultSupport

public abstract class StrutsResultSupport implements Result, StrutsStatics {
 
    public static final String DEFAULT_PARAM = "location";
 
    private boolean parse ;
    private boolean encode ;
    private String location;
    private String lastFinalLocation;
 
    public StrutsResultSupport(String location, boolean parse, boolean encode) {
        this.location = location;
        this.parse = parse;
        this.encode = encode;
    }
 
    public void setLocation(String location) {
        this.location = location;
    }
   
    public String getLocation() {
        return location ;
    }
 
    public void setParse(boolean parse) {
        this.parse = parse;
    }
 
    
    public void setEncode(boolean encode) {
        this.encode = encode;
    }
 
    public void execute(ActionInvocation invocation) throws Exception {
  //在这里获取目标地址Url 默认为location
        lastFinalLocation = conditionalParse(location , invocation);
//执行ServletDispatcherResult 的实现方法
        doExecute( lastFinalLocation, invocation);
    }
结果类型:  redirect

redirect 结果类型将把响应重定向到另一个资源, 而不是转发给该资源.
redirect 结果类型接受下面这些参数:
location: 用来给出重定向的目的地.它是默认属性
parse: 用来表明是否把 location 参数的值视为一个 OGNL 表达式来解释. 默认值为 true
redirect 结果类型可以把响应重定向到一个外部资源
实例代码: 

resultSet是什么 result s_命名空间_05

源码解析:

public class ServletRedirectResult extends StrutsResultSupport {
    protected void doExecute(String finalLocation, ActionInvocation invocation) {
        ActionContext ctx = invocation.getInvocationContext();
        HttpServletRequest request = (HttpServletRequest) ctx.get(ServletActionContext.HTTP_REQUEST );
        HttpServletResponse response = (HttpServletResponse) ctx.get(ServletActionContext.HTTP_RESPONSE );
 
          //获取到目标Url
            finalLocation = response.encodeRedirectURL(tmpLocation.toString());
        } 
        sendRedirect(response, finalLocation);
    }
 protected void sendRedirect(HttpServletResponse response, String finalLocation) {
        if (SC_FOUND == statusCode ) {
//进行重定向
            response.sendRedirect(finalLocation);

    }
location 和parse:参数也是从父类中继承和dispatcher一样,在StrutsResultSupport中进行设置 
 
结果类型:  redirectAction

redirectAction 结果类型把响应重定向到另一个 Action
redirectAction 结果类型接受下面这些参数:
actionName: 指定 “目的地” action 的名字. 它是默认属性
namespace: 用来指定 “目的地” action 的命名空间. 如果没有配置该参数, Struts 会把当前 Action 所在的命名空间作为 “目的地” 的命名空间

resultSet是什么 result s_resultSet是什么_06

源码解析:继承于ServletRedirectResult 结果类型

public class ServletActionRedirectResult extends ServletRedirectResult implements ReflectionExceptionHandler {
 
    public static final String DEFAULT_PARAM = "actionName";
     //这是多出的参数在配置文件中
    protected String actionName;
    protected String namespace;
    protected String method;
 
    public void execute(ActionInvocation invocation) throws Exception {
        actionName = conditionalParse(actionName , invocation);
        if (namespace == null) {
            namespace = invocation.getProxy().getNamespace();
        } else {
            namespace = conditionalParse(namespace , invocation);
        }
        if (method == null) {
            method = "";
        } else {
            method = conditionalParse( method, invocation);
        }
 
        String tmpLocation = actionMapper.getUriFromActionMapping(new ActionMapping(actionName, namespace , method , null));
 
        setLocation(tmpLocation);
//最终通过解析配置生成目标Url交给父类进行重定向到目标地址
        super.execute(invocation);
    }
 
    public void setActionName(String actionName) {
        this.actionName = actionName;
    }
 
    public void setNamespace(String namespace) {
        this.namespace = namespace;
    }
 
    public void setMethod(String method) {
        this.method = method;
    }
  
}
结果类型:  chain

chain 结果类型的基本用途是构成一个 action 链: 前一个 action 把控制权转发给后一个 action, 而前一个 action 的状态在后一个 action 中依然保持
chain 结果类型接受下面这些参数:
actionName: 指定目标 action 的名字. 它是默认属性
namespace: 用来指定 “目的地” action 的命名空间. 如果没有配置该参数, Struts 会把当前 action 所在的命名空间作为 “目的地” 的命名空间
method: 指定目标 action 方法. 默认值为 execute

 源码解析:

public class ActionChainResult implements Result {
 
    public static final String DEFAULT_PARAM = "actionName";
 
    private static final String CHAIN_HISTORY = "CHAIN_HISTORY";
 
    public static final String SKIP_ACTIONS_PARAM = "skipActions";
 
 
    private ActionProxy proxy;
    private String actionName;
   
    private String namespace;
 
    private String methodName;
 
    public void setActionName(String actionName) {
        this.actionName = actionName;
    }
 
    public void setNamespace(String namespace) {
        this.namespace = namespace;
    }
 
   
    public void setSkipActions(String actions) {
        this.skipActions = actions;
    }
 
 
    public void setMethod(String method) {
        this.methodName = method;
    } 
    public void execute(ActionInvocation invocation) throws Exception {
         
        proxy = actionProxyFactory.createActionProxy(finalNamespace, finalActionName, finalMethodName, extraContext);
        proxy.execute();
    }
 
    private String makeKey(String namespace, String actionName, String methodName) {
        if (null == methodName) {
            return namespace + "/" + actionName;
        }
 
        return namespace + "/" + actionName + "!" + methodName;
    }
}

实现的简单过程图:举例

resultSet是什么 result s_重定向_07