2013-03-22 27 views
10

Tôi đã xem nhiều bài viết về chủ đề này nhưng không thể nhận được giải pháp hoạt động trong trường hợp của tôi.Chuyển hướng sau thời gian HttpSession ra

Tôi đang sử dụng Java EE 6 với JSF 2.0 (triển khai trên JBoss AS 7.1)

Trong web.xml của tôi, tôi có:

<session-config> 
     <session-timeout>1</session-timeout> 
    </session-config> 

và tôi muốn người dùng được chuyển hướng đến trang đăng nhập khi phiên tự động hết giờ.

những gì tôi đã cố gắng:

Cách tiếp cận 1: sử dụng bộ lọc

Tôi đã thử các bộ lọc sau:

@WebFilter() 
public class TimeOutFilter implements Filter { 

     @Override 
     public void init(FilterConfig filterConfig) throws ServletException { 
     } 

     @Override 
     public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, 
     ServletException { 
     System.out.println("filter called"); 
     final HttpServletRequest req = (HttpServletRequest) request; 
     final HttpSession session = req.getSession(false); 
     if (session != null && !session.isNew()) { 
      chain.doFilter(request, response); 
     } else { 
      System.out.println("Has timed out"); 
      req.getRequestDispatcher("/logon.xthml").forward(request, response); 
     } 
    } 

    @Override 
    public void destroy() { 
    } 
} 

Trong web.xml Tôi đã thử

<filter-mapping> 
    <filter-name>TimeOutFilter</filter-name> 
    <url-pattern>*.xhtml</url-pattern> 
</filter-mapping> 

<filter-mapping> 
    <filter-name>TimeOutFilter</filter-name> 
    <servlet-name>Faces Servlet</servlet-name> 
</filter-mapping> 

Bộ lọc hoạt động như được gọi trên mọi yêu cầu (ghi nhật ký "fiter được gọi là" trong bảng điều khiển). Tuy nhiên, nó không được gọi khi phiên họp hết giờ.

Phương pháp 2: HttpSessionLister

Tôi đã cố gắng sử dụng một HttpSessionListerner. Phương thức được gọi có chữ ký sau:

public void sessionDestroyed(HttpSessionEvent se) { 
} 

Tôi không thể chuyển hướng đến một trang cụ thể. Khi tôi muốn chuyển hướng người dùng, tôi thường sử dụng số NavigationHandler từ FacesContext nhưng trong trường hợp này không có FacesContext (FacesContext.getCurrentInstance() trả về null).

Theo điều này post, HttpListener không thể chuyển hướng người dùng vì nó không phải là một phần của yêu cầu.

Câu hỏi

cách tốt nhất để đi đến giải quyết vấn đề này là gì? Tôi có thể làm gì để thực hiện một trong hai cách tiếp cận trên để làm việc?

+1

liên quan: http://stackoverflow.com/q/ 4992526/1065197 –

+0

@LuiggiMendoza: Cảm ơn bạn rất thú vị. Mặc dù tôi chưa bao giờ thấy 'ViewExpiredException' và tôi muốn, nếu có thể, để chuyển hướng đến trang đăng nhập mà không cần người dùng phải nhấp vào bất kỳ thứ gì. – phoenix7360

+0

Bạn cần một số hình thức bỏ phiếu ở phía khách hàng để kích hoạt 302 ở phía máy chủ của bạn. một nhịp tim ... –

Trả lời

15

Bạn không thể gửi phản hồi HTTP miễn là khách hàng chưa gửi yêu cầu HTTP. Đơn giản như thế. Đó chỉ là cách HTTP hoạt động. Internet nếu không sẽ có vẻ rất khác nhau nếu bất kỳ trang web đã có thể unaskingly đẩy một phản ứng HTTP mà không có khách hàng có yêu cầu cho nó.

Một JavaScript dựa nhịp tim dựa trên hoạt động bàn phím/chuột của khách hàng như là trả lời here, hoặc một meta refresh tiêu đề như là đã trả lời here sẽ là giải pháp nếu bạn đã cơ bản là một webapp một trang (do đó, bạn có hiệu quả không sử dụng phạm vi phiên nhưng phạm vi xem), nhưng điều đó sẽ không hoạt động độc đáo nếu bạn đã mở trang trong nhiều tab/cửa sổ trong cùng một phiên.

Websockets về lý thuyết là giải pháp phù hợp để thúc đẩy một cái gì đó cho khách hàng, nhưng điều này đòi hỏi phải lần lượt một phiên hoạt động. Vấn đề về trứng gà. Ngoài ra, nó sẽ không hoạt động trong các trình duyệt cũ hơn hiện vẫn còn tương đối rộng rãi trong sử dụng, do đó, nó hiện chỉ nên được sử dụng để tăng cường tiến bộ.

Đặt cược tốt nhất của bạn là chỉ xác định một trang lỗi liên quan đến vụ việc khi người dùng cuối gọi một hành động trong khi phiên hết hạn. Xem thêm javax.faces.application.ViewExpiredException: View could not be restored.

+1

Tôi bây giờ thấy sự hiểu lầm của tôi. Thay vì tự động chuyển hướng người dùng, tôi cần một cái gì đó để cho người dùng biết liệu cô ấy có thực hiện một hành động sau khi phiên hết hạn hay không. – phoenix7360

-1

Tôi hiểu rằng bạn đang sử dụng java-EE6 và JSF, nhưng nếu bạn có thể thử sử dụng mã JSP hoặc chuyển đổi mã này bên dưới để hoạt động trong servlet. Giả sử bạn đang sử dụng tên người dùng để kiểm tra phiên, sau khi thiết lập thời gian chờ phiên trong tệp web.xml. Xin lưu ý rằng mã JSP và mã servlet là tương tự. Mã của bạn để xác thực phiên có thể trông như thế này (Định dạng JSP) Nếu tên người dùng đóng vai trò là khóa chính trong cơ sở dữ liệu của bạn.

<% 
    String un = (String)session.getAttribute("un"); 

    if(un == null){ 
    response.sendRedirect(login page); 
    return; 
}else{ 
     code to process login form 
} 
    %> 

đang Servlet có thể trông như thế này

String un = (String)session.getAttribute("un"); 
if(un == null){ 
    response.sendRedirect(loginPage); 
} 
0

Trong HttpSessionListerner bạn không thể gửi bất kỳ phản ứng để người dùng. Một cách tốt để đạt được điều này là bằng cách bỏ phiếu, trình duyệt gửi yêu cầu HTTP theo chu kỳ đều đặn và ngay lập tức nhận được phản hồi.
Có rất nhiều cách để làm điều đó:

  1. Bạn có thể sử dụng đồng bằng javascript cũ để thăm dò ý kiến: Điều này sẽ làm việc trong môi trường trình duyệt chéo.

    chức năng làm mới() {

    // make Ajax call here, inside the callback call: 
    
    setTimeout(refresh, 5000); 
    
    // ... 
    

    }

    // initial call, or just call refresh directly 
    

    setTimeout (refresh, 5000);

  2. Bạn có thể sử dụng Sockets Web. đặc điểm kỹ thuật ổ cắm Web có mặt trên dưới liên kết:

    http://dev.w3.org/html5/websockets/

-1

Bạn có thể sử dụng một bộ lọc và làm bài kiểm tra sau:

HttpSession session = request.getSession(false); 
if(session != null && !session.isNew()) { 
    chain.doFilter(request, response); 
} 
else {enter code here 
    response.sendRedirect("/login.jsp"); 
} 
Các vấn đề liên quan