2009-06-22 38 views
38

Tôi đang chạy một ứng dụng web trong JBoss AS 5. Tôi cũng có một bộ lọc servlet chặn tất cả các yêu cầu đến máy chủ. Bây giờ, tôi muốn chuyển hướng người dùng đến trang đăng nhập, nếu phiên đã hết hạn. Tôi cần phải làm điều này 'isSessionExpired()' kiểm tra trong bộ lọc và cần phải chuyển hướng người dùng cho phù hợp. Tôi phải làm nó như thế nào? Tôi đang đặt giới hạn thời gian phiên của mình trong web.xml, như sau:Cách chuyển hướng đến trang Đăng nhập khi Phiên hết hạn trong ứng dụng web Java?

<session-config> 
    <session-timeout>15</session-timeout> 
</session-config> 
+0

Tại sao không sử dụng một SessionListener và chuyển hướng trên phiên bị phá hủy? –

+4

@Mr_and_Mrs_D: vì không nhất thiết phải có yêu cầu HTTP trong quá trình hủy phiên. – BalusC

Trả lời

50

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

HttpSession session = request.getSession(false);// don't create if it doesn't exist 
if(session != null && !session.isNew()) { 
    chain.doFilter(request, response); 
} else { 
    response.sendRedirect("/login.jsp"); 
} 

Đoạn mã trên là chưa được kiểm tra.

Tuy nhiên, đây không phải là giải pháp mở rộng nhất. Bạn cũng nên kiểm tra rằng một số đối tượng hoặc cờ cụ thể theo miền có sẵn trong phiên trước khi giả sử rằng vì phiên không phải là mới mà người dùng phải đăng nhập. Hãy là người hoang tưởng!

+0

cách "chuỗi" được đặt ở trên mã này? – MacGyver

+0

Vâng, đó là sự thật. Đó sẽ là đối số thứ 3 (giá trị được truyền vào) cho tham số thứ 3 tùy chọn (cho định nghĩa phương thức) trong phương thức, nhưng doFilter là một phương thức của đối tượng "chuỗi" trong mã của bạn. "Chuỗi" được đặt ở đâu trên dòng mã đó trong mã nguồn của bạn? – MacGyver

+0

Tôi không biết bạn đang đề cập đến những thông số thứ 3 tùy chọn nào. Biến 'chain' được truyền vào để bạn thực hiện' doFilter', bởi vùng chứa. Nó được ngụ ý trong câu trả lời này rằng mã nằm bên trong 'doFilter'. –

5

Kiểm tra phiên là mới.

HttpSession session = request.getSession(false); 
if (!session.isNew()) { 
    // Session is valid 
} 
else { 
    //Session has expired - redirect to login.jsp 
} 
+9

Đoạn mã của bạn dễ bị ngoại lệ con trỏ null. Việc chuyển false đến 'getSession' sẽ không tạo ra một session nếu một session không tồn tại và do đó sẽ trả về null. –

+1

'session! = Null &&! Session.isNew()' nên làm việc mặc dù;) – Yeti

+0

@Yeti, sau đó tại sao để kiểm tra isNew() ở tất cả khi chúng ta có thể làm tương tự với một kiểm tra null !! :) – Jaikrat

-2

Khi các bản ghi sử dụng trong, đặt tên người dùng của nó trong phiên:

`session.setAttribute("USER", username);` 

Vào đầu mỗi trang, bạn có thể làm điều này:

<% 
String username = (String)session.getAttribute("USER"); 
if(username==null) 
// if session is expired, forward it to login page 
%> 
<jsp:forward page="Login.jsp" /> 
<% { } %> 
+4

Mã được sao chép không phải là DRY. Sử dụng Bộ lọc. Xem thêm http://stackoverflow.com/questions/3177733/how-to-avoid-java-code-in-jsp-files – BalusC

+2

Giải pháp hoàn toàn ghê gớm! – Kong

4

Bên trong bộ lọc tiêm JavaScript này mà sẽ mang trang đăng nhập như thế này. Nếu bạn không thực hiện điều này thì trong cuộc gọi AJAX, bạn sẽ nhận được trang đăng nhập và nội dung của trang đăng nhập sẽ được thêm vào.

Bên trong bộ lọc của bạn hoặc chuyển hướng chèn script này để đáp ứng:

String scr = "<script>window.location=\""+request.getContextPath()+"/login.do\"</script>"; 
response.getWriter().write(scr); 
8

bạn cũng có thể làm điều đó với một bộ lọc như thế này:

public class RedirectFilter implements Filter { 

public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { 
    HttpServletRequest req=(HttpServletRequest)request; 

    //check if "role" attribute is null 
    if(req.getSession().getAttribute("role")==null) { 
     //forward request to login.jsp 
     req.getRequestDispatcher("/login.jsp").forward(request, response); 
    } else { 
     chain.doFilter(request, response); 
    } 
} 
} 

bạn sẽ nhìn thấy phần còn lại trong này tutorial

+0

Điều này cũng có thể ném một ngoại lệ con trỏ NULL khi bạn cố gắng đọc thuộc tính nếu getSession trả về null. – Swaprks

+1

Ngoài ra, bạn có thể có một số trang mà người dùng không đăng nhập. Tức là trang đăng ký mà bạn sẽ không nhận được bất kỳ vai trò nào. –

1

Cho đến khi hết giờ phiên, chúng tôi nhận được yêu cầu bình thường, sau đó chúng tôi nhận được yêu cầu Ajax. Chúng ta có thể xác định nó theo cách sau:

String ajaxRequestHeader = request.getHeader("X-Requested-With"); 
if ("XMLHttpRequest".equals(ajaxRequestHeader)) { 
    response.sendRedirect("/login.jsp"); 
} 
0

tôi tìm thấy giải pháp posible này:

public void logout() { 
    ExternalContext ctx = FacesContext.getCurrentInstance().getExternalContext(); 
    String ctxPath = ((ServletContext) ctx.getContext()).getContextPath(); 
    try { 
     //Use the context of JSF for invalidate the session, 
     //without servlet 
     ((HttpSession) ctx.getSession(false)).invalidate(); 
     //redirect with JSF context. 
     ctx.redirect(ctxPath + "absolute/path/index.jsp"); 
    } catch (IOException ex) { 
     System.out.println(ex.getMessage()); 
    } 
} 
14

Làm thế nào để chuyển hướng đến trang đăng nhập khi phiên hết hạn trong ứng dụng web Java?

Đây là câu hỏi sai. Bạn nên phân biệt giữa các trường hợp "Người dùng chưa đăng nhập" và "Phiên hết hạn". Về cơ bản, bạn muốn chuyển hướng đến trang đăng nhập khi người dùng không đăng nhập. Không phải khi phiên hết hạn. Câu trả lời hiện được chấp nhận chỉ kiểm tra HttpSession#isNew(). Nhưng điều này rõ ràng là không thành công khi người dùng đã gửi nhiều hơn một yêu cầu trong cùng một phiên khi phiên được tạo ngầm bởi JSP hoặc những gì không. Ví dụ. khi nhấn F5 trên trang đăng nhập.

Như đã nói, thay vào đó, bạn nên kiểm tra xem người dùng có đăng nhập hay không. Với thực tế là bạn đang hỏi loại câu hỏi này trong khi các khung xác thực chuẩn như j_security_check, Shiro, Spring Security, vv đã quản lý minh bạch điều này (và do đó sẽ không cần phải hỏi loại câu hỏi này), chỉ có thể có nghĩa là bạn đang sử dụng phương thức xác thực trong nhà.

Giả sử rằng bạn đang lưu trữ cho người dùng đăng nhập trong phiên làm việc trong một số đăng nhập servlet như dưới đây:

@WebServlet("/login") 
public class LoginServlet extends HttpServlet { 

    @EJB 
    private UserService userService; 

    @Override 
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 
     request.getRequestDispatcher("/WEB-INF/login.jsp").forward(request, response); 
    } 

    @Override 
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 
     String username = request.getParameter("username"); 
     String password = request.getParameter("password"); 
     User user = userService.find(username, password); 

     if (user != null) { 
      request.getSession().setAttribute("user", user); 
      response.sendRedirect(request.getContextPath() + "/home"); 
     } else { 
      request.setAttribute("error", "Unknown login, try again"); 
      doGet(request, response); 
     } 
    } 

} 

Sau đó, bạn có thể kiểm tra cho rằng trong một đăng nhập filter như dưới đây:

@WebFilter("/*") 
public class LoginFilter implements Filter { 

    @Override 
    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws ServletException, IOException {  
     HttpServletRequest request = (HttpServletRequest) req; 
     HttpServletResponse response = (HttpServletResponse) res; 
     HttpSession session = request.getSession(false); 
     String loginURI = request.getContextPath() + "/login"; 

     boolean loggedIn = session != null && session.getAttribute("user") != null; 
     boolean loginRequest = request.getRequestURI().equals(loginURI); 

     if (loggedIn || loginRequest) { 
      chain.doFilter(request, response); 
     } else { 
      response.sendRedirect(loginURI); 
     } 
    } 

    // ... 
} 

Không cần phải fiddle xung quanh với giòn HttpSession#isNew() kiểm tra.

2

Bạn cần triển khai giao diện HttpSessionListener, máy chủ sẽ thông báo thời gian chờ của phiên.

như thế này;

import javax.servlet.http.HttpSessionEvent; 
import javax.servlet.http.HttpSessionListener; 

public class ApplicationSessionListener implements HttpSessionListener { 

public void sessionCreated(HttpSessionEvent event) { 
    System.out.println("Session Created"); 
} 

public void sessionDestroyed(HttpSessionEvent event) { 
    //write your logic 
    System.out.println("Session Destroyed"); 
    } 
} 

Kiểm tra ví dụ này để hiểu rõ hơn

http://www.myjavarecipes.com/how-to-catch-session-timeouts/

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