浏览 6075 次
锁定老帖子 主题:对struts的一点理解
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2004-05-12
因为1.0比较简单,先从1.0的源码开始看起的,看过之后,虽然有些地方不是很清楚,但大体的框架能够理解了, 其实struts1.0之中使用的技术也不过那些,servlet,jsp,tag,java的内省机制,xml,以及实现国际化的东西。看过 一些介绍struts的东西,国内的大多都是垃圾,英文的还看不懂,开始很郁闷,所以我说英语是多么的重要!用我的理解 方式来说struts是这养的:1客户端发出请求,表现成带有参数的一个串像 abc.do?aa=aa&bb=bb 这里是开始 2struts中只有 一个servlet,请求会被传到这里,他的作用主要有两个,a:改变 session级,servletcontext级,request级 的数据,也就是说 他把从业务逻辑中得到的数据放到这三个地方,想想,就只有这三个地方了吧,然后他会是用servletcontext.getRequestdispather(通过forwardd得到的路径), 跳到一个jsp,这个jsp就是传说中的view,因为数据都是已经是现成的了,被actionservlet放到了三个级别中,所以他的工作就是使用tag显示 这些数据,当然里面需要一些技巧,(写到这里就知道自己的文学水平差啊,我看我写的东西也就自己能看懂,没关系,我不介意^_^)。 我再次说一下一个问题,struts很花稍,但实时上可以抽象成两个servlet(1 actionServlet 2,显示的jsp) 他们之间是通过RequestDispatcher来联系的 第一个是处理数据,将数据放到3个级别的地方,第二个就是用这些数据显示页面,当然之间会有很多枝杈,但大体就是可以这么理解,所以我说struts 不过如此,至少1.0是这样。但是因为我刚入挨踢,做起项目还是很费劲,自己给自己打气吧吧! 说这些都是没用的,你要真正立即struts还要看他的源码,不然本来很垃圾的东西,你会觉得他很神,这些感觉更多是宣传出来的。1.0比较 简单,1.1就相对复杂了,但我想有些思想是相同的,所以我看1.0目的是为了学习1.1,学习1.1是为了做东西,唉,还真麻烦,好了,我就大致 说说struts的流程,再罗索一下,我用的是jb9来看源码的,因为我喜欢点右键有个findDefinition 这样跳转起来很方便。 struts1.0中最重要的应该是ActionServlet,它在org.apache.struts.action下,哦,也不短了, public class ActionServlet extends HttpServlet { 看看这里就知道他是一个servlet,所以应该从public void init() throws ServletException { 这个init方法开始,我简单的介绍一下 initActions(),记住点右键找findDefinition啊,他会初始一个actions ,这个action 是一个protected FastHashMap 看这里: protected FastHashMap actions = new FastHashMap(); 他是在servlet生成的时候就生成的了,我要说一下fasthasmap, 想这种fast** 的东西,你都可以立即成去掉fast后的形式,他只不过是struts自定义的一个集合,有两种形态fast:ture 和fast:false false用在初始化 的时候,这是候使用的是会 synchronized (this)来处理多线程的冲突,这样会比较慢,而ture会使用 synchronized (map)用clone的方法处理, 这个不重要,理解是个hashmap就行了, 接着是initInternal(),他是这样的:internal = MessageResources.getMessageResources(internalName) internal 是 MessageResources 对象,他是实现国际化的那类东西,具体的很麻烦,理解到这就行了,他主要用于servlet内部写日志用的, initDebug(); 调试级别,是从web.xml中读出来的,getServletConfig().getInitParameter("debug");具体的级别我不太清楚,反正不是很重要的东西 然后是 initApplication() 这个方法跟initInternal()只不过他初始化的 MessageResources 是给用户用的,并且放到ServletContext级 看这里: getServletContext().setAttribute(Action.MESSAGES_KEY, application); 这个就是在jsp中用<bean:message>使用到的东西, 接下来是一个非常重要的初始化方法 initMapping()他会从web.xml中读取一些信息比如validating,formBean,forward,但这并不是主要的,主要的是这里 if (validate) digester = initDigester(detail); else digester = initDigesterOld(detail); 这个是让我迷惑过的东西,我们主要看initDigester,另一个差不多,digester是一个解析struts-config.xml内容的东西,当然什么xml都可以, 我们找一段看看就行了: digester.addObjectCreate("struts-config/action-mappings/action", mappingClass, "className"); digester.addSetProperties("struts-config/action-mappings/action"); digester.addSetNext("struts-config/action-mappings/action", "addMapping", "org.apache.struts.action.ActionMapping"); digester.addSetProperty ("struts-config/action-mappings/action/set-property", "property", "value"); 这个是解析actionMapping的代码,都是先这样,最有调用digester.parse(input),input是xml的流 这些add方法都是在添加rule用来在digester.parse(input)用,然后会通过内省调用servlet中的addDataSource addDataSource addForward addMapping 这就实现了从mxl到类的转换。接着是initUpload()这个是初始化上传文件的东西,接着是initDataSources(),1.1中可能不这样用了 他将dataSources中的GenericDataSource 按照key放到servletcontext级中,接着是initOther 主要是做 getServletContext().setAttribute(Action.FORM_BEANS_KEY, formBeans); getServletContext().setAttribute(Action.FORWARDS_KEY, forwards); getServletContext().setAttribute(Action.MAPPINGS_KEY, mappings); 接着是 initServlet,完成将urlpatten(abc.do)放到ServletContext, getServletContext().setAttribute(Action.SERVLET_KEY, servletMapping); 这样init方法玩了,他如要是实现根据struts-config.xml生成formBeans forwards mappings 然后放入servletcontext中, 下面应该是调用servlet的doget和,dopost方法了,但是他们都没有直接实现而是调用了protected void process(HttpServletRequest request, HttpServletResponse response) 这个方法,这个就是ActionServlet的核心方法,在1.1中又被分离了一部分,找到他看看, 这个process中也是在调用很多的process**; 第一个就是processPath(); processLocale(request);....这些都很简单,直到这里processMapping() protected ActionMapping processMapping(String path, HttpServletRequest request) { ActionMapping mapping = findMapping(path); if (mapping == null) mapping = mappings.getUnknown(request); if (mapping != null) request.setAttribute(Action.MAPPING_KEY, mapping); return (mapping); } 先根据path(就是xml action中的path)在mappings中找到特定的ActiongMapping 放到request中,并返回他,这是真正跟你的程序有关的开始, 然后是processActionForm(), processPopulate(formInstance, mapping, request);这个方法就是使用内省将请求的参数放到actionform中去,注意 ActionFormBean,和ActiongForm的区别,ActionFormBean中装的是Actiongform的信息,包括名字,和类的类型,这些都是通过digester从xml中获得的,ActionFormBean是用来创建一个新的actionform的东西,也会使用到内省。然后processValidate() 主要是调用actiongform中的validate,和处理errors request.setAttribute(Action.ERROR_KEY, errors);errors就放在request中,供jsp用,errors是一个HashMap的数据结构的类,key和一个ArrayList, 然后是processForward,processInclude这些是xml中设施相关项,引发的效果一般不用吧,我是很少是forward,和include 然后是processActionCreate(),如果action存在,就从actions通过action的类名查到相应的实例,没有,创建。 action只不过是servlet中的类而已,只不过传了几个重要的参数,就显得很牛×, 然后是: ActionForward forward = processActionPerform(actionInstance, mapping, formInstance, request, response); 这个方法很熟悉了完成处理数据,和返回ActionForward,(人家都说起到控制调度模块,和跳转页面,我太俗了)ActionForward其实就是个路径!去看看他的定义,很简单。最后就是processActionForward()有两种跳转方式 response.sendRedirect(response.encodeRedirectURL(path));//request中的东西没有了 rd.forward(request, response);//request中的东西保存 就这样条转到了一个相应的jsp去了 再然后,就应该是servlet的生命周期方法destroy()了 public void destroy() { if (debug >= 1) log(internal.getMessage("finalizing")); destroyActions(); destroyApplication(); destroyDataSources(); destroyInternal(); } 这里的东西都很简单。 总结一下,struts是这样的,一开始,通过xml初始化,生成formBeans forwards mappings 等,放到相应的位置,然后再process中,得到ActionMapping, 通过ActiongMapping调用processActionForm(mapping, request);得到ActionForm,然后组装参数,然后是 processActionCreate()获得action,然后调用 processActionPerform得到Actionforward(找到path,用于作为Dispatcher的参数) 最后是processActionForward()跳转走,就这样完了, 再说说用到的类,ActionServlet就是一个普通的servlet,action是servlet中的类,目的是调用模块,以及得到返回页,actiongMapping是个内容很多的东西, 1.0中放在actionMappings中,(actionMappings是个集合),actionforward主要是存放路径信息,actionform可以理解成一个bean,struts页面显示的数据来源, 都喜欢用bean的形式。 希望一边看源码一遍看我的垃圾,如果我们心灵相同,我想你会找到点东西的,没有看到有人贴过介绍源码的贴,我希望研究struts的前辈能够写点心得,或者帮忙, 修改,看再多的文档也不如show me the code!!! 我很弱,但是我很喜欢看真实的东西,这样才能变强,java是很不好入手,尤其是像我这样英文很烂的人,真是 太痛苦了,我说的东西很肤浅,但是思路还是很清晰,起码我看的懂,现在想想为什么还单身啊,表达能力太弱了, 虽然我的贴是垃圾,但是我很喜欢,就当作,一个总结吧,我会接着看1.1,如果水平有提高,会接着贴新的, 我们poper的信念就是不怕BT,越B越勇; 在这里宣传一下POP:http://pop.pcpop.com 欢迎加入神族 by:show me the code 2004-5-12 11:31:33 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2004-05-12
http://www.cn-java.com/target/news.php?news_id=2684
我去年写的一篇,可能也是你眼中的垃圾。呵呵 |
|
返回顶楼 | |
发表时间:2004-05-12
孤魂的文章是去年才写的吗?
我记得很早以前就读过了。:) 受益匪浅。 今天看完lq8202的帖子,就看到你的跟贴, 就又读了一遍,感觉还是受益匪浅。 lq8202的文章写的也不错, 特别是不用担心别人看不懂,我看了,很明白。 不过我推荐你也读读孤魂的那篇文章。 在很多Struts源码的工作机理上阐述的相当清楚。 也感激把自己的理解和经验拿出来和别人分享。 可以给人一个基本的概貌。 不过很多问题上,还要知其然也知其所以然。 记得我读孤魂的那篇文章的时候, 正在做一个和Sturts类似的框架, 从Struts里吸取了Processer的设计和异常处理机制 一种技术所以流行,不是全靠宣传, 只了解Struts是怎么流程的是不够的, 而要了解它技术上比别人优势的地方。 比如现在大家都觉得webwork比struts要好, 你会发现它们的原理和流程几乎是一样的, 那么,好在哪里了呢? 呵呵!读孤魂的文章时候,我对Struts知之甚少, 所以有很多东西读不懂,而读你的文章的时候, 已对其有相当的了解,所以收获自然不如当年大, 但这并不说明你的文章不好,就如同不能因为我 读不懂就说他的表达能力比你差一样。:) 另外问一句题外话:孤魂是在加拿大吗? |
|
返回顶楼 | |
发表时间:2004-05-12
我也忘记了是什么时候写的,写了很久才在chinajavaworld.net放了上去。应该在2002年底写的吧。
BTW:我在广州。 |
|
返回顶楼 | |
发表时间:2004-05-19
最近一直比较懒没有上网,没想到能看到楼上的两位大哥的回复^_^
小弟是今年6月毕业,刚接触java很短,所以脸皮才这么厚,发了这个烂贴,楼上的东西一定好好拜读,这么好的东西怎么都没有好好宣传,上面的大哥说的对,只知道流程是不够的,但知道流程应该是第一步,对不? 这个论坛的人都很强,佩服,以后要多给宣传。 |
|
返回顶楼 | |
发表时间:2004-05-19
有问题还要向各位请教
|
|
返回顶楼 | |