每个 action 方法都将返回一个 String 类型的值, Struts 将根据这个值来决定响应什么结果.
每个 action 声明都必须包含有数量足够多的 result 元素, 每个 result 元素分别对应着 action 方法的一个返回值.
result 元素可以有下面两个属性
name: 结果的名字, 必须与 Action 方法的返回值相匹配, 默认值为 success
type: 响应结果的类型. 默认值为 dispatcher
响应结果的类型
结果类型: dispatcher
dispatcher 结果类型是最常用的结果类型, 也是 struts 框架默认的结果类型
该结果类型有一个 location 参数, 它是一个默认参数
dispatcher 结果类型将把控制权转发给应用程序里的指定资源.
dispatcher 结果类型不能把控制权转发给一个外部资源. 若需要把控制权重定向到一个外部资源, 应该使用 redirect 结果类型
源码解析:
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 结果类型可以把响应重定向到一个外部资源
实例代码:
源码解析:
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 所在的命名空间作为 “目的地” 的命名空间
源码解析:继承于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;
}
}
实现的简单过程图:举例