Petstore源码追踪记(3)-商业逻辑处理(一) (转)

本文介绍了Petstore应用中商业逻辑的处理方式及其优势。通过分离商业逻辑与展示层,提高了程序的灵活性与可维护性。文章详细分析了Petstore中的过滤器(Filter)和监听器(Listener)的作用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Petstore源码追踪记(3)-商业逻辑处理(一) (转)[@more@]

作者:欧宣修

 

图文并茂版请参考
Javatwo.NET/JavaPaper/Petstore-3_business_logic.pdf">http://www.javatwo.net/JavaPaper/Petstore-3_business_logic.pdf

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


1.减少程序变动的冲击:商业逻辑及资料展现彼此独立,不因商业逻辑改变而影响资料展现的程序代码,反之亦然。
2.易于维护:将商业逻辑集中管理,一旦日后有修改,仅须修改一个地方。
3.重复使用:商业逻辑若与资料展现层程序混在一起,如此商业逻辑只能服务一种使用者接口(Client),若将两者分离,我们可以很容易扩充第二种使用者接口。
4.各司其职:资料展现的设计人员与商业逻辑的设计人员通常是不一样的,彼此独立让术业有专攻,品质及效率皆能提升。

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


请开启
Petstore_home(注一)srcappspetstoresrcdocrootweb-INFweb.XML
我们可以看到:
<!-- Encoding Filter Declaration Start --&gt
  //1.第一个Fliter
  EncodingFilter
  EncodingFilter
  no description
  com.sun.J2EE.blueprints.encodingfilter.web.EncodingFilter

 
  encoding
  UTF-8
 

<!-- Encoding Filter Declaration End --&gt
<!-- Signon Filter Declaration Start --&gt
  //2.第二个Filter
  SignOnFilter
  SignOnFilter
  no description
  com.sun.j2ee.blueprints.signon.web.SignOnFilter

<!-- Signon Filter Declaration End --&gt

<!-- Encoding Filter Mapping Start--&gt
//第一个Filter对应
  EncodingFilter
  /*

<!-- Encoding Filter Mapping End --&gt
<!-- Signon Filter Mapping Start--&gt
//第二个Filter对应
  SignOnFilter
  /*

<!-- Signon Filter Mapping End --&gt

<!-- ComponentManager Listener --&gt
//3.第一个Listerner

com.sun.j2ee.blueprints.petstore.controller.web.PetstoreComponentManager


<!-- SignOn Attribute Listener --&gt
//4.第二个Listerner

com.sun.j2ee.blueprints.petstore.controller.web.SignOnNotifier



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

Encoding Filter
它的程序代码位置在
Petstore_homesrccomponentsencodingfiltersrccomsunj2eeblueprintsencodingfilterwebEncodingFilter.java
,它会再读取web.xml(位置在Petstore_homesrcappspetstoresrcdocrootWEB-INFweb.xml)中的参数,决定编码方式再将其设入Request中:

web.xml
<!-- Encoding Filter Declaration Start --&gt
 
  EncodingFilter
  EncodingFilter
  no description
  com.sun.j2ee.blueprints.encodingfilter.web.EncodingFilter

  //设定编码方式参数
  encoding
  UTF-8
 
 

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_homesrcwafsrccontrollercomsunj2eeblueprintswafcontrollerweb

public void sessionCreated(HttpSessionEvent se) {
  HttpSession session = se.getSession();
  //产生服务连结容器
  sl = ServiceLocator.getInstance();
  //将本Listener存入Session
  session.setAttribute(WebKeys.COMPONENT_MANAGER, this);
}

ServiceLacator.java,源码在
Petstore_homesrccomponentsservicelocatorsrccomsunj2eeblueprintsservicelocatorweb
,此类别写法满特别的,大家又可多学一种程序设计技巧,追纵前辈源码,除了能够了解各种功能如何设计之外,程序代码分解(Refactor)、撰写风格、设计技巧,对我们来说都是很重要的收获!ServiceLacator基本上它是一个EJBJMS资源连结服务提供者,且它的服务不因使用者不同而有所改变,所以它使用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容器。



来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/10752043/viewspace-993964/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/10752043/viewspace-993964/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值