Вы можете протестировать истекшие сеансы, установив, что HttpServletRequest#getRequestedSessionId()
не возвращает null
(что означает, что клиент отправил куки-файл сеанса и, следовательно, предполагает, что сеанс по-прежнему действителен) и HttpServletRequest#isRequestedSessionIdValid()
возвращает false
(что означает, что сеанс истек на стороне сервера).
В гайке:
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);
if (request.getRequestedSessionId() != null && !request.isRequestedSessionIdValid()) {
response.sendRedirect(request.getContextPath() + "/sessionexpired.jsp");
} else if (session == null || session.getAttribute("user") == null) {
response.sendRedirect(request.getContextPath() + "/login.jsp");
} else {
chain.doFilter(request, response);
}
}
Не нужно беспокоиться о дополнительных файлах cookie. Сопоставьте это Filter
на url-pattern
, защищенном защищенными страницами (и, таким образом, исключая страницы сеанса и страницы входа!).
Не забудьте отключить кеширование страницы браузером на защищенных страницах, иначе веб-браузер загрузит их из кеша, когда вы вернетесь в историю браузера, вместо отправки нового запроса на сервер. Вы можете добиться этого, выполнив следующее в том же фильтре, перед вызовом Chain#doFilter()
.
response.setHeader("Cache-Control", "no-cache, no-store, must-revalidate"); // HTTP 1.1.
response.setHeader("Pragma", "no-cache"); // HTTP 1.0.
response.setDateHeader("Expires", 0); // Proxies.
Да, первая функция не имеет отношения к экземпляру объекта этой функции-конструктора , вы можете рассматривать ее как «статический метод» .
В JavaScript функции являются объектами первого класса , это означает, что вы можете обращаться с ними так же, как с любым объектом, в этом случае вы только добавляете свойство к объекту функции .
Вторая функция, поскольку вы расширяете прототип функции конструктора, она будет доступна для всех экземпляров объекта, созданных с помощью ключевого слова new
, и контекста внутри этой функции ( this
) будет относиться к фактическому экземпляру объекта, в котором вы его вызываете.
Рассмотрим этот пример:
// constructor function
function MyClass () {
var privateVariable; // private member only available within the constructor fn
this.privilegedMethod = function () { // it can access private members
//..
};
}
// A 'static method', it's just like a normal function
// it has no relation with any 'MyClass' object instance
MyClass.staticMethod = function () {};
MyClass.prototype.publicMethod = function () {
// the 'this' keyword refers to the object instance
// you can access only 'privileged' and 'public' members
};
var myObj = new MyClass(); // new object instance
myObj.publicMethod();
MyClass.staticMethod();