Вопросик из области Web-Programmierung, Java
Еще видно что CURRENT_LOGIN, LAST_ACTION_TIME в сессии есть. Или вы не перенсли эту строчку в начало doPost-а?
Почему у вас два раза выдается лог для поста (разный)? Но хэши запросов - разные. Объекты значит разные. Почему строчки отличаются?
10.09.2015 16:07:53 I: PP_Servlet (16:07:53):ndServlet@1155286236.doPost request@126617484 URL: /ICM6/servlet/de.novadata.pp.servlet.ndServlet sessionID from cookie? true or from URL? false Stacktrace:
10.09.2015 16:07:53 I: PP_Servlet (16:07:53):ndServlet@1155286236.doPost request@126486410 URL: /ICM6/servlet/de.novadata.pp.servlet.ndServlet Session@973355524 with ID 71AFAE004EC7552C250523BCBDD847F8 from cookie? true or from URL? false Stacktrace: java.lang.Exception
Почему стэктрейса нет в логах? Вы выдачу стектрейса поправили, как я писал?
Вообще, что у вас сейчас в doPost() и в init() получилось? Скопируйте их в текстовый файл и притожите к сообщению.
Чтобы разобраться с doPost-ом добавьте в начала и в конец сетода строчку в лог, вроде
showInfo(getClass().getName()+"@"+hashCode()+".doPost START Request: "+request.getClass().getName()+"@"+request.hashCode()); // первой строчкой
showInfo(getClass().getName()+"@"+hashCode()+".doPost STOP Request: "+request.getClass().getName()+"@"+request.hashCode()); // последней
Потом прогнав тест - найдите в логах и скопируйте ВСЕ логи между START и STOP с одним и тем же хэшем запроса.

Еще видно что CURRENT_LOGIN, LAST_ACTION_TIME в сессии есть. Или вы не перенсли эту строчку в начало doPost-а?
Перенес, но не стер в предыдущем месте. Поэтому 2 раза.
Еще раз, корректно-
Метода init:
11.09.2015 12:27:41 I: PP_Servlet (12:27:41):de.novadata.pp.servlet.ndServlet@1216497794.init() called. Servlet name: de.novadata.pp.servlet.ndServlet Context Name: Apache Tomcat/5.5.31
11.09.2015 12:27:41 I: PP_Servlet (12:27:41):Servlet configuration parameters: [HostName, Trace]
Как видите, инициализируется сервлет 1 раз.
Метода doPost вызывается несколько раз, его вызовы я записал в файл.
Почему стэктрейса нет в логах? Вы выдачу стектрейса поправили, как я писал?
Поправил:
showInfo("ndServlet@"+hashCode()+".doPost request@"+request.hashCode()+" URL: "+request.getRequestURI()+" Session@"+session.hashCode()+" with ID "+session.getId()+" from cookie? "
+ request.isRequestedSessionIdFromCookie()+" or from URL? "+request.isRequestedSessionIdFromURL()
+ " Stacktrace: "+writer.toString());
Enumeration<?> attributes = session.getAttributeNames();
Я не знаю, почему там java.lang.Exception.
Вообще, что у вас сейчас в doPost() и в init() получилось? Скопируйте их в текстовый файл и притожите к сообщению.
Текстовый файл приложить здесь почему-то невозможно, ни doc, ни txt. Только xml. Но попробую еще раз.
Чтобы разобраться с doPost-ом добавьте в начала и в конец сетода строчку в лог, вроде
Добавил.
Потом прогнав тест - найдите в логах и скопируйте ВСЕ логи между START и STOP с одним и тем же хэшем запроса.
Еще раз, если файл не пройдет:
- с запросом request@557326648 - много раз выдается
11.09.2015 12:29:43 I: PP_Servlet (12:29:43):doPost: ndServlet@1216497794.doPost request@557326648 URL: /ICM6/servlet/de.novadata.pp.servlet.ndServlet Session@1889038488 with ID 464079885C8AEC3968E75C57320389DB from cookie? true or from URL? false Stacktrace: java.lang.Exception
- с запросом request@280105138 много раз выдется
11.09.2015 12:31:43 I: PP_Servlet (12:31:43):doPost: ndServlet@1216497794.doPost request@280105138 URL: /ICM6/servlet/de.novadata.pp.servlet.ndServlet Session@1889038488 with ID 464079885C8AEC3968E75C57320389DB from cookie? true or from URL? false Stacktrace: java.lang.Exception
P.S. Как видите, если просто переименовать текстовый файл в xml, то показывается здесь только одна строчка.
В логи stacktrace может быть не попадает из-за переносов строки... Попробуйте так: замените
writer.toString()
на
java.util.Arrays.toString((new Exception()).getStackTrace())
Совершенно ненормально то, что с одним и тем же request-ом апплет вызывается много раз. Потом перерыв в пол-минуты и опять тот же реквест
12:27:44 ... de.novadata.pp.servlet.ndServlet@1216497794.doPost START Request: org.apache.catalina.connector.RequestFacade@557326648
12:28:13 ... de.novadata.pp.servlet.ndServlet@1216497794.doPost START Request: org.apache.catalina.connector.RequestFacade@557326648
Stacktrace.txt
Просто добавляетй к сообщению, перименовав в .xml Скачать и переименовать файл я в состоянии :)
Нужен новый лог (в нем-то стэктрейс есть?) и актуальный ndServlet.java
Прошу пардону.
А в чем разница?
А устанавливаем мы этот атрибут так:
session.setAttribute("CURRENT_LOGIN", "123");
Чтобы таких ошибок не случалось надо использовать константы.
С логикой пока чота не клеится. Проблема в том, что метод doPost() вызывается по многу раз для одного окна. Если я в нем делаю LogOff, то юзера вышибает уже при одном окне. Мне кажется, что всю эту логику надо перенести в init, но там нет request'a, а без него не вытаскивается сессия.
Могу ли я просто изменить jsessionid, если, к примеру, установлен тот же current_login?
(или то же самое с session.isNew()?)
Я перепробовал за эти 2 дня кучу решений, пользователи согласны даже на старт нового окна, чтобы в нем происходило перелогинивание, но всякий раз чего-то не хватает, в init - сессии, doPost - вызывается слишком часто уже внутри одного окна, и до логина, и после, и там еще вызываются какие-то дополнительные сервлеты, поэтому происходит путаница, в Authentification свои проблемки :(
Так что главная проблема сейчас - логика, не только когда перезапускать сессию или перелогиниваться, но и где.
Подскажите, пожалуйста, как перезапустить сессию в сервлете?
никак. "перезапустить" сессию нельзя. Можно существующую сделать недействительной - invalidate().
Но вам это не надо.
Установкой session.setMaxInactiveInterval(0)?
По явовской документации:
An interval value of zero or less indicates that the session should never timeout.
Но некоторые веб-контейнеры ведут себя как вы ожидали - при 0 тут же рушат сессию. Но как вел себя 5.5-й томкат я уже не помню, судя по вашему опыту - как положено по контракту метода.
doPost - вызывается слишком часто уже внутри одного окна
doPost вызывается каждый раз когда вы обращаетесь к сервету. sendRequest или как оно там.
У вас на каждое действие посылается объект определенного класса. При логине что-то там с AuthenticateUser, емнип.
Значит в doPost-е смотрите что вам прислали. Имя класса у вас и в content-type заголовке устанавливается (опять же если я правильно помню).
Смотрите что за объект к вам прислали. Если это AuthenticateUser значит идет попытка логина.
но и где.
doPost()
showInfo("doPost, getClass: " + getClass().getName()+"@"+hashCode()+".doPost
всегда выдает одно и то же, как попугай:
doPost: de.novadata.pp.servlet.ndServlet@1590451916.doPost.
То же самое и в init():
showInfo(getClass().getName()+"@"+hashCode()+".init() called. Servlet name: "+config.getServletName()+" Context Name: "+(config.getServletContext().getServerInfo()));
PP_Servlet (15:55:39):de.novadata.pp.servlet.ndServlet@725887812.init() called. Servlet name: de.novadata.pp.servlet.ndServlet Context Name: Apache Tomcat/5.5.31
showInfo("Servlet configuration parameters: "+Collections.list(config.getInitParameterNames()));
10.09.2015 13:45:54 I: PP_Servlet (13:45:54):Servlet configuration parameters: [HostName, Trace]
Я не знаю, как тут фильтровать этот базар на предмет того, откуда doPost вызывается, а при каждом обращении делать логаут, как Вы понимаете, невозможно.
sendRequest() существует как метод в классе GeneralServerAdapter_Servlet, но тоже нигде эксплицитно не вызывается.
Вытащить content-type из реквеста тоже не получается, request.getContentType() выдает всегда java-internal/de.novadata.pp.baseобжектс.ServletTransferОбжект
Вот все, что я смог вытащить из реквеста:
15.09.2015 23:38:13 I: PP_Servlet (23:38:13): \\\request.getParameterNames(): java.util.Hashtable$1@8400840 \\\request.getServletPath():
/servlet/de.novadata.pp.servlet.ndServlet \\\request.getMethod(): POST \\\request.getParameter(getServletInfo()): null \\\request.getContextPath(): /ICM6 \\\request.getContentType(): java-internal/de.novadata.pp.baseобжектs.ServletTransferОбжект
// first get the request Object
ObjectInputStream objIn = new ObjectInputStream(request.getInputStream());
ServletTransferObject objTransfer = (ServletTransferObject)objIn.readObject();
objIn.close();
Вы считали ServletTransferObject из запроса. Этот объект вы отправляли на сервлет из апплета. Посмотрите что в этот объект засовывается в апплете когда пользователь логинится и на стороне сервлета сравнивайте содержимое с ожидаемым для аутентификации.
напишите метод public boolean isAuthorizationRequest(ServletTransferObject)
doPost() нигде эксплицитно не вызывается
В вашем коде - нет. Его вызывает веб-контейнер. Томкат.
всегда выдает одно и то же, как попугай: doPost: de.novadata.pp.servlet.ndServlet@1590451916.doPost.
Потому что она выдает имя класса сервлета. С чего бы ему меняться?
Я не знаю, как тут фильтровать этот базар на предмет того, откуда doPost
Не откуда, а с какими данными в HttpRequest-е. Вы уже разобрались как в принципе работает общение клиента с сервлетом?
вчерашний день выпал у меня для тестирования, сегодня я попробовал реализовать Вашу идею.
При логине можно отследить, что идет обращение сервера аутентификации, но это обращение
происходит ровно 20 раз, т.е. 20 раз повторяется строчка типа
17.09.2015 12:41:03 I: PP_Servlet (12:41:03):1: objTransfer: objTransfer.getAdapterClass():
de.novadata.pp.authenticationdomain.AuthenticationServerAdapter_RMI ###objTransfer.getAdapterMethod(): getForcedLogOff
###objTransfer.getArgumentClass()de.novadata.pp.authenticationdomain.AuthenticationData ###objTransfer.toString():
de.novadata.pp.baseОбжектs.ServletTransferОбжект@79487948 ###objTransfer.getClass(): class
de.novadata.pp.baseОбжектs.ServletTransferОбжект ###objResult.getClass(): class java.lang.Boolean ###objResult.toString(): false
Это вся инфа, которую мне удалось вытащить из objTransferОбжекта, objResult
Мне нужно каким-то образом определить первое обращение сервера аутентификации к сервлету.
1. Еще до логина тоже есть одно обращение от сервера аутентификации:
17.09.2015 13:22:22 I: PP_Servlet (13:22:22):1: objTransfer: objTransfer.getAdapterClass():
de.novadata.pp.authenticationdomain.AuthenticationServerAdapter_RMI ###objTransfer.getAdapterMethod(): getAccessTimeExpiration
###objTransfer.getArgumentClass()de.novadata.pp.authenticationdomain.AuthenticationData ###objTransfer.toString():
de.novadata.pp.baseОбжектs.ServletTransferОбжект@f160f16 ###objTransfer.getClass(): class
de.novadata.pp.baseОбжектs.ServletTransferОбжект ###objResult.getClass(): class java.lang.String ###objResult.toString(): 432000000
Это обращение отличается от других только тем, что objResult - это большое число, а не буквенная строка,
но число это, естественно, тоже выдается в виде строки. Из самого objResult мне пока не удалось выудить инфу,
objResult.getClass(), естественно, class java.lang.String.
2. Потом я делаю логин. Идут эти 20 строчек/обращений к сервлету, которые я обозначил выше.
Класс резалта во всех случаях - java.lang.Boolean, а значение - false
Разница между первым обращением:
17.09.2015 12:41:03 I: PP_Servlet (12:41:03):1: objTransfer: objTransfer.getAdapterClass():
de.novadata.pp.authenticationdomain.AuthenticationServerAdapter_RMI ###objTransfer.getAdapterMethod(): getForcedLogOff
###objTransfer.getArgumentClass()de.novadata.pp.authenticationdomain.AuthenticationData ###objTransfer.toString():
de.novadata.pp.baseОбжектs.ServletTransferОбжект@79487948 ###objTransfer.getClass(): class
de.novadata.pp.baseОбжектs.ServletTransferОбжект ###objResult.getClass(): class java.lang.Boolean ###objResult.toString(): false
и вторым:
17.09.2015 12:41:06 I: PP_Servlet (12:41:06):1: objTransfer: objTransfer.getAdapterClass():
de.novadata.pp.authenticationdomain.AuthenticationServerAdapter_RMI ###objTransfer.getAdapterMethod(): getForcedLogOff
###objTransfer.getArgumentClass()de.novadata.pp.authenticationdomain.AuthenticationData ###objTransfer.toString():
de.novadata.pp.baseОбжектs.ServletTransferОбжект@3c623c62 ###objTransfer.getClass(): class
de.novadata.pp.baseОбжектs.ServletTransferОбжект ###objResult.getClass(): class java.lang.Boolean ###objResult.toString(): false
только в значении обжекта, в первом случае это 79487948, во втором - 3c623c62, в третьем - df40df4 и т.д.
В методе sendRequest(Serializable obj) я выдаю в логи следующую инфу:
showInfo("Open connection to servlet: " + m_servlet.toString());
17.09.2015 11:49:19 I: AdapterServlet (11:49:19):Open connection to servlet:
http://sv062919.-----:8160/ICM6/servlet/de.novadata.pp.servlet.ndServlet
showInfo(" sendRequest, Serializable obj: " + out.toString() + " ###" + m_connection.getInputStream());
17.09.2015 12:10:23 I: AdapterServlet (12:10:23): sendRequest, Serializable obj: java.io.ОбжектOutputStream@d38976
###sun.net.www.protocol.http.HttpURLConnection$HttpInputStream@1162a9c
Эта инфа тоже всегда очень похожа, кроме значений типа "@d38976", так что я и тут не могу выделить первый случай обращения к сервлету для логина.
P.S. При первом обращении сервера аутентификации к сервлету нашел-таки одно отличие:
AdapterMethod - getAccessTimeExpiration
А потом, при логине, этот метод getForcedLogOff.