首页 课程 师资 教程 报名

Struts2工作原理详解

  • 2022-02-10 08:50:56
  • 1128次 星辉

工作准则

Struts2 的工作原理如下图所示。这里我们一步步介绍每一步的核心内容。

在Struts2框架中处理一个请求大致分为以下几个步骤

1.客户端初始化一个对Servlet容器(如Tomcat)的请求

2.这个请求通过一系列过滤器(其中一个是可选的过滤器,称为 ActionContextCleanUp,它对于集成 Struts 2 和其他框架,例如 SiteMesh Plugin 很有用)。

3.然后调用FilterDispatcher,FilterDispatcher询问Action Mapper来决定这个请求是否需要调用一个Action。

FilterDispatcher是控制器的核心,也是mvc中c控制层的核心。下面粗略分析一下我理解的filter Dispatcher工作流程和原理:Filter Dispatcher初始化和核心doFilter启用

public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) 抛出 IOException, ServletException ...{  
        HttpServletRequest 请求 = (HttpServletRequest) 请求;  
        HttpServletResponse 响应 = (HttpServletResponse) res;  
        ServletContext  servletContext  =  filterConfig .getServletContext();  
        //这里处理HttpServletRequest和HttpServletResponse。   
        DispatcherUtils  du  =  DispatcherUtils .getInstance();  
        du.prepare(request, response);//像方法名一样进行locale、encoding和特殊请求参数设置。
        尝试 ...{  
            request  =  du .wrapRequest(request, servletContext);//打包请求
        } 捕捉 (IOException e) ...{  
            String  message  =  "无法使用 MultipartRequestWrapper 包装 servlet 请求!" ;  
            LOG.error(消息,e);  
            抛出新的 ServletException(消息,e);  
        }  
                ActionMapperIF  mapper  =  ActionMapperFactory .getMapper();//获取动作映射器
        ActionMapping  mapping  =  mapper .getMapping(request);//映射获取动作
        如果(映射 ==空)...{  
            // 这个请求中没有任何动作,我们应该寻找静态资源吗?  
            String  resourcePath  =  RequestUtils .getServletPath(request);  
            if ("".equals(resourcePath) && null != request.getPathInfo()) ...{  
                resourcePath  = 请求.getPathInfo();  
            }  
            if ("true".equals(Configuration.get(WebWorkConstants.WEBWORK_SERVE_STATIC_CONTENT))   
                    && resourcePath.startsWith("/webwork")) ...{  
                字符串 名称 =  resourcePath .substring("/webwork".length());  
                findStaticResource(名称,响应);  
            } 别的 ...{  
                // 这是一个正常的请求,让它通过  
                链.doFilter(请求,响应);  
            }  
            // WW 在这里完成了它的工作  
            返回;  
        }  
        对象 o  =  null ;  
        尝试 ...{  
            //setupContainer(请求);  
            o  =  beforeActionInvocation (request, servletContext);  
//下面分析整个框架的核心方法。
            du.serviceAction(请求,响应,servletContext,映射);  
        } 最后 ...{  
            afterActionInvocation(request, servletContext, o);  
            ActionContext.setContext(null);  
        }  
    }  
du.serviceAction(请求,响应,servletContext,映射);  
//该方法询问Action Mapper是否需要调用Action来处理请求。如果 Action Mapper 决定需要调用某个 Action,FilterDispatcher 就会处理对 ActionProxy 的请求。
   
public void serviceAction(HttpServletRequest request, HttpServletResponse response, String namespace, String actionName, Map requestMap, Map parameterMap, Map sessionMap, Map applicationMap) ...{   
        HashMap  extraContext  =  createContextMap (requestMap, parameterMap, sessionMap, applicationMap, request, response, getServletConfig()); //实例化Map请求,询问ActionMapper是否需要调用Action来处理请求。
        extraContext.put(SERVLET_DISPATCHER, 这个);   
        OgnlValueStack 堆栈 = (OgnlValueStack) request.getAttribute(ServletActionContext.WEBWORK_VALUESTACK_KEY);   
        如果(堆栈!= null)...{   
            extraContext.put(ActionContext.VALUE_STACK,new OgnlValueStack(stack));   
        }   
        尝试 ...{   
            ActionProxy 代理 =  ActionProxyFactory .getFactory().createActionProxy(namespace, actionName, extraContext);   
//这里的actionName是通过两个getAction Name通道解析的。FilterDispatcher 处理对 ActionProxy 的请求。这是 Servlet Dispatcher 的 TODO:。
            request.setAttribute(ServletActionContext.WEBWORK_VALUESTACK_KEY, proxy.getInvocation().getStack());   
            proxy.execute();   
         //ActionProxy通过代理方式执行
            如果(堆栈!= null)...{   
                request.setAttribute(ServletActionContext.WEBWORK_VALUESTACK_KEY,stack);   
            }   
        } 捕捉(配置异常 e)...{   
            log.error("找不到动作", e);   
            发送错误(请求,响应,HttpServletResponse.SC_NOT_FOUND,e);   
        } 捕捉(异常 e)...{   
            log.error("无法执行动作", e);   
            sendError(request, response, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e);   
        }   
}   

4.如果ActionMapper决定需要调用一个Action,FilterDispatcher处理对ActionProxy的请求

5.ActionProxy通过ConfigurationManager查询框架的配置文件,找到需要调用的Action类。在这里,我们通常从 struts.xml 中读取配置。

6.ActionProxy 创建一个 ActionInvocation 的实例。

7.ActionInvocation 实例使用命名方式调用。在Action调用前后,都涉及到Intercepter的调用。

通过上述介绍相信大家对Struts2工作原理已经有所了解,大家如果想了解更多相关知识,可以关注一下星辉的Java视频,里面的课程内容从入门到精通,细致全面,通俗易懂,适合没有基础的小白学习,希望对大家能够有所帮助。

选你想看

你适合学Java吗?4大专业测评方法

代码逻辑 吸收能力 技术学习能力 综合素质

先测评确定适合在学习

在线申请免费测试名额
价值1998元实验班免费学
姓名
手机
提交