Struts(4)——结果处理方式

结果的处理大致可以分为四种:转发、重定向、转发到Action以及重定向到Action。
这些方式可以在result标签中通过type属性进行配置。

1. 转发

默认的处理方式是转发ServletDispatcherResult
可以在package org.apache.struts2.dispatcher下查看到其源码,其内部doExcute(String finalLocation, ActionInvocation invocation)方法的核心内容如下

RequestDispatcher dispatcher = request.getRequestDispatcher(finalLocation);
            if (StringUtils.isNotEmpty(finalLocation) && finalLocation.indexOf("?") > 0) {
                String queryString = finalLocation.substring(finalLocation.indexOf("?") + 1);
                Map<String, Object> parameters = this.getParameters(invocation);
                Map<String, Object> queryParams = this.urlHelper.parseQueryString(queryString, true);
                if (queryParams != null && !queryParams.isEmpty()) {
                    parameters.putAll(queryParams);
                }
            }

            if (dispatcher == null) {
                response.sendError(404, "result '" + finalLocation + "' not found");
                return;
            }

            Boolean insideActionTag = (Boolean)ObjectUtils.defaultIfNull(request.getAttribute("struts.actiontag.invocation"), Boolean.FALSE);
            if (!insideActionTag.booleanValue() && !response.isCommitted() && request.getAttribute("javax.servlet.include.servlet_path") == null) {
                request.setAttribute("struts.view_uri", finalLocation);
                request.setAttribute("struts.request_uri", request.getRequestURI());
                dispatcher.forward(request, response);
            } else {
                dispatcher.include(request, response);
            }

我们可以看到这里实际上是传入了result标签中给定的URL,这里的finalLocation也就是dispatcher的最终地址。

2.重定向

ServletRedirectResutl同样是在这个包下,其处理过程,也是类似的。
doExecute(String finalLocation, ActionInvocation invocation)源码如下

protected void doExecute(String finalLocation, ActionInvocation invocation) throws Exception {
        ActionContext ctx = invocation.getInvocationContext();
        HttpServletRequest request = (HttpServletRequest)ctx.get("com.opensymphony.xwork2.dispatcher.HttpServletRequest");
        //通过应用上下文获得response对象
        HttpServletResponse response = (HttpServletResponse)ctx.get("com.opensymphony.xwork2.dispatcher.HttpServletResponse");
        if (this.isPathUrl(finalLocation)) {
            if (!finalLocation.startsWith("/")) {
                ActionMapping mapping = this.actionMapper.getMapping(request, Dispatcher.getInstance().getConfigurationManager());
                String namespace = null;
                if (mapping != null) {
                    namespace = mapping.getNamespace();
                }

                if (namespace != null && namespace.length() > 0 && !"/".equals(namespace)) {
                //重定向的最终地址
                    finalLocation = namespace + "/" + finalLocation;
                } else {
                    finalLocation = "/" + finalLocation;
                }
            }

            if (this.prependServletContext && request.getContextPath() != null && request.getContextPath().length() > 0) {
                finalLocation = request.getContextPath() + finalLocation;
            }
        }

这里我们可以看到,它在内部先获取了HttpServletResponse请求,然后再调用了请求的sendRedirect方法。

3.转发到Action

此时在<result/>标签内,我们配置type属性为chain,在struts-default.xml中,我们可以查看该类型对应的Result类型。
在result标签下,配置如下属性:

<param name="actionName">Action</param>
<param name="namespace"></param>

actionName表示需要被链式调用的Action,namespace表示被转发到的package的命名空间,默认为当前命名空间。除了这两个之外,还有method以及skipAction两个属性。

4.重定向到Action

<result/>标签内,我们配置type属性为sendRediction,在struts-default.xml中,我们可以查看该类型对应的Result类型,并找到其全类名,以便于查看源码。这里依然直接看下它的配置

<param name="actionName">Action</param>
<param name="namespace"></param>

actionName表示重定向的目标Action,这里是重定向,并不能够传递参数。
它对应的类是ServletActionRedirectResult,下面大致地看一下它源码的excute()方法

public void execute(ActionInvocation invocation) throws Exception {
        this.actionName = this.conditionalParse(this.actionName, invocation);
        if (this.namespace == null) {
            this.namespace = invocation.getProxy().getNamespace();
        } else {
            this.namespace = this.conditionalParse(this.namespace, invocation);
        }

        if (this.method == null) {
            this.method = "";
        } else {
            this.method = this.conditionalParse(this.method, invocation);
        }

        String tmpLocation = this.actionMapper.getUriFromActionMapping(new ActionMapping(this.actionName, this.namespace, this.method, (Map)null));
        this.setLocation(tmpLocation);
        //这里它调用了父类的excute方法,那么关键就在于它的父类,它的父类是ServletRedirectResult,因而借助于父类完成了请求的重定向。
        super.execute(invocation);
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值