`
yongtree
  • 浏览: 233918 次
  • 性别: Icon_minigender_1
  • 来自: 青岛
社区版块
存档分类
最新评论

将Grails的Flash Scope移植到Struts2

阅读更多

原文:http://www.po-soft.com/blog/yongtree/937.html

  Web 应用程序中一个常见的用法是,先对请求进行处理然后将请求重定向到另外一个控制器、servlet或其他对象。这种做法本身没什么问题,但是当请求被重定向时它会创建一个崭新的request,并将原本保存在request属性中的数据全都清除掉,因此重定向的目标操作就无法再获得这些数据。当我们使用struts2的actionmessage的时候,遇到重定向,这些消息全都over了。

有些开发者为了避免上述情况的发生而将这些信息保存在session中。这种做法很好,但开发人员会经常忘记清除临时数据,并且需要开发人员自行维护session的状态。无疑增加了程序的开发的复杂性和无畏的性能浪费。
为了解决这个问题,Grails模仿Rails引入了Flash Scope。flash对象只将数据保存在下一次的请求中,在下一次请求之后会自动清除其中的数据。这样不仅减小了开发人员的负担,也使我们能够专注于当前的问题而不用担心其他问题。
Flash 作用域的确可以很好的解决这个问题,可惜我们常用的SSH框架中,却一直缺少这样一个作用域,不知道Struts2的开发者能不能在以后的版本中增加这样的一个功能。等不了他了,还是我们自己手工创造这样一个对象来解决现有的问题吧。
最简单的办法,就是将Grails的实现移植到Struts2中。
首先我们下载Grails的源代码包,并找到Flash对象,将其实现按步照班的移植到struts2中。主要修改主要包括两个部分。第一是将Grails的request上下文改成struts2的;第二删掉我们不适用的Grails对错误信息的处理。
下面就开始简单的介绍修改后的程序,主要有三个类。
第一我们定义一个Flash对象的接口:FlashScope.java
   
Java代码
  1. public   interface  FlashScope  extends  Map, Serializable {   
  2.        
  3.      /**   
  4.      * 设置一个flash作用域经过新的请求到下个状态。   
  5.      */   
  6.      void  next();   
  7.     
  8.      /**   
  9.      * 返回flash对象现有的状态,如果你不希望在下面的请求中使用包含的变量。   
  10.      *    
  11.      * @return A map   
  12.      */   
  13.     Map getNow();   
  14. }   
第二开始编写该接口 Struts2 的实现: StrutsFlashScope.java
Java代码
  1. public   class  StrutsFlashScope  implements  FlashScope {   
  2.     
  3.      private  Map current =  new  ConcurrentHashMap();   
  4.      private  Map next =  new  ConcurrentHashMap();   
  5.      public   static   final  String FLASH_SCOPE =  "com.posoft.web.servlet.FLASH_SCOPE" ;   
  6.     
  7.      public  StrutsFlashScope() {   
  8.     }   
  9.     
  10.      public   void  next() {   
  11.        current.clear();   
  12.        current =  new  ConcurrentHashMap(next);   
  13.        next.clear();   
  14.     }   
  15.     
  16.      public  Map getNow() {   
  17.         return  current;   
  18.     }   
  19.     
  20.      public   int  size() {   
  21.         return  current.size() + next.size();   
  22.     }   
  23.     
  24.      public   void  clear() {   
  25.        current.clear();   
  26.        next.clear();   
  27.     }   
  28.     
  29.      public   boolean  isEmpty() {   
  30.         return  size() ==  0 ;   
  31.     }   
  32.     
  33.      public   boolean  containsKey(Object key) {   
  34.         return  (current.containsKey(key) || next.containsKey(key));   
  35.     }   
  36.     
  37.      public   boolean  containsValue(Object value) {   
  38.         return  (current.containsValue(value) || next.containsValue(value));   
  39.     }   
  40.     
  41.      public  Collection values() {   
  42.        Collection c =  new  ArrayList();   
  43.        c.addAll(current.values());   
  44.        c.addAll(next.values());   
  45.         return  c;   
  46.     }   
  47.     
  48.      public   void  putAll(Map t) {   
  49.         for  (Map.Entry<Object, Object> entry : ((Map<Object, Object>) t)   
  50.               .entrySet()) {   
  51.            put(entry.getKey(), entry.getValue());   
  52.        }   
  53.     }   
  54.     
  55.      public  Set entrySet() {   
  56.        Set keySet =  new  HashSet();   
  57.        keySet.addAll(current.entrySet());   
  58.        keySet.addAll(next.entrySet());   
  59.         return  keySet;   
  60.     }   
  61.     
  62.      public  Set keySet() {   
  63.        Set keySet =  new  HashSet();   
  64.        keySet.addAll(current.keySet());   
  65.        keySet.addAll(next.keySet());   
  66.         return  keySet;   
  67.     }   
  68.     
  69.      public  Object get(Object key) {   
  70.         if  (next.containsKey(key))   
  71.             return  next.get(key);   
  72.         return  current.get(key);   
  73.     }   
  74.     
  75.      public  Object remove(Object key) {   
  76.         if  (current.containsKey(key))   
  77.             return  current.remove(key);   
  78.         else   
  79.             return  next.remove(key);   
  80.     }   
  81.     
  82.      public  Object put(Object key, Object value) {   
  83.         // create the session if it doesn't exist    
  84.        registerWithSessionIfNecessary();   
  85.         if  (current.containsKey(key)) {   
  86.            current.remove(key);   
  87.        }   
  88.     
  89.         if  (value ==  null )   
  90.             return  next.remove(key);   
  91.         else   
  92.             return  next.put(key, value);   
  93.     }   
  94.     
  95.        
  96.     
  97.      private   void  registerWithSessionIfNecessary() {   
  98.        Map<String, Object> session = ActionContext.getContext().getSession();   
  99.         if  (session.get(FLASH_SCOPE) ==  null )   
  100.            session.put(FLASH_SCOPE,  this );   
  101.           
  102.     }   
  103.     
  104. }   
这个实现很好理解,无非内部定义了两个 Map ,将保存在里面的数据,在两个 Map 里来回的转移,这样就保证在下一次重定向请求时,我们只需要将其中一个 Map 的数据转移到另外一个 Map 中,而清楚掉一个 Map 。这样就保证在重定向时,该作用域下依然保存数据。而在第二次的请求时,如果没有新的数据加进来,原来的数据将会被清空。通过这种方式, Flash 的作用域的数据只能保持在下一次的重定向请求中。
第三步也是很关键的一步,如果我们不去清理该作用域下的数据,那么这个作用域就无法达到应有的效果。这就需要我们在每次重定向的时候要执行作用域的 next() 方法,来清理数据。
我们编写的是 Struts2 的实现,我们就需要在 Struts2 的过滤器中植入对 Flash Scope 处理的操作。看 OecpStruts2FilterDispatcher.java
Java代码
  1. public   class  OecpStruts2FilterDispatcher  extends  StrutsPrepareAndExecuteFilter {   
  2.      @Override   
  3.      public   void  doFilter(ServletRequest req, ServletResponse res,   
  4.            FilterChain chain)  throws  IOException, ServletException {   
  5.        HttpServletRequest request = (HttpServletRequest) req;   
  6.        HttpServletResponse response = (HttpServletResponse) res;   
  7.             try  {   
  8.               prepare.setEncodingAndLocale(request, response);   
  9.               prepare.createActionContext(request, response);   
  10.               prepare.assignDispatcherToThread();   
  11.                if  (excludedPatterns !=  null   
  12.                      && prepare.isUrlExcluded(request, excludedPatterns)) {   
  13.                   chain.doFilter(request, response);   
  14.               }  else  {   
  15.                   request = prepare.wrapRequest(request);   
  16.                   ActionMapping mapping = prepare.findActionMapping(request,   
  17.                          response,  true );   
  18.                    if  (mapping ==  null ) {   
  19.                       boolean  handled = execute.executeStaticResourceRequest(   
  20.                              request, response);   
  21.                       if  (!handled) {   
  22.                          chain.doFilter(request, response);   
  23.                      }   
  24.                   }  else  {   
  25.                       /**   
  26.                       * 更新flash作用域   
  27.                       */   
  28.                      FlashScope fs = (FlashScope) ActionContext.getContext()   
  29.                             .getSession().get(StrutsFlashScope.FLASH_SCOPE);   
  30.                       if  (fs !=  null ) {   
  31.                          fs.next();   
  32.                      }   
  33.                      execute.executeAction(request, response, mapping);   
  34. margin: 0px; padding: 0
    0
    0
    分享到:
    评论
    2 楼 freezingsky 2012-10-27  
    这个解决方案极好,之前也曾想过这类问题的解决方法。但明显不如此方法!
    1 楼 xzcgeorge 2012-09-16  
     

相关推荐

    grails2

    grails-2

    the definitive guide to grails 2

    《Grails 2 的终极指南》是一本深入探讨Grails框架精髓的专业书籍,该书以英文撰写,旨在为读者提供全面、深入的Grails框架学习资料。Grails框架基于Groovy语言,是一种高度动态、敏捷的Java应用开发框架,它简化了...

    Grails Grails Grails

    2. **GORM(Grails Object Relational Mapping)**: GORM 是Grails的ORM框架,提供了与数据库交互的能力,支持关系型数据库,如MySQL、PostgreSQL等。它提供了CRUD操作,以及事务管理和动态查询。 3. **插件系统**...

    Eclipse下搭建Grails项目

    - 安装完成后,确保设置`GRAILS_HOME`环境变量,并将其路径添加到系统的`PATH`变量中,确保这两个变量都在同一级别(用户级或系统级)。 - 打开命令行,输入`grails`,如果显示帮助信息,表明Grails已成功安装。 ...

    grails-3.0.5-ga (2/2)

    以下是关于"grails-3.0.5-ga (2/2)"的详细知识点: 1. **Groovy语言**: Grails框架是用Groovy语言编写的,这是一种动态、面向对象的编程语言,与Java高度兼容,但语法更加简洁和灵活。 2. **MVC架构**: Grails遵循...

    Grails权威指南 Grails权威指南

    2. **MVC架构**:Grails采用MVC模式组织应用程序,将业务逻辑、用户界面和数据访问分离,有利于团队协作和代码复用。在Grails中,Controller处理请求,View呈现结果,Model则存储和管理业务数据。 3. **GORM...

    grails中文入门简介

    Grails的URL映射系统使得可以灵活地将请求映射到控制器、视图和操作。而WebFlow则提供了一种高级的Web导航流程。 验证是Web开发中不可或缺的一部分,Grails通过声明约束和验证约束来实现。它支持客户端验证,使得...

    grails-用户手册

    这份用户手册将帮助你深入理解和高效使用Grails。 一、Grails基础 Grails的核心理念是“约定优于配置”,这意味着它有一套默认的规则和结构,减少了开发者在项目初始化阶段的工作量。例如,项目文件结构、数据库...

    eclipse开发grails插件

    2. **安装Grails插件**:有了GroovyEclipse的支持,我们还需要安装Grails插件。同样地,可以通过Eclipse的"Help" -&gt; "Install New Software",添加Grails插件的更新站点(如:...

    grails login

    Grails的环境配置通常包括设置GRAILS_HOME路径以及将其添加到系统的PATH变量中。 **2. 创建新项目** 使用Grails命令行工具创建一个新的Grails应用,例如`grails create-app loginDemo`。这将在指定目录下生成一个...

    grails脚手架2次优化

    本文将深入探讨如何对Grails脚手架进行二次优化,以提升应用的功能和用户体验。 一、理解Grails脚手架的工作原理 Grails的脚手架基于GORM(Grails Object Relational Mapping)和Groovy模板引擎,通过解析Domain ...

    grails-2.4.4.zip

    这个压缩包“grails-2.4.4.zip”包含了完整的Grails 2.4.4版本,使得开发者可以直接将其集成到IDE中,快速地开始项目开发工作。 1. **Grails框架概述** Grails 是一个遵循MVC(模型-视图-控制器)架构模式的全栈...

    [Grails] Grails 2 权威指南 (英文版)

    [Apress] Grails 2 权威指南 (英文版) [Apress] The Definitive Guide to Grails 2 (E-Book) ☆ 出版信息:☆ [作者信息] Jeff Scott Brown, Graeme Rocher [出版机构] Apress [出版日期] 2013年01月23日 ...

    Grails1.1中文文档

    11. **部署**:最后,文档会介绍如何将Grails应用部署到不同的服务器环境,如Tomcat、Jetty等。 通过阅读这份《Grails 1.1 中文文档》,开发者能够全面理解Grails框架的架构、工作原理和最佳实践,从而高效地开发出...

    The definitive guide to grails 2 英文版 书 代码

    随书附带的代码库"The_definitive_guide_to_Grails2_code.zip"包含了书中示例项目的源代码,这有助于读者通过实际操作加深对理论知识的理解。读者可以按照书中的指导运行这些代码,跟随作者的脚步逐步学习Grails开发...

    grails中文参考手册

    - **创建一个Grails应用**:使用`grails create-app`命令可以快速创建一个新的Grails应用,这将生成基本的项目结构。 - **Hello World示例**:在新创建的应用中,你可以通过创建一个简单的控制器和视图来实现经典...

    grails 中文文档+grails-fckeditor-0.9.5.zip插件

    FCKEditor是一款著名的在线文本编辑器,grails-fckeditor-0.9.5插件则是将其集成到Grails应用中的解决方案。以下是关键点: 1. 安装与配置:在Grails项目中添加插件依赖,然后通过配置文件调整编辑器的参数,如默认...

    Groovy和Grails配置方法

    解压后,将`grails-bin-1.0.4`目录重命名为`grails-1.0.4`并放置于期望的位置,例如`C:\grails-1.0.4`。同样地,需要配置系统环境变量: - `GRAILS_HOME`:设置为Grails安装目录,例如`C:\grails-1.0.4`。 - `path`...

Global site tag (gtag.js) - Google Analytics