EJB 最佳实践: 实体bean保护

日期: 2009-11-17 作者:IBM developerworks 来源:TechTarget中国 英文

  Enterprise JavaBeans技术一般分成三种核心类型的bean:会话bean、消息驱动bean和实体 bean。bean还可以分成充当业务对象的bean和充当数据对象的bean。会话bean和消息驱动bean是业务对象;实体bean是数据对象。大多数情况下,只需要将业务对象暴露给Web层(有时称为应用层),因为业务对象可以使用数据对象来处理数据存储。但在有些情况下,有必要允许用户直接访问和操作数据对象,这意味着要将实体bean暴露给Web层。这会使您的应用程序面临安全性威胁,而且随着您的应用程序的发展,还会导致杂乱无章的代码。

  暴露的风险

  实体bean揭示了大量有关数据库底层结构的信息。因为每个bean都包含用于数据库中的各个字段的取值(accessor)和赋值(mutator)方法(即, getxxx() 和 setxxx() ),而且因为方法名称通常与字段名称连在一起(User bean中的getFirstName()通常访问 Users表中的firstName字段),所以从应用程序的实体bean推断这个应用程序的整个数据库结构是可能的。尽管在单个应用程序中这可能不是什么大问题,但您的bean常常会暴露给其它网络上另外的应用程序。在Web服务系统中尤其会发生这种情况,其中应用程序都是跨多个网络链接的。

  除了存在使您数据库结构暴露给未知应用程序的明显危险之外,您还应该考虑当数据结构更改时会发生什么。因为实体bean与您的数据结构紧密地结合在一起,所以随着数据库表中列的更改或新列的添加,实体bean常常要随之更改。通过将您的实体bean暴露给应用层,可以使它们的方法名称可用,而且这些方法名称几乎总是被您的应用程序和外部应用程序合并到新的应用程序代码中。随着您的实体bean的更改以及发展,就会出现严重的代码混乱。

  会话虚包模式

  幸运的是,有一个设计模式让您允许用户访问数据对象,同时又不会将实体bean暴露给Web层。 会话虚包(Session Facade)模式在实体bean和应用程序客户机之间放置了一个会话bean。当我通过这种方法使用会话bean时,我喜欢把它当作管理器,因为它的任务是管理对其它实体的访问。

  会话bean旨在充当业务逻辑和应用逻辑之间的接口,逻辑极其简单,而且它只调出一个底层实体 bean。然而在实际情况中,您可能会选择让会话bean管理数据验证、安全性或任何其它特定于业务的功能。通过将实体bean封装在会话bean中,您可以访问所有所需的业务功能,同时不会“污染”您的实体bean代码。

  为了解决工作示例中的问题,您可以创建称为MovieManager的会话bean。MovieManager bean将包含旧方法getDirector()和新方法getDirectors()。当添加了新方法时,它只是被“代理”到您的实体bean。因为第一个方法在实体bean中不再可用,所以会话bean使用助手方法来隐藏它,如清单 1 所示:

  清单 1. 隐藏已不使用的方法

以下是引用片段:
1 public Person getDirector() {
2           // We can’t call getDirector() any more on the entity bean
3           // Call the new method, through this manager
4           List directors = getDirectors();
5           // Return the first one in the list
6           return (Person)directors.item(0);
7       }

  清单 1 的适用性不是特别健壮,但它获得了成功。因为隐藏了旧方法(而不是删除),所以所有与它相关的应用程序代码都一直存在。通过将助手方法放置在它所属的业务对象中,您还将它排斥在实体bean之外。解决了这个紧急的问题后,您可以选择将bean的客户机手工移植到新方法,或让助手方法一直处理移植工作。不管是哪种方法,都不会影响您的应用程序代码和您的客户机代码。

  隐藏数据结构

  尽管上面的解决方案确实解决了更改管理的问题,但它不能消除安全性问题。您仍需要保护实体 bean(并由此保护您的数据结构),以免暴露给Web层。通过向会话bean添加一些简单的业务逻辑和数据操作功能,您不仅可以隐藏应用程序的数据结构,还可以提供对它所包含的信息的更复杂访问。
  例如,随着应用程序的发展,您可能发现让用户依次访问各种数据对象(例如,导演、制片人、演员)的效率很低。因为这类信息几乎总是被放在一起,并一起使用,所以您可能发现重新确定会话 bean 的用途会很有帮助。您的会话bean将不包含getDirector()或getDirectors()方法,而是包含了如清单 2 所示的新的业务逻辑:

  清单 2. 用会话bean掩盖数据结构

以下是引用片段:
1 public List getCrew(String movieName)
2          throws NamingException, RemoteException {
3           List crew = new LinkedList();
4           EJBHomeFactory f = EJBHomeFactory.getInstance();
5           MovieHome movieHome =
6             (MovieHome)f.lookup(“java:comp/env/ejb/Movie”, MovieHome.class);
7           Movie movie = movieHome.findByName(movieName);
8           crew.add(movie.getDirectors());
9           crew.add(movie.getProducers());
10           crew.add(movie.getExecutiveProducers());
11           // and so on…
12           return crew;
13       }
14       public List getCast(String movieName)
15          throws NamingException, RemoteException {
16           List cast = new LinkedList();
17           EJBHomeFactory f = EJBHomeFactory.getInstance();
18           MovieHome movieHome =
19             (MovieHome)f.lookup(“java:comp/env/ejb/Movie”, MovieHome.class);
20           Movie movie = movieHome.findByName(movieName);
21           crew.add(movie.getActors());
22           crew.add(movie.getStandIns());
23           // and so on…
24           return cast;
25       }

  通过分离不同的应用程序层,以及使用业务逻辑来处理数据操作,您既阻止了对实体bean直接而且可能不安全的访问,又为您的Web层创建了更有意义的方法集。本例中,会话虚包充当了实体bean 的封装器以及真正的业务逻辑单元,从而将原始数据转变成有意义的信息。

  会话虚包模式是许多其它设计模式的基本构件,其优点远远不止这里所讨论的。

我们一直都在努力坚持原创.......请不要一声不吭,就悄悄拿走。

我原创,你原创,我们的内容世界才会更加精彩!

【所有原创内容版权均属TechTarget,欢迎大家转发分享。但未经授权,严禁任何媒体(平面媒体、网络媒体、自媒体等)以及微信公众号复制、转载、摘编或以其他方式进行使用。】

微信公众号

TechTarget微信公众号二维码

TechTarget

官方微博

TechTarget中国官方微博二维码

TechTarget中国

相关推荐

  • 京东云实践:浅谈Redis主从复制

    Redis是一个开源的,遵守BSD许可协议的key/value缓存系统,并由其高效的响应速度以及丰富的数据结构而闻名。

  • 何时是创建门户应用最佳时机

    在创建出新企业门户应用,链接到现有系统之前,你可能需要检查一下这些系统,确保这些系统本身不需要重造。这样你可能就会重新考虑是否要创建新企业门户应用了。

  • 采用EJB开发的三个优势

    EJB是sun的服务器端组件模型,最大的用处是部署分布式应用程序。当然,还有许多方式可以实现分布式应用,类似微软的.net技术。

  • 构建高性能J2EE应用的十个技巧

    构建高性能的J2EE应用不但需要了解常用的实施技巧。下面介绍最常用的10种有效方法,可帮助架构设计师们快速成为这方面的专家。