首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 网络技术 > 网络基础 >

将Grails的Flash Scope移栽到Struts2

2012-10-13 
将Grails的Flash Scope移植到Struts2原文:http://www.po-soft.com/blog/yongtree/937.html??Web应用程序中

将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.javaJava代码
  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.javaJava代码
  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 

热点排行