2010-05-10 34 views
5

tôi đang cố gắng để có được những FacesContext bằng cách gọi FacesContext.getCurrentInstance() trong phương pháp run() của một lớp Runnable, nhưng nó sẽ trả về null.FacesContext.getCurrentInstance() trả về null trong lớp Runnable

public class Task implements Runnable { 

    @Override 
    public void run() { 
     FacesContext context = FacesContext.getCurrentInstance(); // null! 
     // ... 
    } 

} 

Điều này gây ra như thế nào và làm cách nào để giải quyết?

Trả lời

12

FacesContext được lưu trữ dưới dạng biến số ThreadLocal trong chuỗi chịu trách nhiệm cho yêu cầu HTTP gọi ra FacesServlet, người chịu trách nhiệm tạo FacesContext. Chủ đề này thường chỉ đi qua các phương thức bean được quản lý JSF. Các FacesContext không có sẵn trong các chủ đề khác sinh ra bởi chủ đề đó.

Bạn thực sự cũng không cần đến nó trong các chủ đề khác. Hơn nữa, khi chuỗi của bạn bắt đầu và chạy độc lập, yêu cầu HTTP bên dưới sẽ ngay lập tức tiếp tục xử lý phản hồi HTTP và sau đó biến mất. Bạn sẽ không thể thực hiện điều gì đó với phản hồi HTTP.

Bạn cần giải quyết vấn đề của mình theo cách khác. Hãy tự hỏi mình: bạn cần nó để làm gì? Để có được một số thông tin? Chỉ cần vượt qua thông tin cho số Runnable trong quá trình xây dựng để thay thế.

Ví dụ dưới đây giả định rằng bạn muốn truy cập vào một số đối tượng phạm vi phiên trong chuỗi.

public class Task implements Runnable { 

    private Work work; 

    public Task(Work work) { 
     this.work = work; 
    } 

    @Override 
    public void run() { 
     // Just use work. 
    } 

} 
Work work = (Work) FacesContext.getCurrentInstance().getExternalContext().getSessionMap().get("work"); 
Task task = new Task(work); 
// ... 

Nếu bạn tuy nhiên cuối cùng cần phải thông báo cho khách hàng ví dụ rằng công việc của luồng được hoàn thành, thì bạn nên tìm một giải pháp khác với ví dụ: thêm thông điệp khuôn mặt hoặc như vậy. Câu trả lời là sử dụng "đẩy". Điều này có thể đạt được với SSE hoặc websockets. Ví dụ về websockets cụ thể có thể được tìm thấy trong câu hỏi liên quan này: Real time updates from database using JSF/Java EE. Trong trường hợp bạn sử dụng PrimeFaces, hãy xem <p:push>. Trong trường hợp bạn sử dụng OmniFaces, hãy xem <o:socket>.


Không liên quan cho vấn đề cụ thể, bằng tay tạo Runnable s và tự sinh sản chủ đề trong một ứng dụng web Java EE là đáng báo động. Đi đến sau Q & A đến tìm hiểu về tất cả hãy cẩn thận và làm thế nào nó thực sự cần được thực hiện: