Struts原理

很多人都认为Struts很难,事实上struts也并不简单,有些时候通过几个Action + ActionForm是能完成一个Struts项目的配置,但效果不等于掌握,否则helloworld的人也能说他掌握了Java. 不过如果通过Struts的核心原理来剖析的话,它也不怎么难了.
我相信很多人单独用JSP可以做出一个非常出色的web项目,通过jsp和servlet以及javabean也能自己实现MVC,但搞到struts下就不行了,为此,很多人都觉得struts很难,但是我们要明白struts也是基于以上技术实现了,既然我们能掌握底层技术,那么换到struts上来就没有理由不能掌握.
struts的处理步骤是:
    1.首先通过ActionServlet的 url-pattern属性将所有".do"的请求拦截.
    2.打开ActionServlet的源码可以发现,它的process方法很简单,只是调用RequestProcessor的process方法,把自己的request和response传给RequestProcessor的process方法,从而实现业务委托.而RequestProcessor是哪来的呢?打开struts的配置文件,会发现里面的<controller>节点里定义的className就是对RequestProcessor的定义.
    3.RequestProcessor的process方法这时会创建ActionMapping对象(根据<actionMappings>下的<action>建立),如果存在当前请求路径可以创建一个ActionMapping对象,则返回这个对象,否则就报404错误,比如请求的是 /hello.do,那么在创建ActionMapping对象时就会去找<action里的path为"/hello">的,如果找到了,就创建ActionMapping对象,找不到就抱 HTTP 404;  
4. 创建ActionForm对象, 从3里创建的ActionMapping对象取得当前ActionForm的名称,根据type创建一个ActionForm对象(如果其存在,就不创建).
5.通过3中的ActionMapping对象创建Action对象,并调用它的execute方法.
6.通过3中的actionMapping对象创建Actionforward对象(事实上是个Map).

以上是Struts的工作原理,很多时候,Actionform的子类里都要有reset方法,如果我们在reset方法里用System.out.println()打出一个调试语句的话,那么在Action的execute方法执行后,我们会发现该调式语句一共打了2次, 原因就是:在上面4中建立ActionFOrm对象时,调用了reset一次, 在Action里取得ActionForm对象时又调用了reset一次,所以结果是2次。这也从另外一方面印证了struts的处理过程.

另外,对struts对<html:form>的解析也是一个很重要的点,它的原理是: 首先加载Form,然后Action从Form里取得数据并在Forward时给这个Form赋值并解析标签,然后生成响应. 我曾经就遇到过这样的一种情况.
a.jsp  
   ... <html:form action="/hello">...</html:form>.....

   b.jsp :
    <script> location.href = "/a.jsp"</script>

我这样href到a.jsp却发现a.jsp的代码解析到<form>这里就没有了,当时百思不得其解,后来结合struts原理,就很容易解决了.
原来问题在: 当struts框架没有取到这个ActionForm,所以在解析form标签的时候失败,但最后我把代码一改:   location.href = "/hello.do"; 而hello.do里将页面流转到a.jsp,最后页面就正常被解析出来了.以上也说明了 struts在解析页面form的时候的原理.

以上问题在单模块下遇到的几率还比较小,但到了多模块下就比较多了,而对多模块的配置,也有几个地方很容易出错,下面是我在此的一点小经验.
   1. 在web.xml里配置多模块
<servet>
<servlet-name> action</servlet>
<servlet-class>.....</servlet-class>
<init-param>
       <param-name>config</param-name> <!--默认模块-->
       <param-value>/WEB-INF/struts-config.xml</param-value>
</init-param>

<init-param>
       <param-name>config/mclaren</param-name> <!--自定义模块-->
       <param-value>/WEB-INF/struts-mclaren-config.xml</param-value>
</init-param>
<!-- 其他模块依次类推-->
</servlet>

以上注意 :在自定义模块的时候,如果config/mclaren,那么一定要在webRoot下有mclaren这个文件夹,它下面是该模块的内容,如果是config/123,则该文件夹一定要是123,依次类推..

另外,。struts要求所有导航都经过它,所以我们必须强制要求自己在开发时候遵循这一原则,这样一来,也避免了上面出现form不能解析的问题.

而对于实际调用效果,就和大家平时做的没什么两样了, 在action了通过业务接口调业务层的东西,但掌握了struts原理,再回头搞JavaWeb这一块,应该是小菜一叠了..

你可能感兴趣的:(Struts原理)