2009-08-31 37 views
23

Tôi muốn biết làm cách nào để truy cập hệ thống tệp từ một hạt EJB 3?Cách truy cập hệ thống tệp từ EJB 3?

Tôi đã tìm kiếm trên Internet về chủ đề và chưa tìm thấy câu trả lời hay.

Một số đề xuất sử dụng java.io/java.nio mặc dù đặc điểm kỹ thuật cấm sử dụng này. Hầu hết các máy chủ ứng dụng dường như vẫn cho phép truy cập vào API này.

Một ý tưởng khác là sử dụng trình kết nối JCA để truy cập hệ thống tệp hoặc thư mục LDAP.

Tôi muốn làm điều này để tránh việc sử dụng BLOB trong cơ sở dữ liệu khi một tệp đơn giản sẽ là giải pháp tốt hơn nhiều về hiệu suất và tài nguyên được sử dụng.

Bạn giải quyết vấn đề này như thế nào?

+1

Bạn không cần phải có BLOB trong cơ sở dữ liệu. SQL Server 2008 hỗ trợ lưu trữ filestream mà về cơ bản đổ tập tin vào một thư mục trên máy chủ DB nhưng để lộ nó thông qua cơ sở dữ liệu. http://blogs.msdn.com/rdoherty/archive/2007/10/12/getting-traction-with-sql-server-2008-filestream.aspx – pjp

Trả lời

9

Lý do mà bạn không được phép từ truy cập hệ thống tập tin trong EJB là bạn đã không kiểm soát như thế nào ứng dụng của bạn chạy trong vòng một (Java EE) container. Ví dụ, ứng dụng của bạn có thể được chạy trên một cụm máy chủ, trong trường hợp đó, việc lưu một số đối tượng vào một thư mục trên một máy chủ có thể sẽ ít được sử dụng. (Tất nhiên, bạn có thể có một hệ thống tập tin mạng, do đó có thể không áp dụng giới hạn này).

Một lựa chọn có thể là sử dụng các JNDI thực hiện mà đi kèm với bạn container. Bạn có thể sẽ có thể tiết kiệm một byte[] mảng thô tại một số vị trí JNDI, vì vậy bạn luôn có thể tiết kiệm xuống dưới hình thức tuần tự của đối tượng:

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

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

này có thể được nhìn lên sau đó và lại chuyển đổi thành đối tượng của bạn:

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

Hoặc bạn có thể sử dụng java.beansdai dẳng XML (tức XMLDecoder, XMLEncoder) để mã hóa Ví dụ bạn như là một chuỗi XML một lưu đó vào JNDI.

+0

Đây có phải là cách được khuyến nghị để viết các tệp từ EJB không? Liệu tệp có sẵn cho mọi nút trong một cụm (tôi nghĩ rằng JNDI thực sự được nhóm lại vì vậy có lẽ có)? Lần đọc cuối cùng (hoặc viết từ) JNDI là giao dịch? –

+0

"bạn không được phép" - bạn không còn được phép truy cập vào hệ thống tệp và không bao giờ có ý định rằng điều này chỉ áp dụng cho đặc tả EJB. Bất cứ ai đã viết rằng vào thời điểm đó đã được lừa gạt rằng EJB sẽ là nền tảng của tất cả các Java EE và có khá nhiều bằng Java EE. –

7

Nếu bạn biết bạn sẽ không bao giờ nhóm ứng dụng của bạn (hoặc bạn sẽ có thể nối mạng ổ đĩa) thì chỉ cần sử dụng java.io. *.

Hãy chắc chắn giới thiệu cấu hình thích hợp về vị trí gốc của lưu trữ tệp của bạn.

+0

+1 Câu trả lời này chỉ là * ý thức chung *. Nếu tệp được lấp đầy bởi một chương trình khác (không tuân theo EJB) thì không có cách nào nhanh hơn và * rõ ràng * để thực hiện nó. – ATorras

+2

Bằng cách viết một ứng dụng không tuân theo đặc tả Java EE, bạn không thể chắc chắn rằng ứng dụng đó có thể di chuyển và bảo trì được. Ví dụ: trong thời gian 12 tháng, bạn có thể đã bỏ lại dự án này với một bất ngờ lớn cho người nghèo vì nhiệm vụ phân cụm ứng dụng của bạn. Hoặc chuyển nó vào một container khác. –

+7

* "Nếu bạn biết bạn sẽ không bao giờ nhóm ứng dụng của bạn" * - nếu bạn thấy rằng bạn có thể nhìn thấy trong tương lai, bạn có thể nghĩ rằng có một sự nghiệp sinh lợi hơn trong ngành công nghiệp cờ bạc. –

5

Đóng gói quyền truy cập của bạn vào dữ liệu tệp. Sau đó, bạn có thể sử dụng bất kỳ phương pháp nào được nêu ở trên. Thậm chí sử dụng cơ sở dữ liệu. Đo hiệu suất của hệ thống của bạn. Nếu nó đáp ứng yêu cầu thì bạn đã hoàn thành. Nếu không truy cập tệp của bạn được bản địa hóa ở một nơi và bạn có thể thay thế một giải pháp khác. Cùng một lợi ích nếu phần mềm phải được chuyển đến một container khác và/hoặc phải được duy trì bởi người khác.

+0

+1 để đóng gói – flybywire

1

Truy cập tệp thuần túy không phải là giao dịch trong tự nhiên. Trừ khi bạn xây dựng hỗ trợ cho các hoạt động giao dịch (tôi không biết làm thế nào - đây là công việc của một người quản lý tài nguyên), bạn sẽ phải lo lắng về ngữ nghĩa giao dịch của hoạt động mà bạn đang thực hiện. Nếu bạn xây dựng trong hỗ trợ giao dịch, có rất ít bạn sẽ đạt được trong hiệu suất (một số mất hiệu suất trong cơ sở dữ liệu, là do tất cả các sổ sách kế toán được thực hiện bởi người quản lý tài nguyên). Và đừng quên người anh em họ của quản lý giao dịch - đồng thời.Trừ khi bạn bắt đầu viết vào một tập tin mới cho mọi yêu cầu, các vấn đề tương tranh sẽ ít nhiều cắn bạn.

Bạn sẽ tìm thấy nhiều thông tin hơn trong số Sun Blueprint's FAQ on EJB restrictions.

Trừ khi bạn rõ ràng với một biện minh kỹ thuật tốt, bạn không nên cố gắng truy cập hệ thống tệp từ EJB. Một ví dụ rất tốt, sẽ là một khung công tác ghi nhật ký (không kiểm toán) - có ít tác hại hơn trong việc truy cập hệ thống tệp để ghi các tệp nhật ký, vì việc ghi nhật ký đó không phải là một hoạt động giao dịch nghĩa là bạn không cần khôi phục ghi logfile; không phải là chấp nhận được viết một phần.

+0

Lưu tập tin cục bộ qua Singleton/timer là một ví dụ khác về thao tác khá an toàn. –

+1

"Trừ khi [...] bạn không nên cố gắng truy cập hệ thống tập tin từ EJB" - hoàn toàn không có lý do cụ thể tại sao điều này chỉ nên giữ cho EJB. Người ta phải thận trọng khi thực hiện IO từ * mọi loại đậu *, không chỉ các hạt đậu xảy ra là đậu EJB. –

Các vấn đề liên quan