我写的这个框架大致模仿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 代码
- package?com.sophie.dispatcher; ??
- ??
- import?java.io.IOException; ??
- import?java.util.HashMap; ??
- import?java.util.Iterator; ??
- import?java.util.Map; ??
- import?java.util.Set; ??
- ??
- import?javax.servlet.ServletConfig; ??
- import?javax.servlet.ServletContext; ??
- import?javax.servlet.ServletException; ??
- import?javax.servlet.http.HttpServlet; ??
- import?javax.servlet.http.HttpServletRequest; ??
- import?javax.servlet.http.HttpServletResponse; ??
- ??
- import?com.sophie.context.ConfigUtil; ??
- import?com.sophie.context.Configuration; ??
- import?com.sophie.context.SophieContext; ??
- import?com.sophie.parameter.Parameter; ??
- ??
- public?class?SophieDispatcher?extends?HttpServlet?{ ??
- ????@Override??
- ????protected?void?service(HttpServletRequest?request,?HttpServletResponse?response)?throws?ServletException,?IOException?{ ??
- ????????/* ?
- ?????????*?因为进入该servlet的不是来至对该servelt本身的请求,(eg:test.action)所以这里用getServletConfig()得不到ServletConfig,从而无法得到ServletContext ?
- ?????????*保存servlet中的信息到自己定义的SophieContext对象中,备用 ?
- ?????????*/??
- ????????Map?parametersMap=request.getParameterMap(); ??
- ????????setParamtersMap(request,?parametersMap); ??
- ????????SophieContext.setRequest(request); ??
- ????????SophieContext.setResponse(response); ??
- ???????? ??
- ????????//根据url得到actionName ??
- ????????String?actionName=getActionName(request); ??
- ???????? ??
- ????????//执行action ??
- ????????SophieInvocation?invocation=new?SophieInvocation(actionName); ??
- ????????String?resultString=invocation.execute(); ??
- ????????ResultDispatcher?resultDispatcher=new?ResultDispatcher(invocation.getResultConfigMap(),resultString); ??
- ????????resultDispatcher.Dispatcher(); ??
- ????} ??
- ???? ??
- ????@Override??
- ????/* ?
- ?????*?init?sophieContext ?
- ?????*/??
- ????public?void?init(ServletConfig?config)?throws?ServletException?{ ??
- ????????ServletContext?context=config.getServletContext(); ??
- ????????/* ?
- ?????????*?更改于2007-5-10 ?
- ?????????*?1.把备置文件读出以后保存在对象里面,而不再是数组里面 ?
- ?????????*?2.把配置文件的map保存在sophieContext里面而不是servletContext里面 ?
- ?????????*??init?the?action?and?result?map? ?
- ?????????*?Map?map=new?HashMap(); ?
- ?????????*?map=PropertiesUtil.convertPropertyFileToMap(PropertiesUtil.ACTION_PROPERTIES); ?
- ?????????*?context.setAttribute(SophieStatic.ACTION_RESULT_MAP,?configMap); ?
- ?????????*/??
- ??
- ????????Map?configMap=new?HashMap(); ??
- ????????configMap=ConfigUtil.initConfigurationMap(); ??
- ???????? ??
- ????????SophieContext.setServletContext(context); ??
- ????????SophieContext.setConfigurationMap(configMap); ??
- ????????System.out.println("===init===="); ??
- ????} ??
- ???? ??
- ????//把parameter放到一个map中并存入SophieContext的map中备用 ??
- ????private?void?setParamtersMap(HttpServletRequest?request,Map?parametersMap){ ??
- ????????Parameter?parm=new?Parameter(); ??
- ????????Set?entrySet=parametersMap.entrySet(); ??
- ????????Map?map=new?HashMap(); ??
- ????????for?(Iterator?iter?=?entrySet.iterator();?iter.hasNext();)?{ ??
- ????????????Map.Entry?entry=(Map.Entry)iter.next(); ??
- ????????????parm.setName((String)entry.getKey()); ??
- ????????????parm.setValue((String[])entry.getValue()); ??
- ????????????map.put((String)entry.getKey(),?parm); ??
- ????????} ??
- ????????SophieContext.setRequestParametersMap(map); ??
- ????} ??
- ???? ??
- ????//分析uri得到action的name ??
- ????private?String?getActionName(HttpServletRequest?request){ ??
- ????????String?uri=request.getRequestURI(); ??
- ????????String?actionName=uri.substring(uri.lastIndexOf("/")+1,?uri.indexOf(".action")); ??
- ????????return?actionName; ??
- ????} ??
- ???? ??
- ???? ??
- ??
- } ??
?
2)SophieContext 保存servlet中的信息,如servletContext,requet,response
java 代码
- package?com.sophie.context; ??
- ??
- import?java.util.HashMap; ??
- import?java.util.Map; ??
- ??
- import?javax.servlet.ServletContext; ??
- import?javax.servlet.http.HttpServletRequest; ??
- import?javax.servlet.http.HttpServletResponse; ??
- ??
- import?com.sophie.parameter.Parameter; ??
- ??
- public?class?SophieContext?{ ??
- ???? ??
- ??
- ????//save?actioncontext?to?a?map ??
- ????private??static?Map?context=new?HashMap(); ??
- ???? ??
- ????//private?static?SophieContext?sophieContext; ??
- ???? ??
- ????private?SophieContext(){ ??
- ???????? ??
- ????} ??
- ???? ??
- ????/* ?
- ?????*?在后面的使用中,好像没有体现单例的作用,因为context已经是static了,不管是不是单例,context都是唯一的, ?
- ?????*?所以把所有的方法都改成静态的 ?
- ?????*/??
- ????/*public?static?SophieContext?getInstance(){ ?
- ????????if(null==sophieContext){ ?
- ????????????sophieContext=new?SophieContext(); ?
- ????????} ?
- ????????return?sophieContext; ?
- ????}*/??
- ??
- ????public?static?Map?getContext()?{ ??
- ????????return?context; ??
- ????} ??
- ??
- ????//??get?httpServletResponse ??
- ????public?static?HttpServletRequest?getRequest(){ ??
- ????????return?(HttpServletRequest)getContext().get(SophieStatic.HTTP_REQUEST); ??
- ????} ??
- ???? ??
- ????public?static?void?setRequest(HttpServletRequest?request){ ??
- ????????getContext().put(SophieStatic.HTTP_REQUEST,?request); ??
- ????} ??
- ???? ??
- ????//get?httpServletResponse ??
- ????public?static?HttpServletResponse?getResponse(){ ??
- ????????return?(HttpServletResponse)getContext().get(SophieStatic.HTTP_RESPONSE); ??
- ????} ??
- ???? ??
- ????public?static?void?setResponse(HttpServletResponse?response){ ??
- ????????getContext().put(SophieStatic.HTTP_RESPONSE,?response); ??
- ????} ??
- ???? ??
- ????/* ?
- ?????*?save?ServletContext ?
- ?????*/??
- ????public?static?void?setServletContext(ServletContext?servletContext){ ??
- ????????getContext().put(SophieStatic.SERVLET_CONTEXT,?servletContext); ??
- ????} ??
- ???? ??
- ????//get?servletContext ??
- ????public?static?ServletContext?getServletContext(){ ??
- ????????return?(ServletContext)getContext().get(SophieStatic.SERVLET_CONTEXT); ??
- ????} ??
- ???? ??
- ????/* ?
- ?????*?save?action?config?map ?
- ?????*/??
- ????public?static?void?setConfigurationMap(Map?configMap){ ??
- ????????getContext().put(SophieStatic.SOPHIE_ACTION_CONFIG_MAP,?configMap); ??
- ????} ??
- ???? ??
- ????@SuppressWarnings("unchecked") ??
- ????public?static?Map?getConfigurationMap(){ ??
- ????????return?(Map)getContext().get(SophieStatic.SOPHIE_ACTION_CONFIG_MAP); ??
- ????} ??
- ???? ??
- ????/* ?
- ?????*?get?the?parameters?from?httpservletRequest? ?
- ?????*/??
- ????public?static?void?setRequestParametersMap(Map?parametersMap){ ??
- ????????getContext().put(SophieStatic.PARAMETERS_MAP,?parametersMap); ??
- ????} ??
- ???? ??
- ????@SuppressWarnings("unchecked") ??
- ????/* ?
- ?????*?get?the?parameters?? ?
- ?????*/??
- ????public?static?Map?getRequestParametersMap(){ ??
- ????????return?(Map)getContext().get(SophieStatic.PARAMETERS_MAP); ??
- ????} ??
- ???? ??
- }??
?
3)Configuration, ResultConfiguration两个类是两个model,封装备置文件中action的属性信息
java 代码
- /* ?
- ?*?author?sophie?dong?2007-5-10 ?
- ?*?action?config?object ?
- ?*/??
- package?com.sophie.context; ??
- ??
- import?java.util.Map; ??
- ??
- public?class?Configuration?{ ??
- ??
- ????private?String?actionName; ??
- ??
- ????private?String?className; ??
- ??
- ????private?String?methodName; ??
- ??
- ????private?Map?resultMap; ??
- ??
- //get?set…… ??
- ??
- } ??
?
4)配置文件action.properties
java 代码
- test|com.sophie.action.TestAction||success--/hello.jsp ??
- testInclude|com.sophie.action.TestAction|testParameter|success--/includePage.html??
?
5)action的执行 这里用反射
java 代码
- /* ?
- ?*?author:sophie?dong ?
- ?*?把不同的result分发到相应的result类去处理 ?
- ?*/??
- package?com.sophie.dispatcher; ??
- ??
- import?java.io.IOException; ??
- import?java.util.Map; ??
- ??
- import?javax.servlet.ServletException; ??
- import?javax.servlet.http.HttpServletRequest; ??
- import?javax.servlet.http.HttpServletResponse; ??
- ??
- import?com.sophie.context.ResultConfiguration; ??
- import?com.sophie.context.SophieContext; ??
- import?com.sophie.result.SophieResult; ??
- ??
- public?class?ResultDispatcher?{ ??
- ????private?Map?resultMap; ??
- ????private?String?resultString; ??
- ???? ??
- ????//resultType=dispatcher的时候?判断用include还是forward ??
- ????private?String?include; ??
- ???? ??
- ????public?ResultDispatcher(Map?resultMap,String?resultString)?{ ??
- ????????this.resultMap=resultMap; ??
- ????????this.resultString=resultString; ??
- ????} ??
- ??
- //??处理result ??
- ????public?void?Dispatcher(){ ??
- ???????? ??
- ????????HttpServletRequest?request=SophieContext.getRequest(); ??
- ????????HttpServletResponse?response=SophieContext.getResponse(); ??
- ????????ResultConfiguration?resultConfig=resultMap.get(resultString); ??
- ????????//result?type==dispatcher ??
- ????????if(null==resultConfig.getResultType()?||?"".equals(resultConfig.getResultType()?)){ ??
- ????????????SophieResult?dispatcher=new?SophieResult(); ??
- ????????????dispatcher.setLocation(resultConfig.getPageUrl()); ??
- ????????????dispatcher.setInclude(include); ??
- ????????????try?{ ??
- ????????????????dispatcher.service(request,?response); ??
- ????????????}?catch?(ServletException?e)?{ ??
- ????????????????e.printStackTrace(); ??
- ????????????}?catch?(IOException?e)?{ ??
- ????????????????e.printStackTrace(); ??
- ????????????} ??
- ????????} ??
- ???????? ??
- ????} ??
- ??
- ????public?void?setInclude(String?include)?{ ??
- ????????this.include?=?include; ??
- ????} ??
- ??
- } ??
?
7) result类 处理输出
java 代码
- /* ?
- ?*?author?sophie?dong ?
- ?*?resultType?for?HttpServletRequest?de?forward?or?include ?
- ?*/??
- package?com.sophie.result; ??
- ??
- import?java.io.IOException; ??
- import?javax.servlet.RequestDispatcher; ??
- import?javax.servlet.ServletException; ??
- import?javax.servlet.http.HttpServlet; ??
- import?javax.servlet.http.HttpServletRequest; ??
- import?javax.servlet.http.HttpServletResponse; ??
- ??
- public?class?SophieResult?extends?HttpServlet{ ??
- ???? ??
- ????private?String?location; ??
- ????private?String?include; ??
- ??
- ????public?void?setLocation(String?location)?{ ??
- ????????this.location?=?location; ??
- ????} ??
- ???? ??
- ????@Override??
- ????protected?void?service(HttpServletRequest?request,?HttpServletResponse?response)?throws?ServletException,?IOException?{ ??
- ????????if(null!=location){ ??
- ????????????RequestDispatcher?dispatcher=request.getRequestDispatcher(location); ??
- ????????????if(null!=include?&&?"include".equals(include)) ??
- ????????????????dispatcher.include(request,?response); ??
- ????????????else??
- ????????????????dispatcher.forward(request,?response); ??
- ????????} ??
- ???????? ??
- ????} ??
- ??
- ????public?void?setInclude(String?include)?{ ??
- ????????this.include?=?include; ??
- ????} ??
- } ??
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>
<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.
不过代码写得还不错.
你的那个只是个front controller的一部分,
Context和Invocation那部分你可参考xwork部分,如ThreadLocal
而且ww的一大核心是它的interception.
不过代码写得还不错.
7 楼
hgq0011
2007-05-11
你发的EMIAL收到,可能是我这边的网络有些问题,老是发送不成功,所以在这回复你,:)
我刚才抽了点时间仔细的看了你的源码,真的值得学习呀,:)
自己封装那些东西当然不错了,放在一个全局的静态变量中,避免了每次调用都要开辟内存空间。是否可以在调用的时候,判断一下MAP是否生成了,如果生成了就不用去调用那些获取属性文件中的类。
我刚才抽了点时间仔细的看了你的源码,真的值得学习呀,:)
自己封装那些东西当然不错了,放在一个全局的静态变量中,避免了每次调用都要开辟内存空间。是否可以在调用的时候,判断一下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,支持下。