当前位置: 代码迷 >> Web前端 >> 框架初试,一个粗略mvc框架。仿照webwork
  详细解决方案

框架初试,一个粗略mvc框架。仿照webwork

热度:416   发布时间:2012-11-21 08:23:25.0
框架初试,一个粗略mvc框架。模仿webwork

我写的这个框架大致模仿webwork的原理。我只用过webwork一个框架,当然模仿它了^^

主要是为了学习,苦思冥想写出来了。把它帖出来,大家多给我一些意见。

在我的框架里面出现大量的sophie是我的名字,呵呵,女性写的代码命名也比较女性化吧*^_^*

?

Sophie的web框架
主要思路
Init配置文件-》dispatcher调度-》invocation执行action=》result处理结果,显示页面
?
主要功能部分
1.?????? 调度器,在启动服务的时候调用init方法,初始化action的配置文件。保存servlet的内容到SophieContext 中dispatcher
2.?????? 和resultConfiguration模型,把配置文件中的action信息,封装到一个configration类中。多个action信息组成一个map。每个action的result信息,封装到resultConfiguration中,多个result组成一个map.configuration
3.?????? 类。逻辑的东西可以写在action中。Action类从servlet中分离出来。专注与逻辑本身。提供给框架的使用者。action
4.?????? 保存context的类。里面有个静态的map。SophieContext
5.?????? 执行actionSophieInvocation
6.?????? 处理action执行的结果,根据resultConfiguration里的配置,转向显示页面。sophieResult
7.?????? 标签,可以在页面上用标签调用actionActionTag action
代码详细说明

1)SophieDispatcher是一个servlet,init()方法中初始化一些配置文件。

service()方法中执行action

?

SophieDispatcher 代码
  1. package?com.sophie.dispatcher; ??
  2. ??
  3. import?java.io.IOException; ??
  4. import?java.util.HashMap; ??
  5. import?java.util.Iterator; ??
  6. import?java.util.Map; ??
  7. import?java.util.Set; ??
  8. ??
  9. import?javax.servlet.ServletConfig; ??
  10. import?javax.servlet.ServletContext; ??
  11. import?javax.servlet.ServletException; ??
  12. import?javax.servlet.http.HttpServlet; ??
  13. import?javax.servlet.http.HttpServletRequest; ??
  14. import?javax.servlet.http.HttpServletResponse; ??
  15. ??
  16. import?com.sophie.context.ConfigUtil; ??
  17. import?com.sophie.context.Configuration; ??
  18. import?com.sophie.context.SophieContext; ??
  19. import?com.sophie.parameter.Parameter; ??
  20. ??
  21. public?class?SophieDispatcher?extends?HttpServlet?{ ??
  22. ????@Override??
  23. ????protected?void?service(HttpServletRequest?request,?HttpServletResponse?response)?throws?ServletException,?IOException?{ ??
  24. ????????/* ?
  25. ?????????*?因为进入该servlet的不是来至对该servelt本身的请求,(eg:test.action)所以这里用getServletConfig()得不到ServletConfig,从而无法得到ServletContext ?
  26. ?????????*保存servlet中的信息到自己定义的SophieContext对象中,备用 ?
  27. ?????????*/??
  28. ????????Map?parametersMap=request.getParameterMap(); ??
  29. ????????setParamtersMap(request,?parametersMap); ??
  30. ????????SophieContext.setRequest(request); ??
  31. ????????SophieContext.setResponse(response); ??
  32. ???????? ??
  33. ????????//根据url得到actionName ??
  34. ????????String?actionName=getActionName(request); ??
  35. ???????? ??
  36. ????????//执行action ??
  37. ????????SophieInvocation?invocation=new?SophieInvocation(actionName); ??
  38. ????????String?resultString=invocation.execute(); ??
  39. ????????ResultDispatcher?resultDispatcher=new?ResultDispatcher(invocation.getResultConfigMap(),resultString); ??
  40. ????????resultDispatcher.Dispatcher(); ??
  41. ????} ??
  42. ???? ??
  43. ????@Override??
  44. ????/* ?
  45. ?????*?init?sophieContext ?
  46. ?????*/??
  47. ????public?void?init(ServletConfig?config)?throws?ServletException?{ ??
  48. ????????ServletContext?context=config.getServletContext(); ??
  49. ????????/* ?
  50. ?????????*?更改于2007-5-10 ?
  51. ?????????*?1.把备置文件读出以后保存在对象里面,而不再是数组里面 ?
  52. ?????????*?2.把配置文件的map保存在sophieContext里面而不是servletContext里面 ?
  53. ?????????*??init?the?action?and?result?map? ?
  54. ?????????*?Map?map=new?HashMap(); ?
  55. ?????????*?map=PropertiesUtil.convertPropertyFileToMap(PropertiesUtil.ACTION_PROPERTIES); ?
  56. ?????????*?context.setAttribute(SophieStatic.ACTION_RESULT_MAP,?configMap); ?
  57. ?????????*/??
  58. ??
  59. ????????Map?configMap=new?HashMap(); ??
  60. ????????configMap=ConfigUtil.initConfigurationMap(); ??
  61. ???????? ??
  62. ????????SophieContext.setServletContext(context); ??
  63. ????????SophieContext.setConfigurationMap(configMap); ??
  64. ????????System.out.println("===init===="); ??
  65. ????} ??
  66. ???? ??
  67. ????//把parameter放到一个map中并存入SophieContext的map中备用 ??
  68. ????private?void?setParamtersMap(HttpServletRequest?request,Map?parametersMap){ ??
  69. ????????Parameter?parm=new?Parameter(); ??
  70. ????????Set?entrySet=parametersMap.entrySet(); ??
  71. ????????Map?map=new?HashMap(); ??
  72. ????????for?(Iterator?iter?=?entrySet.iterator();?iter.hasNext();)?{ ??
  73. ????????????Map.Entry?entry=(Map.Entry)iter.next(); ??
  74. ????????????parm.setName((String)entry.getKey()); ??
  75. ????????????parm.setValue((String[])entry.getValue()); ??
  76. ????????????map.put((String)entry.getKey(),?parm); ??
  77. ????????} ??
  78. ????????SophieContext.setRequestParametersMap(map); ??
  79. ????} ??
  80. ???? ??
  81. ????//分析uri得到action的name ??
  82. ????private?String?getActionName(HttpServletRequest?request){ ??
  83. ????????String?uri=request.getRequestURI(); ??
  84. ????????String?actionName=uri.substring(uri.lastIndexOf("/")+1,?uri.indexOf(".action")); ??
  85. ????????return?actionName; ??
  86. ????} ??
  87. ???? ??
  88. ???? ??
  89. ??
  90. } ??

?

2)SophieContext 保存servlet中的信息,如servletContext,requet,response

java 代码
  1. package?com.sophie.context; ??
  2. ??
  3. import?java.util.HashMap; ??
  4. import?java.util.Map; ??
  5. ??
  6. import?javax.servlet.ServletContext; ??
  7. import?javax.servlet.http.HttpServletRequest; ??
  8. import?javax.servlet.http.HttpServletResponse; ??
  9. ??
  10. import?com.sophie.parameter.Parameter; ??
  11. ??
  12. public?class?SophieContext?{ ??
  13. ???? ??
  14. ??
  15. ????//save?actioncontext?to?a?map ??
  16. ????private??static?Map?context=new?HashMap(); ??
  17. ???? ??
  18. ????//private?static?SophieContext?sophieContext; ??
  19. ???? ??
  20. ????private?SophieContext(){ ??
  21. ???????? ??
  22. ????} ??
  23. ???? ??
  24. ????/* ?
  25. ?????*?在后面的使用中,好像没有体现单例的作用,因为context已经是static了,不管是不是单例,context都是唯一的, ?
  26. ?????*?所以把所有的方法都改成静态的 ?
  27. ?????*/??
  28. ????/*public?static?SophieContext?getInstance(){ ?
  29. ????????if(null==sophieContext){ ?
  30. ????????????sophieContext=new?SophieContext(); ?
  31. ????????} ?
  32. ????????return?sophieContext; ?
  33. ????}*/??
  34. ??
  35. ????public?static?Map?getContext()?{ ??
  36. ????????return?context; ??
  37. ????} ??
  38. ??
  39. ????//??get?httpServletResponse ??
  40. ????public?static?HttpServletRequest?getRequest(){ ??
  41. ????????return?(HttpServletRequest)getContext().get(SophieStatic.HTTP_REQUEST); ??
  42. ????} ??
  43. ???? ??
  44. ????public?static?void?setRequest(HttpServletRequest?request){ ??
  45. ????????getContext().put(SophieStatic.HTTP_REQUEST,?request); ??
  46. ????} ??
  47. ???? ??
  48. ????//get?httpServletResponse ??
  49. ????public?static?HttpServletResponse?getResponse(){ ??
  50. ????????return?(HttpServletResponse)getContext().get(SophieStatic.HTTP_RESPONSE); ??
  51. ????} ??
  52. ???? ??
  53. ????public?static?void?setResponse(HttpServletResponse?response){ ??
  54. ????????getContext().put(SophieStatic.HTTP_RESPONSE,?response); ??
  55. ????} ??
  56. ???? ??
  57. ????/* ?
  58. ?????*?save?ServletContext ?
  59. ?????*/??
  60. ????public?static?void?setServletContext(ServletContext?servletContext){ ??
  61. ????????getContext().put(SophieStatic.SERVLET_CONTEXT,?servletContext); ??
  62. ????} ??
  63. ???? ??
  64. ????//get?servletContext ??
  65. ????public?static?ServletContext?getServletContext(){ ??
  66. ????????return?(ServletContext)getContext().get(SophieStatic.SERVLET_CONTEXT); ??
  67. ????} ??
  68. ???? ??
  69. ????/* ?
  70. ?????*?save?action?config?map ?
  71. ?????*/??
  72. ????public?static?void?setConfigurationMap(Map?configMap){ ??
  73. ????????getContext().put(SophieStatic.SOPHIE_ACTION_CONFIG_MAP,?configMap); ??
  74. ????} ??
  75. ???? ??
  76. ????@SuppressWarnings("unchecked") ??
  77. ????public?static?Map?getConfigurationMap(){ ??
  78. ????????return?(Map)getContext().get(SophieStatic.SOPHIE_ACTION_CONFIG_MAP); ??
  79. ????} ??
  80. ???? ??
  81. ????/* ?
  82. ?????*?get?the?parameters?from?httpservletRequest? ?
  83. ?????*/??
  84. ????public?static?void?setRequestParametersMap(Map?parametersMap){ ??
  85. ????????getContext().put(SophieStatic.PARAMETERS_MAP,?parametersMap); ??
  86. ????} ??
  87. ???? ??
  88. ????@SuppressWarnings("unchecked") ??
  89. ????/* ?
  90. ?????*?get?the?parameters?? ?
  91. ?????*/??
  92. ????public?static?Map?getRequestParametersMap(){ ??
  93. ????????return?(Map)getContext().get(SophieStatic.PARAMETERS_MAP); ??
  94. ????} ??
  95. ???? ??
  96. }??

?

3)Configuration, ResultConfiguration两个类是两个model,封装备置文件中action的属性信息

java 代码
  1. /* ?
  2. ?*?author?sophie?dong?2007-5-10 ?
  3. ?*?action?config?object ?
  4. ?*/??
  5. package?com.sophie.context; ??
  6. ??
  7. import?java.util.Map; ??
  8. ??
  9. public?class?Configuration?{ ??
  10. ??
  11. ????private?String?actionName; ??
  12. ??
  13. ????private?String?className; ??
  14. ??
  15. ????private?String?methodName; ??
  16. ??
  17. ????private?Map?resultMap; ??
  18. ??
  19. //get?set…… ??
  20. ??
  21. } ??

?

4)配置文件action.properties

java 代码
  1. test|com.sophie.action.TestAction||success--/hello.jsp ??
  2. testInclude|com.sophie.action.TestAction|testParameter|success--/includePage.html??

?

5)action的执行 这里用反射

java 代码
  1. /* ?
  2. ?*?author:sophie?dong ?
  3. ?*?把不同的result分发到相应的result类去处理 ?
  4. ?*/??
  5. package?com.sophie.dispatcher; ??
  6. ??
  7. import?java.io.IOException; ??
  8. import?java.util.Map; ??
  9. ??
  10. import?javax.servlet.ServletException; ??
  11. import?javax.servlet.http.HttpServletRequest; ??
  12. import?javax.servlet.http.HttpServletResponse; ??
  13. ??
  14. import?com.sophie.context.ResultConfiguration; ??
  15. import?com.sophie.context.SophieContext; ??
  16. import?com.sophie.result.SophieResult; ??
  17. ??
  18. public?class?ResultDispatcher?{ ??
  19. ????private?Map?resultMap; ??
  20. ????private?String?resultString; ??
  21. ???? ??
  22. ????//resultType=dispatcher的时候?判断用include还是forward ??
  23. ????private?String?include; ??
  24. ???? ??
  25. ????public?ResultDispatcher(Map?resultMap,String?resultString)?{ ??
  26. ????????this.resultMap=resultMap; ??
  27. ????????this.resultString=resultString; ??
  28. ????} ??
  29. ??
  30. //??处理result ??
  31. ????public?void?Dispatcher(){ ??
  32. ???????? ??
  33. ????????HttpServletRequest?request=SophieContext.getRequest(); ??
  34. ????????HttpServletResponse?response=SophieContext.getResponse(); ??
  35. ????????ResultConfiguration?resultConfig=resultMap.get(resultString); ??
  36. ????????//result?type==dispatcher ??
  37. ????????if(null==resultConfig.getResultType()?||?"".equals(resultConfig.getResultType()?)){ ??
  38. ????????????SophieResult?dispatcher=new?SophieResult(); ??
  39. ????????????dispatcher.setLocation(resultConfig.getPageUrl()); ??
  40. ????????????dispatcher.setInclude(include); ??
  41. ????????????try?{ ??
  42. ????????????????dispatcher.service(request,?response); ??
  43. ????????????}?catch?(ServletException?e)?{ ??
  44. ????????????????e.printStackTrace(); ??
  45. ????????????}?catch?(IOException?e)?{ ??
  46. ????????????????e.printStackTrace(); ??
  47. ????????????} ??
  48. ????????} ??
  49. ???????? ??
  50. ????} ??
  51. ??
  52. ????public?void?setInclude(String?include)?{ ??
  53. ????????this.include?=?include; ??
  54. ????} ??
  55. ??
  56. } ??

?

7) result类 处理输出

java 代码
  1. /* ?
  2. ?*?author?sophie?dong ?
  3. ?*?resultType?for?HttpServletRequest?de?forward?or?include ?
  4. ?*/??
  5. package?com.sophie.result; ??
  6. ??
  7. import?java.io.IOException; ??
  8. import?javax.servlet.RequestDispatcher; ??
  9. import?javax.servlet.ServletException; ??
  10. import?javax.servlet.http.HttpServlet; ??
  11. import?javax.servlet.http.HttpServletRequest; ??
  12. import?javax.servlet.http.HttpServletResponse; ??
  13. ??
  14. public?class?SophieResult?extends?HttpServlet{ ??
  15. ???? ??
  16. ????private?String?location; ??
  17. ????private?String?include; ??
  18. ??
  19. ????public?void?setLocation(String?location)?{ ??
  20. ????????this.location?=?location; ??
  21. ????} ??
  22. ???? ??
  23. ????@Override??
  24. ????protected?void?service(HttpServletRequest?request,?HttpServletResponse?response)?throws?ServletException,?IOException?{ ??
  25. ????????if(null!=location){ ??
  26. ????????????RequestDispatcher?dispatcher=request.getRequestDispatcher(location); ??
  27. ????????????if(null!=include?&&?"include".equals(include)) ??
  28. ????????????????dispatcher.include(request,?response); ??
  29. ????????????else??
  30. ????????????????dispatcher.forward(request,?response); ??
  31. ????????} ??
  32. ???????? ??
  33. ????} ??
  34. ??
  35. ????public?void?setInclude(String?include)?{ ??
  36. ????????this.include?=?include; ??
  37. ????} ??
  38. } ??
1 楼 hgq0011 2007-05-10  
LZ还挺有钻研精神的,值得学习。我用过好几个MVC的框架,可就没有自己DIY一个。
2 楼 dovecat 2007-05-10  
好长啊。支持下...一会细看
3 楼 zyl 2007-05-10  
能先给个类图,或者关系图也行,先从大概上给个轮廓,看代码毕竟有点累
4 楼 ecsoftcn 2007-05-11  
<p>赞一个先!</p>
<p>?</p>
<p>不断的模仿、练习必能提高个人的设计水平。</p>
<p>?</p>
<p>为演示Guice框架的使用,我也设计了一个简单的MVC,不过和楼主的相比就逊色很多,有时间我们可以交流一下设计思想,共同提高。</p>
<p><a href='http://www.iteye.com/topic/78365'><font size='4' color='#ff0000'><strong><em>AromaRI</em></strong></font></a></p>
5 楼 一半是鱼 2007-05-11  
zyl 写道
能先给个类图,或者关系图也行,先从大概上给个轮廓,看代码毕竟有点累

我不会画类图
给一个文字描述

Sophie的web框架
主要思路
Init配置文件-》dispatcher调度-》invocation执行action=》result处理结果,显示页面

主要功能部分
1. dispatcher 调度器,在启动服务的时候调用init方法,初始化action的配置文件。保存servlet的内容到SophieContext 中
2. configuration和resultConfiguration模型,把配置文件中的action信息,封装到一个configration类中。多个action信息组成一个map。每个action的result信息,封装到resultConfiguration中,多个result组成一个map.
3. action 类。逻辑的东西可以写在action中。Action类从servlet中分离出来。专注与逻辑本身。提供给框架的使用者。
4. SophieContext 保存context的类。里面有个静态的map。
5. SophieInvocation 执行action
6. sophieResult 处理action执行的结果,根据resultConfiguration里的配置,转向显示页面。
7. ActionTag action标签,可以在页面上用标签调用action
6 楼 shaucle 2007-05-11  
爱专研技术的MM还真不多. ^_^

你的那个只是个front controller的一部分,
Context和Invocation那部分你可参考xwork部分,如ThreadLocal
而且ww的一大核心是它的interception.

不过代码写得还不错.
7 楼 hgq0011 2007-05-11  
你发的EMIAL收到,可能是我这边的网络有些问题,老是发送不成功,所以在这回复你,:)

我刚才抽了点时间仔细的看了你的源码,真的值得学习呀,:)
自己封装那些东西当然不错了,放在一个全局的静态变量中,避免了每次调用都要开辟内存空间。是否可以在调用的时候,判断一下MAP是否生成了,如果生成了就不用去调用那些获取属性文件中的类。
8 楼 一半是鱼 2007-05-11  
hgq0011 写道

是否可以在调用的时候,判断一下MAP是否生成了,如果生成了就不用去调用那些获取属性文件中的类。

调用那些获取属性文件中的类是在服务启动的时候调用的,
因为是写在servlet的init方法里面,所以只会被调用到一次的:)

我现在觉得SophieDispatcher类里面 service方法中存入静态map里的一些对象,在并发的环境下是会冲突。我现在在考虑怎么改进这块
9 楼 umbrella 2007-05-11  
map改用hashtable或用collections.synchroized方法设置下,实在不行用同步锁住。
10 楼 shaucle 2007-05-11  
一半是鱼 写道
hgq0011 写道

是否可以在调用的时候,判断一下MAP是否生成了,如果生成了就不用去调用那些获取属性文件中的类。

调用那些获取属性文件中的类是在服务启动的时候调用的,
因为是写在servlet的init方法里面,所以只会被调用到一次的:)

我现在觉得SophieDispatcher类里面 service方法中存入静态map里的一些对象,在并发的环境下是会冲突。我现在在考虑怎么改进这块


ThreadLocal 
//from seam
public static void beginRequest(ExternalContext externalContext) {
      Contexts.eventContext.set(
//from jsf
public static FacesContext getCurrentInstance()
    {
        return (FacesContext)_currentInstance.get();
    }
11 楼 zyp731 2007-05-22  
女人就是女人啊,就爱干一些没用的事.现在已经有好多框架了,为什么还要自己去写呢?而且你写的,肯定不如struts好.有时间可以在公司的架构上下功夫.
12 楼 sunsy 2007-06-26  
读书加工作的这几年,还真是头次见这么热衷于技术的MM,支持下。