我想知道如何从EJB 3 bean中访问文件系统?
我在互联网上搜索了相关内容,但没有找到好的答案。
有些人建议使用java.io/java.nio,尽管规范禁止这种用法。大多数应用服务器似乎仍允许访问此API。
另一个想法是使用JCA连接器来访问文件系统或LDAP目录。
我想要做的是避免在数据库中使用BLOB,而是使用简单的文件作为更好的性能和资源利用解决方案。
您会如何解决这个问题?
我想知道如何从EJB 3 bean中访问文件系统?
我在互联网上搜索了相关内容,但没有找到好的答案。
有些人建议使用java.io/java.nio,尽管规范禁止这种用法。大多数应用服务器似乎仍允许访问此API。
另一个想法是使用JCA连接器来访问文件系统或LDAP目录。
我想要做的是避免在数据库中使用BLOB,而是使用简单的文件作为更好的性能和资源利用解决方案。
您会如何解决这个问题?
如果您知道您永远不会对应用程序进行集群化(或者您将能够将驱动器映射到网络),那么只需使用java.io.*。
请确保引入适当的配置,关于文件存储的根位置。
在EJB中,您被禁止访问文件系统的原因是您无法控制应用程序在(Java EE)容器中的运行方式。例如,您的应用程序可能在服务器群集上运行,在这种情况下,将某个对象保存到一个服务器的目录中可能没有什么用处。当然,您可能有网络文件系统,因此该限制可能不适用。
一种选择是使用您的Container附带的实现。你可能可以在某个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
的 持久化XML(即XMLDecoder
,XMLEncoder
)将实例编码为XML字符串,并将其保存到JNDI中。
封装文件数据的访问。然后您可以使用上述任何方法。甚至使用数据库。测量系统的性能。如果符合要求,则完成。如果不符合要求,则文件访问仅限于一个地方,您可以替换为其他解决方案。同样的好处,如果软件必须移植到另一个容器和/或由其他人维护。
普通文件访问本质上不具备事务性。除非您构建支持事务操作的支持(我对如何做这个工作一无所知 - 这是资源管理器的工作),否则您将不得不担心正在执行的操作的事务语义。如果您确实构建了事务支持,那么您在性能方面几乎没有获得任何好处(数据库中性能损失的一部分是由于资源管理器执行的所有簿记)。
不要忘记事务管理的近亲 - 并发。除非您为每个请求编写一个新文件,否则并发问题或多或少会困扰您。
您将在Sun Blueprint's FAQ on EJB restrictions中找到更多信息。
除非您有充分的技术理由,否则不应尝试从EJB访问文件系统。一个很好的例子是日志记录(而不是审计)框架 - 访问文件系统以写入日志文件相对较少有害,因为日志记录不必是事务操作,即您不需要回滚对日志文件的写入;但是部分写入是不可接受的。