框架-struts2

一:struts2概要
    以WebWork优秀设计思想为核心,吸收了struts1的部分优点。

二:struts2详解
    主要就是详解struts2与struts1之间的区别,以及为什么要采用webwork重新设计新框架,以及吸收了struts1的哪部分优点。
    首先将区别:
  •     最大的区别是与servlet成功解耦,不在依赖容器来初始化HttpServletRequest和HttpServletResponse
    struts1里依赖的核心控制器为ActionServlet而struts2依赖ServletDispatcher,一个是servlet一个是filter,正是采用了filter才不至于和servlet耦合,所有的数据 都是通过拦截器来实现,如下图显示:
    

  •     web层表现层的丰富,struts2已经可以使用jsp、velocity、freemarker
  •     线程模式方面:struts1的action是单例模式而且必须是线程安全或同步的,是struts2的action对每一个请求都产生一个新的实例,因此没有线程安全问       题。
  •     封装请求参数:是struts1采用ActionForm封装请求参数,都必须继承ActionForm基类,而struts2通过bean的属性封装,大大降低了耦合。
  •     类型转换:struts1封装的ActionForm都是String类型,采用Commons- Beanutils进行类型转换,每个类一个转换器;struts2采用OGNL进行类型转       换,支持基本数据类型和封装类型的自动转换。
  •     数据校验:struts1在ActionForm中重写validate方法;struts2直接重写validate方法,直接在action里面重写即可,不需要继承任何基类,实际的调用顺序是,validate()-->execute(),会在执行execute之前调用validate,也支持xwork校验框架来校验。
    其次,讲一下为什么要采用webwork来重新设计struts2
          
首先的从核心控制器谈起,struts2的FilterDispatcher,这里我们知道是一个filter而不是一个servlet,讲到这里很多人还不是很清楚web.xml里它们之间的联系,先简短讲一下它们的加载顺序,context-param(应用范围的初始化参数)-->listener(监听应用端的任何修改通知)-->filter(过滤)-->servlet。
    filter在执行servlet之间就以及调用了,所以才有可能解脱完全依赖servlet的局面,那我们来看看这个filter做了什么事情:
    /**
     * Process an action or handle a request a static resource.
     * <p/>
     * The filter tries to match the request to an action mapping.
     * If mapping is found, the action processes is delegated to the dispatcher's serviceAction method.
     * If action processing fails, doFilter will try to create an error page via the dispatcher.
     * <p/>
     * Otherwise, if the request is for a static resource,
     * the resource is copied directly to the response, with the appropriate caching headers set.
     * <p/>
     * If the request does not match an action mapping, or a static resource page,
     * then it passes through.
     *
     * @see javax.servlet.Filter#doFilter(javax.servlet.ServletRequest, javax.servlet.ServletResponse, javax.servlet.FilterChain)
     
*/
    
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {

        HttpServletRequest request 
= (HttpServletRequest) req;
        HttpServletResponse response 
= (HttpServletResponse) res;
        ServletContext servletContext 
= getServletContext();

        String timerKey 
= "FilterDispatcher_doFilter: ";
        
try {

            
// FIXME: this should be refactored better to not duplicate work with the action invocation
            ValueStack stack = dispatcher.getContainer().getInstance(ValueStackFactory.class).createValueStack();
            ActionContext ctx 
= new ActionContext(stack.getContext());
            ActionContext.setContext(ctx);

            UtilTimerStack.push(timerKey);
            request 
= prepareDispatcherAndWrapRequest(request, response);
            ActionMapping mapping;
            
try {
                mapping 
= actionMapper.getMapping(request, dispatcher.getConfigurationManager());
            } 
catch (Exception ex) {
                log.error(
"error getting ActionMapping", ex);
                dispatcher.sendError(request, response, servletContext, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, ex);
                
return;
            }

            
if (mapping == null) {
                
// there is no action in this request, should we look for a static resource?
                String resourcePath = RequestUtils.getServletPath(request);

                
if ("".equals(resourcePath) && null != request.getPathInfo()) {
                    resourcePath 
= request.getPathInfo();
                }

                
if (staticResourceLoader.canHandle(resourcePath)) {
                    staticResourceLoader.findStaticResource(resourcePath, request, response);
                } 
else {
                    
// this is a normal request, let it pass through
                    chain.doFilter(request, response);
                }
                
// The framework did its job here
                return;
            }

            dispatcher.serviceAction(request, response, servletContext, mapping);
//过滤用户请求,拦截器执行,把对应的action请求转到业务action执行        } 

finally {
            
try {
                ActionContextCleanUp.cleanUp(req);
            } 
finally {
                UtilTimerStack.pop(timerKey);
            }
        }
    }
    对应的action参数由拦截器获取。
    解耦servlet是struts2采用webwork思路的最重要的一个原因,也迎合了整个技术的一个发展方向,解耦一直贯穿于整个框架。
        

posted on 2012-02-27 17:07 陈睿 阅读(1636) 评论(2)  编辑  收藏 所属分类: 框架

评论

# re: 框架-struts2 2012-02-27 22:28 todayx.org

不错

历史上的今天
回顾历史的今天,历史就像生活的一面镜子;可以了解历史的这一天发生的事件;借古可以鉴今;历史是不能忘记的.要记住历史的每一天
http://www.todayx.org/  回复  更多评论   

# re: 框架-struts2 2012-02-28 09:13 tb

讲解的不错   回复  更多评论   


只有注册用户登录后才能发表评论。


网站导航:
 

导航

<2012年2月>
2930311234
567891011
12131415161718
19202122232425
26272829123
45678910

统计

常用链接

留言簿

随笔分类

随笔档案

搜索

最新评论

阅读排行榜

评论排行榜