SSH-Struts(一)实现过程

来源:互联网 发布:赛嘉电动牙刷 知乎 编辑:程序博客网 时间:2024/05/22 16:53

       Struts2是基于WebWork提出的MVC框架,相对于Struts1做出了巨大改变,但与WebWork实现框架是一致的。作为MVC的一个框架模式实现,继承了MVC将数据输入,处理,输出分离的特点。


                   

    

     通过上面的Struts结构图,我们分析Struts2的实现过程:


     (1)用户在web页面发出http请求,到达一个servlet(服务器端java程序)容器(可以为tomcat)

 

     (2)经过一系列过滤器后到达FilterDispatcher,通过ActionMapper查询决定调用Action;


     (3)将处理交给ActionProxy,通过访问configuration manager的配置文件,找到调用的Action类;


     (4)由ActionProxy创建一个ActionInvocation


     (5)ActionInvocation实例使用命名模式(例如配置文件的name对应相应的java Action类)来调用,期间涉及到相应的拦截器(Intercepter)的调用


     (6)Action执行完毕,ActionInvocation负责根据Struts.xml中的配置找到对应的返回结果。


    源码分析:


    (1)用户请求到达servlet请求,通过配置web.xml找到相应的FilterDispather过滤器实现类:

<filter>  <filter-name>struts2</filter-name>  <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>  </filter>    <filter-mapping>  <filter-name>struts2</filter-name>  <url-pattern>/*</url-pattern></filter-mapping>

    FilterDispatcher实现了Filter和StrutsStatics接口,StrutsStatics接口是一些对相关接口封装的常量,例如HttpServletRequest,HttpServletResponse等,实例化StrutsPrepareAndExecuteFilter类后,执行init(FilterConfig filterConfig)方法,该方法调用CreateDispatcher后将页面参数传入DisPather对象中:


/**     * Create a {@link Dispatcher}     */    private Dispatcher createDispatcher( HostConfig filterConfig ) {        Map<String, String> params = new HashMap<String, String>();        for ( Iterator e = filterConfig.getInitParameterNames(); e.hasNext(); ) {            String name = (String) e.next();            String value = filterConfig.getInitParameter(name);            params.put(name, value);        }        return new Dispatcher(filterConfig.getServletContext(), params);    }

    页面发送请求则调用doFilter方法,该方法对请求对象进行重新包装requst,通过ActionMapper的getMapping()方法得到请求的Action。

 public ActionMapping findActionMapping(HttpServletRequest request, HttpServletResponse response, boolean forceLookup) {        ActionMapping mapping = (ActionMapping) request.getAttribute(STRUTS_ACTION_MAPPING_KEY);        if (mapping == null || forceLookup) {            try {                mapping = dispatcher.getContainer().getInstance(ActionMapper.class).getMapping(request, dispatcher.getConfigurationManager());                if (mapping != null) {                    request.setAttribute(STRUTS_ACTION_MAPPING_KEY, mapping);                }            } catch (Exception ex) {                dispatcher.sendError(request, response, servletContext, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, ex);            }        }        return mapping;    }


public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {        HttpServletRequest request = (HttpServletRequest) req;        HttpServletResponse response = (HttpServletResponse) res;        try {            prepare.setEncodingAndLocale(request, response);            prepare.createActionContext(request, response);            prepare.assignDispatcherToThread();if ( excludedPatterns != null && prepare.isUrlExcluded(request, excludedPatterns)) {chain.doFilter(request, response);} else {request = prepare.wrapRequest(request);ActionMapping mapping = prepare.findActionMapping(request, response, true);//获得Action信息,包含struts2.xml里面的信息:name,包名称,方法名称if (mapping == null) {boolean handled = execute.executeStaticResourceRequest(request, response);if (!handled) {chain.doFilter(request, response);}} else {execute.executeAction(request, response, mapping);//执行Action的excute方法}}        } finally {            prepare.cleanupRequest(request);        }    }

   (2)Struts2.xml的配置文件如下:


<struts><!--struts2的action必须放在指定的宝空间下定义--><package name="strutsqs" extends="struts-default"><action name="login" class="lee.LoginAction"><result name="error">/error.jsp</reuslt><result name="success">/welcome.jsp</result></action><package></struts>


    以上的源码跟踪到达excuteAction方法后,就不知道到哪个方法重写该方法了,跟之前的struts2版本有出入,至于是如何调用的ActionProxy,待后续研究!


0 0