Вопросик из области Web-Programmierung, Java
Я ведь запостил код сервлета, который Вы просили, а что еще надо?
Пока что в этих кусках кода не видно где же какое-то нестандартное поведение с сессией происходит.
Давайте так, я вам коротенько расскажу как обычно томкат работает с HttpSession.
1. Клиент запрашивает url http://myserver.com/myservlet
2. Http сервер передает запрос томкату (ну или сам томкат слушает 80-й порт).
3. Томкат смотрит - есть ли у запроса идентификатор сессии. Это или куки JSESSIONID или дополнение к URL, который выглядит тогда как http://myserver.com/myservlet;jsessionid=abcd1234
4. Если идентификатора нет, томкат создает новую сессию. Генерирует для нее ID и создает новый объект HttpSession. Если идентификатор и для него существует сессия, томкат берет cуществующий HttpSession
Томкат может поменять id сессии, в зависимости от настроек.
5. Томкат отвечат на запрос и передает ID текущей сессии или как куки в заголовке ответа "Set-Cookie" или переписывая все ссылки в ответе, добавляя к ним ;jsessionid=<текущий ID>
6. Клиент или сохраняет куки или просто использует переписанные ссылки.
N.B. Кстати, а посмотрите в каком месте в вашем коде пишется в лог "DCC_4 (25) I: request for access key: 540C407B5B9122D19AFC1588C2A49579". Узнаете откуда берется этот ID.
Вы уверены что общение с сервлетом идет через doRequest(ServletTransferObject). В этом методе не делается ничего чтобы передать томкату инормацию о сессии. Ни куки в заголовок не добавляются, ни ;jsessionid с текущим ID сессии. Из ответа новый JSESSIONID тоже не считывается. "Автоматически" это не происходит.
Итого. По увиденному коду я ожидаю новую HttpSession на томкате, каждый раз, когда на сервлет приходит запрос.
Если вы в данный момент отличать запущенные на одном компе копии апплета не можете, сделайте следующее:
1. При запуске апплета (в init-е) генерируйте MD5 хэш. Например из текущего времени и еще чего-нибудь случайного.
2. Расширьте ServlerTransferObject: добавьте поле appletId, в которое перед отравкой на сервер будете вписывать ид апплета.
3. На сервере в doPost читаем этот ID из запроса. Профит. Он и будет uniqueClientId из моего предыдущего примера.
Да, чтобы найти где же у вас конфигурация для ndServet-а поищите в вашем проекте или в томкатовском каталоге, куда сервлет деплоится, файл web.xml в котором содержатися параметры сервера "HostName", "HandleCommunication" и т.п. (см. код ndServlet.init(ServletConfig)). Выглядит это примерно так:
<init-param>
<param-name>HostName</param-name>
<param-value>a.b.com</param-value>
</init-param>
P.S. Совет - чтбы написать ругательные слова Object, script, applet, пишите их как Obje[i][/i]ct. Тогда движок их не находит и не выбрасывает.
1. При логине смотрим в HttpSession (метод getAttribute(String))- есть ли у нас аттрибут CURRENT_LOGIN
1.1 нет аттрибута. Значит в этой сессии никто не залогинен. Разрешаем логин
session.setAttribute("CURRENT_LOGIN", uniqueClientId);
session.setAttribute("LAST_ACTION_TIME", System.currentTimeMillis());
1.2 есть аттрибут. Проверяем не вылетел ли этот пользоватль по таймауту. Читаем из сессии LAST_ACTION_TIME
[/pre]
Получилось вот что. Он вызывает сервлет несколько раз - только для одного окна.
Я ставлю атррибут, в качестве uniqueClientId использую идентификатор сессии, это длинное 16ричное число, которое Вы видели (это ничто иное как obj.getAccessKey() = accessKey из класса ndRMIRequest- - implements Serializable).
И вот какая штука: он все время говорит, что аттрибута нет!
09.09.2015 19:13:50
session got: F73F2838299E3E9088ECE0B56C5D798C
localIP0:
current_login is NULL
.......
09.09.2015 19:13:50
session got: F73F2838299E3E9088ECE0B56C5D798C
localIP0:
current_login is NULL
......
09.09.2015 19:14:20 I: PP_Servlet (19:14:20):session got: F73F2838299E3E9088ECE0B56C5D798C
session got: F73F2838299E3E9088ECE0B56C5D798C
localIP0:
current_login is NULL
....
09.09.2015 19:14:20 I: PP_Servlet (19:14:20):session got: F73F2838299E3E9088ECE0B56C5D798C
session got: F73F2838299E3E9088ECE0B56C5D798C
localIP0:
current_login is NULL
Нормальным дебаггером Эклипса пользоваться нельзя, поэтому приходится каждый раз долго деплоить, но я все же выясню, что это за 4 вызова сервлета для одного окна.
Хотя главная фигня мне не нравится: получается, что не только апплет, но и сервлет нельзя поймать, он каждый раз новый что ли?
Хорошо что вы нашли логи, в которые выводится "ndServlet.doPost, SessionID(access key) set: " + session.getId()".
Посмотрите - какой ID выдается в логах при каждом приходящем запросе?
Для дебага выдайте еще
showInfo("ndServlet.doPost, Session Attributes: "+java.util.Collections.list(session.getAttributeNames()));
Хотя главная фигня мне не нравится: получается, что не только апплет, но и сервлет нельзя поймать, он каждый раз новый что ли?
Теоретически такое возможно. Конфигурация вашего серверного контекста ICM6 тоже доставляет. Если к сервлету лезут действительно через него...
Кстати, server.xml, который вы постили тоже как-то кусками послался. Может все-таки xml файл приложится к сообщению?
Проверить можно - хэш-код сервлета в логи выдайте в doPost()
showInfo("ndServlet.doPost hashCode(): "+ hashCode())
и в init()
showInfo("ndServlet.init hashCode(): "+ hashCode())
Увидите сколько раз он инициализировался и какие объекты класса ndServlet обрабатывают запросы.
Посмотрите, может на вашем томкате менеджер поднят, можно посмотреть что же на нем сконфигурировано.
см. http://tomcat.apache.org/tomcat-7.0-doc/manager-howto.html
Еще мыслЯ. В doPost() сделайте
showInfo("ndServlet.doPost request: "+request.hashCode()+" and stacktrace: "+(new Exception()).toString());
Я хочу в логах увидеть stacktrace вызова. Чтобы понять кто и откуда эти 4 раза ваш doPost() вызывает, действительно ли вам 4 разных запроса приходят, или кто-то ваш код 4 раза с одним и ем же запросом вызывает.
Я ведь ставлю значение аттрибута current_id в сессии, сессия сохраняется, а аттрибут нет? Почему?
session у вас это HttpSession, полученное в doPost(HttpRequest request, HttpResponse response) из request.getSession(), верно?
Да.
Посмотрите - какой ID выдается в логах при каждом приходящем запросе?
Каждый раз выдается 596099E13516A03E708161FEE9B16F99.
Посмотрите, может на вашем томкате менеджер поднят, можно посмотреть что же на нем сконфигурировано.
см. http://tomcat.apache.org/tomcat-7.0-doc/manager-howto.html
Я работаю не с локальным Томкатом, а с тем, что запущен на Юниксе. А где там можно посмотреть? И что именно нужно смотреть?
Пробую приложить server.xml...
------
Это - как оно сделано - надо смотреть в твоей реализации.
сессия сохраняется, а аттрибут нет?
------
Вероятно что-то опускаешь. Например, не сохраняешь копию сессии на аппсервере
и новый инстансе сервлета получает от аппсервера копию когда-то сохраненной сессии.


Тебе уже не раз говорилось - это не С/СРР - надо понимать не только что делает код,
но и как работает вся схема. Без этого можно месить код до бесконечности.
Для дебага выдайте еще
showInfo("ndServlet.doPost, Session Attributes: "+java.util.Collections.list(session.getAttributeNames()));
ndServlet.doPost, Session Attributes: [bindings.listener, CURRENT_LOGIN, LAST_ACTION_TIME, javax.security.auth.subject]
showInfo("ndServlet.doPost hashCode(): "+ hashCode())
10.09.2015 11:40:57 I: PP_Servlet (11:40:57):ndServlet.doPost, getAttribute(KEY_BINDING_LISTENER) <> this
10.09.2015 11:40:57 I: PP_Servlet (11:40:57):ndServlet.doPost hashCode(): 625485128
и в init()
showInfo("ndServlet.init hashCode(): "+ hashCode())
10.09.2015 11:16:41 I: PP_Servlet (11:16:41):ndServlet.init hashCode(): 1505384890
10.09.2015 11:16:41 I: PP_Servlet (11:16:41):ndServlet.init: init called ...
10.09.2015 11:26:44 I: PP_Servlet (11:26:44):ndServlet.init: init called ...
10.09.2015 11:26:44 I: PP_Servlet (11:26:44):ndServlet.init hashCode(): 625485128
10.09.2015 11:26:44 I: PP_Servlet (11:26:44):ndServlet.init: init called ...
showInfo("ndServlet.doPost request: "+request.hashCode()+" and stacktrace: "+(new Exception()).toString());
10.09.2015 11:46:27 I: PP_Servlet (11:46:27):ndServlet.doPost request: 1957459116 and stacktrace: java.lang.Exception
10.09.2015 11:46:27 I: PP_Servlet (11:46:27):ndServlet.doPost request: 251137784 and stacktrace: java.lang.Exception
10.09.2015 11:46:57 I: PP_Servlet (11:46:57):ndServlet.doPost request: 1957459116 and stacktrace: java.lang.Exception
10.09.2015 11:46:57 I: PP_Servlet (11:46:57):ndServlet.doPost request: 251137784 and stacktrace: java.lang.Exception
Если до завтра не сделаю, то таск, видимо, снимается и мне запишут жирный минус..

сессия сохраняется, а аттрибут нет?
------
Вероятно что-то опускаешь. Например, не сохраняешь копию сессии на аппсервере
и новый инстансе сервлета получает от аппсервера копию когда-то сохраненной сессии.
К сессии идет обращение через сервлет 4 раза!
И каждый раз ставится аттрибут current_session, и каждый раз он теряется!
Это что, 4 копии одной сессии?

Быть такого не может!..
Каждый раз выдается 596099E13516A03E708161FEE9B16F99.
Ерунда какая-то. Если сессия каждый раз та же самая, то почему не сохраняется аттрибут. А если сессия разная, то почему всегда ID одинаковый.
server.xml нормально передался. Посмотрите в томкатовском каталоге conf, есть ли там (или в его подкаталогах) файлы context<xxx>.xml в которых ваш ndSerlvet упоминается. Где-то же кто-то делает нестандартные вещи с сессией.
А что у вас в каталоге /home/icm6/dcc/web/lib? Может там все-таки номальные дескрипторы есть... Поищите в этои каталоге файлы web.xml. Если найдете такой, в котором ndServlet упоминается (или другие сервлеты из вашего приложения) - шлите.
Даже выкинуть все нафиг и настроить нормально веб-приложение с описанием деплоймента сервлета не посоветуешь, 100% работа сервера завязана на том, что у сессии один и тот же ID...
Я работаю не с локальным Томкатом, а с тем, что запущен на Юниксе. А где там можно посмотреть? И что именно нужно смотреть?
По ссылку написано что такое менеджер и как его открывать. А посмотреть на нем можно запущенные на сервере приложения.
ndServlet.doPost, Session Attributes: [bindings.listener, CURRENT_LOGIN, LAST_ACTION_TIME, javax.security.auth.subject]
Это в самом начале doPost-а выдается? Или после того как вы уже с setAttribute CURRENT_LOGIN и LAST_ACTION_TIME установили?
10.09.2015 11:26:44 I: PP_Servlet (11:26:44):ndServlet.init: init called ...
10.09.2015 11:26:44 I: PP_Servlet (11:26:44):ndServlet.init hashCode(): 625485128
10.09.2015 11:26:44 I: PP_Servlet (11:26:44):ndServlet.init: init called ...
Это как вообще?
1 раз init вызвался, напечатался только " init called ..." а следующий раз пишутся оба, и "init called ..." и "init hashCode(): 625485128"? Вы что, выдачу "init hashCode(): 625485128" в какой-то if засунули что ли?
Ну а вообще - поздравляю. Многократная инициализация двух образцов (а то и больше) сервлета. И это при каждом запросе или все же один раз?
Давайте посмотрим из каких контекстов такая красота идет.
в начале init-а сразу после super.init(config) :
showInfo(getClass.getName()+"@"+hashCode()+".init() called. Servlet name: "+config.getServletName()+" Context Name: "+config.getServletContext().getServletContextName());
showInfo("Servlet configuration parameters: "+Collections.list(config.getInitParameterNames()));
Остальные два вызова showInfo (с " init called ..." и "init hashCode(): ...") сотрите чтобы не засоряло лог.
Дальше.
10.09.2015 11:46:27 I: PP_Servlet (11:46:27):ndServlet.doPost request: 1957459116 and stacktrace: java.lang.Exception
10.09.2015 11:46:27 I: PP_Servlet (11:46:27):ndServlet.doPost request: 251137784 and stacktrace: java.lang.Exception
10.09.2015 11:46:57 I: PP_Servlet (11:46:57):ndServlet.doPost request: 1957459116 and stacktrace: java.lang.Exception
10.09.2015 11:46:57 I: PP_Servlet (11:46:57):ndServlet.doPost request: 251137784 and stacktrace: java.lang.Exception
Два разных запроса, ок. А через 30 секунд еще раз эта же пара, фантастика.
Поправьте код для логов, чтобы все же стэктрейс выдался:
Exception tmp = new Exception();
StringWriter writer = new StringWriter();
tmp.printStackTrace(new PrintWriter(writer));
showInfo("ndServlet@"+hashCode()+".doPost request@"+request.hashCode()+" URL: "+request.getRequestURL()+" Session@"+session.hashCode()+" with ID "+session.getId()+" from cookie? "
+ request.isRequestedSessionIdFromCookie()+" or from URL? "+request.isRequestedSessionIdFromURL()
+ " Stacktrace: "+writer.toString());
Если до завтра не сделаю, то таск, видимо, снимается и мне запишут жирный минус..
Когда начальство дурное это плохо, да.
Ерунда какая-то. Если сессия каждый раз та же самая, то почему не сохраняется аттрибут. А если сессия разная, то почему всегда ID одинаковый.
Oh yes, that is the question, как говорилось у Вильяма нашего Шыкспира...
server.xml нормально передался. Посмотрите в томкатовском каталоге conf, есть ли там (или в его подкаталогах) файлы context<xxx>.xml в которых ваш ndSerlvet упоминается. Где-то же кто-то делает нестандартные вещи с сессией.
Есть файл context.xml, но он полупустой (теги раскрываю, иначе они тут не показываются)
-> cat context.xml
The contents of this file will be loaded for each web application -->
xml version="1.0" encoding="UTF-8"?>
Context allowLinking="true">
-- Default set of monitored resources -->
<WatchedResource>WEB-INF/web.xml</WatchedResource>
Uncomment this to disable session persistence across Tomcat restarts -->
Manager pathname="" />
/Context>
А что у вас в каталоге /home/icm6/dcc/web/lib? Может там все-таки номальные дескрипторы есть... Поищите в этои каталоге файлы web.xml. Если найдете такой, в котором ndServlet упоминается (или другие сервлеты из вашего приложения) - шлите.
web.xml там нет, есть три файла, которые я туда "деплойю", но они, есесна, бинарные:
-rw-r--r-- 1 icm6 icmdev 85443 Sep 10 11:26 dcc_guitext.properties
-rwxr-x--- 1 icm6 icmdev 1752297 Sep 10 11:26 dcc_domain.jar
-rw-r--r-- 1 icm6 icmdev 1774816 Sep 10 11:26 pp_domain.jar
В одном из них, очевидно, что-то содержится на эту темку в бинарной форме, но grep не показывает:
-> grep ndServlet *
grep: can't open ICM-9.3-Benutzerhandbuch.pdf
pp_domain.jar:
pp_domain.jar:
jar-ы это обычные zip-ы. В них могут быть каталог WEB-INF с web.xml внутри.
(я немного расширил в предыдущем сообщении выдачу в лог - будете вставлять, посмотрите что последнее вставляете).
-----
Ну не может так не может.


Правда это наиболее распространенная и труднопонимаемая (для начинающих) ошибка.

И Я надеюсь, что это все же она, а не проблема с правами для процесса в котором выполняется
сервлет.
Это что, 4 копии одной сессии?
-----
А чем тебя смущает количество копий?
Если смущает - обработай корректно следующее:
- приходит запрос и запускается сервлет
- сервлет что-то считает
- приходит еще один запрос и запускается еще одна копия сервлета
- сервлет что-то считает
- приходит еще один запрос и запускается еще одна копия сервлета
и еще так же 100500 раз...
Что ты будешь делать с сессиями, при условии, что место хранения сессионной информации
- какая-то база данных размещенная где-то на хосте, отличном от апп.сервера?
Или ты полагаешь, что для второго и последующих сервлетов используется другой алгоритм
запуска?

Это в самом начале doPost-а выдается? Или после того как вы уже с setAttribute CURRENT_LOGIN и LAST_ACTION_TIME установили?
Это выдается до того, как я setAttribute CURRENT_LOGIN и LAST_ACTION_TIME установил, но не в начале, а после
// now handle special case: multi block transfer
// (in case of own support for communication)
if (!(objTransfer.getData- -() instanceof ndCommunication- -) ||
!c_fSpecialCommunicationSupport)
ибо сессия определяется уже после этого if:
// set binding listener for session if it's not already done...
HttpSession session = request.getSession(true);
Впрочем, я могу перенести этот кусок и в начало метода doPost, если надо.
Это как вообще?
1 раз init вызвался, напечатался только " init called ..." а следующий раз пишутся оба, и "init called ..." и "init hashCode(): 625485128"? Вы что, выдачу "init hashCode(): 625485128" в какой-то if засунули что ли?
Нет, не в if. Просто дебаг "init called" у меня пишется сначала не в самом сервлете, а в классе ndReportServlet, а потом уже в init самого класса ndServlet:
showInfo("ndServlet.init hashCode(): "+ hashCode());
String hostname;
String maxBlockSize;
int tracelevel;
//In the Moment, we set no Security! It remains to check, if you can do it with policy-files
//System.setSecurityManager(new NoSecurityManager());
// Trace on/off?
if (config.getInitParameter("Trace") != null)
{
tracelevel = Integer.parseInt(config.getInitParameter("Trace"));
if ((tracelevel > Trace.TRACE_OFF) &&
(tracelevel <= Trace.FUNCTION_TRACE))
Trace.setTraceLevel(tracelevel);
}
showInfo("ndServlet.init: init called ...");
Так что многократной инициализации все же нет, init вызывается 1 раз.
в начале init-а сразу после super.init(config) :
showInfo(getClass.getName()+"@"+hashCode()+".init() called. Servlet name: "+config.getServletName()+" Context Name: "+config.getServletContext().getServletContextName());
showInfo("Servlet configuration parameters: "+Collections.list(config.getInitParameterNames()));
Первую строчку вставить не получается, getClass не находится. Вторую вставил, инклюдировав Collections.
+request.getRequestURL()
Очень странно, +request.getRequestURL() не находится, но есть +request.getRequestURI()
10.09.2015 13:44:58 I: PP_Servlet (13:44:58):Servlet configuration parameters: [HostName, Trace]
showInfo("ndServlet@"+hashCode()+".doPost request@"+request.hashCode()+" URL: "+request.getRequestURL()+" Session@"+session.hashCode()+" with ID "+session.getId()+" from cookie? "
+ request.isRequestedSessionIdFromCookie()+" or from URL? "+request.isRequestedSessionIdFromURL()
+ " Stacktrace: "+writer.toString());
-> grep "ndServlet@" tomcat.log
10.09.2015 13:44:58 I: PP_Servlet (13:44:58):ndServlet@41943680.doPost request@1957459116 URL: /ICM6/servlet/de.novadata.pp.servlet.ndServlet sessionID from cookie? true or from URL? false Stacktrace: java.lang.Exception
10.09.2015 13:44:58 I: PP_Servlet (13:44:58):ndServlet@41943680.doPost request@251137784 URL: /ICM6/servlet/de.novadata.pp.servlet.ndServlet sessionID from cookie? true or from URL? false Stacktrace: java.lang.Exception
10.09.2015 13:45:28 I: PP_Servlet (13:45:28):ndServlet@41943680.doPost request@1957459116 URL: /ICM6/servlet/de.novadata.pp.servlet.ndServlet sessionID from cookie? true or from URL? false Stacktrace: java.lang.Exception
Вместо того, чтобы троллить подзаборными словами, запрещенными свыше, выдай уже что-нить конструктивное.
Например, откуда взять getClass для дибага.