Как получить доступ к файловой системе из EJB 3?

Я хотел бы знать, как я могу получить доступ к файловой системе из bean-компонента EJB 3?

Я искал в Интернете по этому вопросу и не нашел хорошего ответа.

Некоторые предлагают использовать java.io/java.nio, хотя спецификация запрещает такое использование. Большинство серверов приложений в любом случае разрешают доступ к этому API.

Другой идеей было бы использовать коннектор JCA для доступа к файловой системе или каталогу LDAP.

Что я хочу сделать, чтобы избежать использования BLOB в базе данных, когда простой файл был бы гораздо лучшим решением с точки зрения производительности и используемых ресурсов.

Как бы вы решили эту проблему?


person Pierre Thibault    schedule 31.08.2009    source источник
comment
Вам не нужно иметь BLOB в базе данных. SQL Server 2008 поддерживает хранилище файлового потока, которое, по сути, выгружает файл в папку на сервере БД, но предоставляет доступ к нему через базу данных. блоги. msdn.com/rdoherty/archive/2007/10/12/   -  person pjp    schedule 31.08.2009


Ответы (4)


Причина, по которой вам запрещен доступ к файловой системе в EJB, заключается в том, что вы не можете контролировать, как ваше приложение работает в контейнере (Java EE). Например, ваше приложение может выполняться на кластере серверов, и в этом случае сохранение какого-либо объекта в каталоге на одном сервере, скорее всего, будет бесполезным. (Конечно, у вас может быть сетевая файловая система, поэтому ограничение может не применяться).

Одним из вариантов может быть использование реализации JNDI, которая поставляется с вашим Контейнером. Скорее всего, вы сможете сохранить необработанный массив byte[] в каком-то месте JNDI, чтобы вы всегда могли сохранить сериализованную форму объекта:

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.

person oxbow_lakes    schedule 31.08.2009
comment
Это рекомендуемый способ записи файлов из EJB? Будет ли файл доступен для каждого узла в кластере (я думаю, что JNDI действительно кластеризован, так что, вероятно, да)? Последнее чтение (или запись) JNDI является транзакционным? - person Mike Argyriou; 29.07.2015
comment
вам запрещено - вам больше не запрещен доступ к файловой системе, и НИКОГДА не предполагалось, что это применимо только к спецификации EJB. Кто бы ни написал это в то время, он был введен в заблуждение, что EJB станет основой всей Java EE и поэтому в значительной степени равен Java EE. - person dexter meyers; 04.09.2015

Если вы знаете, что никогда не будете кластеризовать свое приложение (или что вы сможете подключить диск к сети), просто используйте java.io.*.

Обязательно введите правильную конфигурацию в отношении корневого расположения вашего хранилища файлов.

person flybywire    schedule 31.08.2009
comment
+1 Этот ответ просто здравый смысл. Если файл заполняется другой программой (не совместимой с EJB), более быстрого и понятного способа сделать это не существует. - person ATorras; 31.08.2009
comment
Написав приложение, которое не соответствует спецификации Java EE, вы не можете быть уверены в его переносимости и удобстве сопровождения. Например, через 12 месяцев вы, возможно, оставили этот проект позади с большим сюрпризом для бедного человека, получившего задачу кластеризации вашего приложения. Или перенос его в другой контейнер. - person oxbow_lakes; 31.08.2009
comment
Если вы знаете, что никогда не будете кластеризовать свое приложение — если вы обнаружите, что можете заглянуть в будущее, вы можете подумать, что в индустрии азартных игр манит более прибыльная карьера. - person oxbow_lakes; 31.08.2009
comment
+1 Я думаю, это просто зависит от требований. Кстати, я отправил много резюме ;) - person ATorras; 31.08.2009
comment
@oxbow_lakes проектировать будущее, которое вам не нужно ни сегодня, ни завтра — тоже плохая практика. Я видел, как люди полностью усложняли свой дизайн, чтобы быть гибкими в будущем, но вся эта предполагаемая гибкость не использовалась ни разу после 10 лет жизни. Все это время он действительно замедлял все виды задач. Как всегда, руководствуйтесь здравым смыслом. - person Mike Braun; 26.11.2012
comment
Часто эти сложные сейчас для будущего методы в конечном итоге даже не подходят в будущем, и в любом случае никогда не используются в пользу огромного переписывания. - person trognanders; 14.06.2013

Инкапсулируйте свой доступ к данным файла. Затем вы можете использовать любой из методов, описанных выше. Даже использовать базу данных. Измерьте производительность вашей системы. Если он соответствует требованиям, то все готово. Если нет, доступ к вашему файлу локализован в одном месте, и вы можете заменить его другим решением. То же преимущество, если программное обеспечение должно быть перенесено в другой контейнер и/или должно поддерживаться кем-то другим.

person Conor    schedule 31.08.2009

Обычный доступ к файлам не является транзакционным по своей природе. Если вы не встроите поддержку транзакционных операций (я понятия не имею, как это сделать — это работа менеджера ресурсов), вам придется беспокоиться о транзакционной семантике выполняемой вами операции. Если вы встроите поддержку транзакций, вы получите очень мало производительности (некоторая потеря производительности в базах данных связана со всей бухгалтерией, выполняемой менеджером ресурсов). И не забывайте о близком родственнике управления транзакциями — параллелизме. Если вы не начнете писать в новый файл для каждого запроса, проблемы параллелизма будут более или менее кусать вас.

Дополнительную информацию можно найти в часто задаваемых вопросах Sun Blueprint об ограничениях EJB.

Если вы не находитесь в чистоте с хорошим техническим обоснованием, вам не следует пытаться получить доступ к файловой системе из EJB. Очень хорошим примером может быть фреймворк ведения журнала (а не аудита) — доступ к файловой системе для записи файлов журнала наносит относительно меньший вред, учитывая, что ведение журнала не обязательно должно быть операцией транзакции, т. е. вам не нужно откатывать записи в журнальный файл; не то, чтобы было приемлемо иметь частичную запись.

person Vineet Reynolds    schedule 31.08.2009
comment
Локальное кэширование файлов с помощью Singleton/timer — еще один пример операции, которая почти всегда безопасна. - person Mike Braun; 26.11.2012
comment
Если [...] вы не должны пытаться получить доступ к файловой системе из EJB - нет абсолютно никакой конкретной причины, по которой это должно выполняться только для EJB. Следует соблюдать осторожность при выполнении операций ввода-вывода из компонентов любого типа, а не только из компонентов, которые оказались EJB-бинами. - person dexter meyers; 04.09.2015