【问题标题】:How to access the file system from an EJB 3?如何从 EJB 3 访问文件系统?
【发布时间】:2010-11-24 08:48:30
【问题描述】:

我想知道如何从 EJB 3 bean 访问文件系统?

我在互联网上搜索了这个主题,但没有找到好的答案。

有些人建议使用 java.io/java.nio,即使规范禁止这种用法。无论如何,大多数应用服务器似乎都允许访问此 API。

另一个想法是使用 JCA 连接器来访问文件系统或 LDAP 目录。

当一个简单的文件在性能和使用的资源方面是一个更好的解决方案时,我想这样做以避免在数据库中使用 BLOB。

你会如何解决这个问题?

【问题讨论】:

标签: java file-io ejb-3.0


【解决方案1】:

不允许您在 EJB 中访问文件系统的原因是您无法控制应用程序在 (Java EE)Container 中的运行方式。例如,您的应用程序可能跨服务器集群运行,在这种情况下,将某些对象保存到一台服务器上的目录可能没什么用。 (当然你可能有一个网络文件系统,所以限制可能不适用)。

一种选择可能是使用您的Container附带的JNDI实现。您可能能够在某个 JNDI 位置保存原始 byte[] 数组,因此您始终可以保存对象的序列化形式:

ByteArrayOutputStream baos= new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos);
oos.writeObject(myObj);

//Now save into JNDI
new InitialContext().bind("path/to/myobject", baos.toByteArray());

这可以稍后查找并重新转换为您的对象:

byte[] bs = (byte[]) new InitialContext().lookup("path/to/myobject");
ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(bs));
MyObj myObj = (MyObj) ois.readObject();

或者,您可以使用java.beans persistent XML(即XMLDecoderXMLEncoder)将您的实例编码为 XML 字符串并将其保存到 JNDI。

【讨论】:

  • 这是从 EJB 写入文件的推荐方式吗?该文件是否对集群中的每个节点都可用(我认为 JNDI 确实是集群的,所以可能是的)?最后一次读取(或写入)JNDI 是事务性的吗?
  • "you are disallowed" - 你不再被禁止访问文件系统,而且这绝不是只适用于 EJB 规范的意图。写这本书的人当时被迷惑了,认为 EJB 将成为所有 Java EE 的基础,因此几乎等同于 Java EE。
【解决方案2】:

如果您知道您永远不会集群您的应用程序(或者您将能够对驱动器进行网络映射),那么只需使用 java.io.*。

请务必引入有关文件存储根位置的正确配置。

【讨论】:

  • 通过编写不符合 Java EE 规范的应用程序,您无法确定它的可移植性和可维护性。例如,在 12 个月的时间里,你可能会因为对你的应用程序进行集群的任务而让穷人大吃一惊而放弃了这个项目。或者将其移植到不同的容器中。
  • “如果你知道你永远不会集群你的应用程序” - 如果你发现你可以看到未来,你可能会认为有一个更赚钱的职业在召唤赌博业。
  • +1 我认为这取决于要求。顺便说一句,我已经发送了很多简历;)
  • @oxbow_lakes 为今天或明天不需要的未来而设计也是一种不好的做法。我见过人们为了“未来的灵活性”而将他们的设计完全复杂化,但是在 10 年的使用寿命之后,所有这些所谓的灵活性都没有被使用一次。一直以来,它确实减慢了各种任务。一如既往,使用常识。
  • 通常这些复杂的现在用于未来的技术最终甚至不适合未来,并且永远不会用于支持大规模重写。
【解决方案3】:

封装您对文件数据的访问。然后,您可以使用上述任何一种方法。甚至使用数据库。测量系统的性能。如果它满足要求,那么你就完成了。如果不是,您的文件访问被本地化在一个地方,您可以替换一个不同的解决方案。如果软件必须移植到另一个容器和/或必须由其他人维护,则同样有好处。

【讨论】:

    【解决方案4】:

    普通文件访问本质上不是事务性的。除非您构建对事务操作的支持(我不知道如何 - 这是资源管理器的工作),否则您将不得不担心您正在执行的操作的事务语义。如果您确实构建了事务支持,那么您在性能方面将获得的收益很少(数据库中的一些性能损失是由于资源管理器完成的所有簿记)。 并且不要忘记事务管理的近亲——并发。除非您开始为每个请求写入一个新文件,否则并发问题或多或少会困扰您。

    您将在Sun Blueprint's FAQ on EJB restrictions 中找到更多信息。

    除非您有充分的技术依据,否则您不应尝试从 EJB 访问文件系统。一个很好的例子是一个日志(不是审计)框架——访问文件系统来写日志文件的危害相对较小,因为日志不一定是一个事务操作,即你不需要回滚写到一个日志文件;并不是说可以接受部分写入。

    【讨论】:

    • 通过单例/定时器在本地缓存文件是另一个几乎总是安全的操作示例。
    • “除非 [...] 您不应该尝试从 EJB 访问文件系统” - 绝对没有具体的理由说明这仅适用于 EJB。从每种类型的 bean 进行 IO 时,应该小心谨慎,而不仅仅是恰好是 EJB bean 的 bean。
    猜你喜欢
    • 2023-04-02
    • 1970-01-01
    • 1970-01-01
    • 2017-05-21
    • 1970-01-01
    • 2022-10-25
    • 1970-01-01
    • 2013-03-29
    • 1970-01-01
    相关资源
    最近更新 更多