利用J2EE模式构建网站.docx
《利用J2EE模式构建网站.docx》由会员分享,可在线阅读,更多相关《利用J2EE模式构建网站.docx(17页珍藏版)》请在冰豆网上搜索。
利用J2EE模式构建网站
二、设计网站系统
我们的样例是一个教学网站系统,它的软件包括WebSphereApplicationServer应用服务器软件V4.0、WSAD开发工具和DB2数据库(非商业用途),硬件为IBMxSeries服务器。
在本文中,主要探讨MVC的开发模型和常用的J2EE模式,关于网站建设的其他细节就略过不提了。
(一)系统用例图
分析网站的系统目标后,我们首先具体化系统功能,形成一张用例图,定义一系列的可重构组件,以指导随后的开发工作。
图1UseCasepicture
(二)组件化设计
在构造网站系统时,我们把每层的系统想象成拥有多个"槽"的装置,开发人员可以向槽中插入组件以扩大其能力,也可以通过继承或其他机制具体化组件系统。
这些组件可以是开发人员为该应用系统开发的,也可以是以前开发好的复用组件。
在这种分层体系结构中,每个应用系统都表示为一个单独的系统。
每个系统都采用组件构造。
每个组件系统又可以通过其他下层组件系统构造。
重构人员采用一组与特定应用系统领域和业务有关的组件或顶层中的组件系统来构造每个应用系统。
结合J2EE,让我们首先了解J2EE体系中的组件构成情况,如图2所示。
图2J2EE组件打包策略
在上图中可以看出,不同的组件归档到不同的文件包中,这样就保证了一个组件的"插拔"不会影响到其它的组件。
根据应用系统组件的功能,我们可以把它们分为动态组件和静态组件。
静态的组件包含网页文件,主要用于放置教学资料和参考文章。
动态组件则包括各种功能模块,如论坛系统、模拟测验系统等。
应用系统组件之下是于特定业务有关的组件。
在这里,我们可以添加非Java编写的一些程序,用于处理特定内容下的操作,比如模拟测验系统中的出题模块。
当然,要考虑到上层组件调用的正面接口问题。
对于这层组件,我们能够随时替换,只要其提供的数据符合上级正面的要求。
以上两级组件之下是J2EE应用服务器和操作系统,整体如图3所示。
图3计算机组成原理网站系统组件架构图
(三)利用J2EE模式开发组件系统
下面着重介绍开发过程中使用的J2EE模式,这些模式都是通用类型的。
本系统采用MVC开发模型,即Model-View-Controller。
Model是指应用程序的数据,以及对这些数据的操作;View是指用户界面;Controller负责用户界面和程序数据之间的同步。
这种模型的好处在于分离不同功能的代码,便于以后的维护,还有利于在项目小组内按照小组成员各自的擅长进行分工,有利于三个部分并行开发、加快项目进度。
为了使各开发人员协调一致,为其他组件提供一致和标准的正面,增强系统的可维护性和可复用性,我们广泛采用了SUN公司提出的基于MVC的设计模式。
图4是用户注册模块的UML图,我们将结合这个模块具体阐述各模式的特点和在本系统中的实际应用。
图4表示层模式
明确了所采用的体系和模式,下面具体设计类的属性和方法,通过设计完善的接口和继承、重载等方法进行重构。
模块的UML的类图表示如下:
图5模块的UML的类图
结合上图,让我们看看这个模块中都运用了哪些模式。
1.表示层模式
系统的表示层集中了MVC模式中的View与Controller。
该系统用JSP代表View,用Servlet代表Controller。
在Controller这一模块中,又采用了视图助手、分发者与值对象模式,以增强系统的模块化,提高维护性。
(1)前端控制器
控制器通常表现为Servlet形式,其UML表示如下:
图6前端控制器
根据Model-View-Controller的开发思想,使用控制器作为处理请求的最初联系点。
该控制器管理着请求的处理,包括调用安全服务,比如验证和授权、委托业务处理、管理合适的视图选择、处理错误,以及管理内容创建逻辑的选择。
也可以把前端控制器看成一个触发器,由它来启动流程。
下面是功能代码的样本。
其中出现的RegisterHelper、Command等类,接下来会有详细介绍。
publicvoidperformTask(javax.servlet.http.HttpServletRequestrequest,
javax.servlet.http.HttpServletResponseresponse)
throwsjavax.servlet.ServletException,java.io.IOException
{
RegisterHelperrh=newRegisterHelper(request,response);//启动注册视图助手
Commandcommand=rh.getCommand();//由视图助手中获得并初始化Command
CustomerBeancb=rh.getCustomerBean();//由视图助手中获得并初始化值对象
request.setAttribute("customerbean",cb);
Stringdispatcher=rh.getDispatcher();//由视图助手中获得并初始化分发者
request.setAttribute("type",rh.getType());//设置上下文属性
try{
command.execute((Helper)rh);//执行业务代码
}catch(javax.ejb.DuplicateKeyExceptionde){
request.setAttribute("errorbean",newErrorBean("对不起,已经有人注册了该用户名!
"));//注册重名处理
dispatch(request,response,dispatcher);//分发并移交控制权
return;
}catch(Exceptione){
request.setAttribute("errorbean",newErrorBean("对不起,数据库出错!
"));//出错处理
dispatch(request,response,dispatcher);
return;
}
dispatch(request,response,dispatcher);
}
优点:
通过集中化决策点和控制,控制器有助于减少嵌入在JSP中Java代码(Scriptlet)的数量,保持View功能的纯洁性。
它的位置如图5中Controller所示。
(2)视图助手
表示层更改经常发生,而且当业务数据访问逻辑和表示格式化逻辑被混杂时,表示层更改很难开发和维护。
这使系统灵活性更差,更缺乏可用性,而且对变化的适应性更弱。
图7视图助手
视图包含格式化代码,把其处理责任委托给其助手类。
助手也存储该视图的中间数据,如表单、URL参数等,并且充当业务数据适配器。
下面是功能代码的样本。
publicclassRegisterHelperimplementsHelper{
staticStringdispatcher="RegisterDispatcher";
privateCustomerBeancustomer=null;
privateStringtype=null;
publicRegisterHelper(
javax.servlet.http.HttpServletRequestrequest,
javax.servlet.http.HttpServletResponseresponse){
setType(request);
setCustomerBean(request);
}
/**
*定义页面类型:
HTMLorXML
*/
publicvoidsetType(javax.servlet.http.HttpServletRequestrequest){
type=request.getParameter("type");
}
/**
*获取Command
*/
publicCommandgetCommand(){
RegisterCommandrc=newRegisterCommand();
returnrc;
}
/**
*向值对象中填充数据
*/
publicvoidsetCustomerBean(javax.servlet.http.HttpServletRequestrequest){
customer=newCustomerBean();
customer.setUsername(request.getParameter("username"));
customer.setPassword(request.getParameter("password"));
customer.setEmail(request.getParameter("email"));
customer.setTruename(request.getParameter("truename"));
customer.setId(request.getParameter("id"));
customer.setService(this.setService(request));
}
/**
*获取值对象
*/
publicCustomerBeangetCustomerBean(){
returnthis.customer;
}
/**
*获取分发者
*/
publicStringgetDispatcher(){
returnthis.dispatcher;
}
/**
*获取类型
*/
publicStringgetType(){
returntype;
}
}
优点:
在助手中而不是在视图中封装业务逻辑会增强应用程序的模块化,并且更有利于组件重用。
助手有大量的责任,包括收集视图和控制需要的数据,以及存储中间模型。
它的位置如图5中Helper所示。
(3)Command模式
Command中包含纯业务代码,如注册、登陆、检验等。
在样例模块中,它的职责是将注册信息传递给EntityBean。
图8Command
功能代码如下所示:
publicvoidexecute(Helperhelper)throwsException
{
RegisterHelperrh=(RegisterHelper)helper;//获取视图助手
CustomerBeancb=rh.getCustomerBean();//从视图助手中获取值对象
ServiceLocatorsl=ServiceLocator.getInstance();//初始化服务定位器
CustomersHomech=(CustomersHome)sl.getHome(ServiceLocator.Services.CUSTOMERS);
//从服务定位器中获取EntityBean本地接口
try{
Customerscustomers=ch.create(cb);//将注册信息导入数据库
}catch(javax.ejb.DuplicateKeyExceptione){
thrownewjavax.ejb.DuplicateKeyException();
}catch(Exc