分享
 
 
 

EJB最佳实践:如何做实体bean的保护

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

如何才能使用户可以访问您的应用程序数据,又不会将您的实体 bean 直接暴露给 Web 层,从而不会使您的应用程序面临安全性威胁?

Brett McLaughlin 提供了一个解决方案,它可使您的实体 bean 很安全,并且使您的整个应用程序有效率地运行。

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

在这篇EJB最佳实践的文章中,我们将讨论为什么绝对不可以将实体 bean 暴露给应用程序的 Web 层,以及为什么这是难以避免的。接着我将向您演示一个变通方法,它既能使您的实体 bean 更安全,又能使您的整个应用程序更有效率。

暴露的风险

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

暴露的 bean:一个工作示例

请考虑称为Movie的实体bean。该bean的方法是getTitle()、getDirector()和getActors()。因为您已暴露了该 bean 的远程接口,所以您的应用程序和几个客户机应用程序都编写了合并 getDirector() 方法的代码。但是,随着应用程序的发展,它应该能接受由多位导演指导的电影,这一点很清楚。数据库更改了,您的 getDirector() 方法变成了 getDirectors()。现在该方法是复数形式并被编码为返回一个列表,而不是单一对象。其结果是,所有使用旧方法的代码都将破坏,从而不得不重写您的应用程序代码(以及您的客户机应用程序代码)。

除了存在使您数据库结构暴露给未知应用程序的明显危险之外,您还应该考虑当数据结构更改时会发生什么。因为实体 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. 隐藏已不使用的方法

public Person getDirector() {

// We can't call getDirector() any more on the entity bean

// Call the new method, through this manager

List directors = getDirectors();

// Return the first one in the list

return (Person)directors.item(0);

}

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

隐藏数据结构

尽管上面的解决方案确实解决了更改管理的问题,但它不能消除安全性问题。您仍需要保护实体bean(并由此保护您的数据结构),以免暴露给Web层。通过向会话bean添加一些简单的业务逻辑和数据操作功能,您不仅可以隐藏应用程序的数据结构,还可以提供对它所包含的信息的更复杂访问。

例如,随着应用程序的发展,您可能发现让用户依次访问各种数据对象(例如,导演、制片人、演员)的效率很低。因为这类信息几乎总是被放在一起,并一起使用,所以您可能发现重新确定会话 bean 的用途会很有帮助。您的会话 bean 将不包含 getDirector() 或 getDirectors() 方法,而是包含了如清单 2 所示的新的业务逻辑:

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

public List getCrew(String movieName)

throws NamingException, RemoteException {

List crew = new LinkedList();

EJBHomeFactory f = EJBHomeFactory.getInstance();

MovieHome movieHome =

(MovieHome)f.lookup("java:comp/env/ejb/Movie", MovieHome.class);

Movie movie = movieHome.findByName(movieName);

crew.add(movie.getDirectors());

crew.add(movie.getProducers());

crew.add(movie.getExecutiveProducers());

// and so on...

return crew;

}

public List getCast(String movieName)

throws NamingException, RemoteException {

List cast = new LinkedList();

EJBHomeFactory f = EJBHomeFactory.getInstance();

MovieHome movieHome =

(MovieHome)f.lookup("java:comp/env/ejb/Movie", MovieHome.class);

Movie movie = movieHome.findByName(movieName);

crew.add(movie.getActors());

crew.add(movie.getStandIns());

// and so on...

return cast;

}

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

会话虚包模式是许多其它设计模式的基本构件,其优点远远不止这里所讨论的。在 EJB 最佳实践的下一篇专栏文章中,我们将使用本系列的第一篇技巧文章中研究的业务接口(Business Interface)模式,以及您在这里了解到的某些诀窍来进一步抽象出使用您应用程序中所有类型 EJB 组件的过程。

要避免的解决方案

解决所描述的这类问题的一个常见解决方案是简单地将助手方法添加到实体bean本身。但这样做的后果可能是灾难性的。即使您实体bean中的每个方法每年只更改一次,但bean会在那年结束时将拥有双倍数量的方法。当您考虑方法不只是每年更改一次,而是以频繁得多的频率更改时,为什么这个“邦迪式(Band-Aid)”方法不起作用就很明显了。当实体bean看上去不再象数据对象而开始象助手类时,您知道您已经有问题了。另一方面,会话 bean 常常看上去十分象助手类,因为那是会话 bean 旨在实现的功能之一。

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
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- 王朝網路 版權所有