分享
 
 
 

Petstore源码追踪记

王朝other·作者佚名  2008-05-31
窄屏简体版  字體: |||超大  

前言

透过前面的介绍,我们能够了解Petstore中Model、Controller、View是如何相互合作,现在让笔者来说明Petstore商业逻辑(Business Logic)的处理方式,首先让我们先了解为什么要将商业逻辑与资料展现(Presentation)分开,如此做有下列的好处:

1.减少程序变动的冲击:商业逻辑及资料展现彼此独立,不因商业逻辑改变而影响资料展现的程序代码,反之亦然。

2.易于维护:将商业逻辑集中管理,一旦日后有修改,仅须修改一个地方。

3.重复使用:商业逻辑若与资料展现层程序混在一起,如此商业逻辑只能服务一种使用者接口(Client),若将两者分离,我们可以很容易扩充第二种使用者接口。

4.各司其职:资料展现的设计人员与商业逻辑的设计人员通常是不一样的,彼此独立让术业有专攻,品质及效率皆能提升。

隐形角色

在追纵Petstore商业逻辑处理方式前,我们先来看看Petstore中的隐形角色,这些隐形角色在服务器(RI)激活时即默默准备好,待适当时机为Petstore中商业逻辑处理服务,所以笔者须先介绍它们。

请开启

Petstore_home(注一)\src\apps\petstore\src\docroot\WEB-INF\web.XML,

我们可以看到:

<!-- Encoding Filter Declaration Start -->

<filter> //1.第一个Fliter

<filter-name>EncodingFilter</filter-name>

<display-name>EncodingFilter</display-name>

<description>no description</description>

<filter-class>com.sun.j2ee.blueprints.encodingfilter.web.EncodingFilter

</filter-class>

<init-param>

<param-name>encoding</param-name>

<param-value>UTF-8</param-value>

</init-param>

</filter>

<!-- Encoding Filter Declaration End -->

<!-- Signon Filter Declaration Start -->

<filter> //2.第二个Filter

<filter-name>SignOnFilter</filter-name>

<display-name>SignOnFilter</display-name>

<description>no description</description>

<filter-class>com.sun.j2ee.blueprints.signon.web.SignOnFilter</filter-class>

</filter>

<!-- Signon Filter Declaration End -->

<!-- Encoding Filter Mapping Start-->

<filter-mapping> //第一个Filter对应

<filter-name>EncodingFilter</filter-name>

<url-pattern>/*</url-pattern>

</filter-mapping>

<!-- Encoding Filter Mapping End -->

<!-- Signon Filter Mapping Start-->

<filter-mapping> //第二个Filter对应

<filter-name>SignOnFilter</filter-name>

<url-pattern>/*</url-pattern>

</filter-mapping>

<!-- Signon Filter Mapping End -->

<!-- ComponentManager Listener -->

<listener> //3.第一个Listerner

<listener-class>com.sun.j2ee.blueprints.petstore.controller.web.PetstoreComponentManager</listener-class>

</listener>

<!-- SignOn Attribute Listener -->

<listener> //4.第二个Listerner

<listener-class>com.sun.j2ee.blueprints.petstore.controller.web.SignOnNotifier</listener-class>

</listener>

Filter与Listener是Servlet2.3增加的功能,Filter可以在接受使用者的Request之后,做一些检查处理,若没问题则把使用者要求的Response丢回给使用者,反之则丢回系统预设的处理画面,最常使用的情况就是登入,在网页应用系统中有些功能是必须登入才能使用,过去的做法我们会将登入检查写在这些个别功能上,如此会造成登入检查若要修正,则必须逐支修改,造成时间浪费,运用Filter,我们可将登入检查程序与其它程序独立,日后容易维护。Listener则是增加对Context,Session生命周期的控制,例如我们能够在Session初始化时,将所需使用的资料一起产生,并将Reference存入Session,Seesion关闭时可顺便将相关资源移除,如此资源集中控管,容易维护。

Encoding Filter

它的程序代码位置在

Petstore_home\src\components\encodingfilter\src\com\sun\j2ee\blueprints\encodingfilter\web\EncodingFilter.Java

,它会再读取web.xml(位置在Petstore_home\src\apps\petstore\src\docroot\WEB-INF\web.xml)中的参数,决定编码方式再将其设入Request中:

web.xml

<!-- Encoding Filter Declaration Start -->

<filter>

<filter-name>EncodingFilter</filter-name>

<display-name>EncodingFilter</display-name>

<description>no description</description>

<filter-class>com.sun.j2ee.blueprints.encodingfilter.web.EncodingFilter

</filter-class>

<init-param> //设定编码方式参数

<param-name>encoding</param-name>

<param-value>UTF-8</param-value>

</init-param>

</filter>

EncodingFilter.java

public class EncodingFilter implements Filter {

private FilterConfig config = null;

// default to ASCII

private String targetEncoding = "ASCII";

//初始化时读取参数

public void init(FilterConfig config) throws ServletException {

this.config = config;

this.targetEncoding = config.getInitParameter("encoding");

}

public void destroy() {

config = null;

targetEncoding = null;

}

//将编码方式参数存入reqeust,结束此Filter

public void doFilter(ServletRequest srequest, ServletResponse sresponse,

FilterChain chain)

throws IOException, ServletException {

HttpServletRequest request = (HttpServletRequest)srequest;

request.setCharacterEncoding(targetEncoding);

// move on to the next

chain.doFilter(srequest,sresponse);

}

}

笔者觉得这个Filter满有用的,可以单独运用在传统jsp+JavaBeans的Web Application,在Tomcat3.2.x,预设编码是UTF-8,所以我们处理中文时,必须自行在程序中处理,在存入数据库前须将中文字编码由Unicode转成Big5;到了Tomcat3.3.x,Tomcat会从OS取得预设编码方式,所以我们不必再自行处理;到了Tomcat4.0.x之后,情况又回到与Tomcat3.2.x一样,笔者开发Web Application就碰到这个情况,历经三个版本的Tomcat,程序改过来改过去的,尽做些白工,后来笔者改运用这个Filter,就不需在存入数据库前须将中文字编码由Unicode转成Big5。

ComponentManager Listener

第二个Filter主要掌管登入,与本次主题有密切关系,为使流程顺畅,所以稍后再说明。我们来看第一个Listener,它的主要功能是作为服务连结提供者,当使用者进入本系统时,应用服务器(Application Sever)会在Session产生时会建置储存服务连结容器,并将其置入Session,待后续程序服务产生后使用。

DefaultComponentManager.java,源码在

Petstore_home\src\waf\src\controller\com\sun\j2ee\blueprints\waf\controller\web

public void sessionCreated(HttpSessionEvent se) {

HttpSession session = se.getSession();

//产生服务连结容器

sl = ServiceLocator.getInstance();

//将本Listener存入Session

session.setAttribute(WebKeys.COMPONENT_MANAGER, this);

}

ServiceLacator.java,源码在

Petstore_home\src\components\servicelocator\src\com\sun\j2ee\blueprints\servicelocator\web

,此类别写法满特别的,大家又可多学一种程序设计技巧,追纵前辈源码,除了能够了解各种功能如何设计之外,程序代码分解(Refactor)、撰写风格、设计技巧,对我们来说都是很重要的收获!ServiceLacator基本上它是一个EJB及JMS资源连结服务提供者,且它的服务不因使用者不同而有所改变,所以它使用static写法来达到这个效果。

public class ServiceLocator {

private InitialContext ic;

private Map cache; //used to hold references to EJBHomes/JMS Resources for

//re-use

private static ServiceLocator me;

//初次宣告此对象时会执行初始化动作

static {

try {

me = new ServiceLocator();

} catch(ServiceLocatorException se) {

System.err.println(se);

se.printStackTrace(System.err);

}

}

//建构子,产生JNDI连结及同步化HashMap容器

private ServiceLocator() throws ServiceLocatorException {

try {

ic = new InitialContext();

cache = Collections.synchronizedMap(new HashMap());

} catch (NamingException ne) {

throw new ServiceLocatorException(ne);

} catch (Exception e) {

throw new ServiceLocatorException(e);

}

}

//将本对象参考传出

static public ServiceLocator getInstance() {

return me;

}

以下略过…

}

上述ServiceLocator建构子中运用Collections的Static Method(静态函式)synchronizedMap()来产生HashMap容器,依J2SDK API文件说法,透过此函式可产生出具同步化及安全执行绪的HashMap容器。

bill-转自:csdn进入讨论组讨论。

(出处:http://www.knowsky.com)

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有