Почему иногда не удается установить атрибут в сеансе из сервлета Java? - PullRequest
6 голосов
/ 01 апреля 2011

Я работаю над довольно простым веб-приложением, использующим JSP и сервлет Java, работающими на tomcat.Мне удалось установить атрибуты в сеансе из сервлета, чтобы передать информацию в JSP, которая затем будет представлена ​​пользователю.Я сделал это с несколькими различными объектами разных классов, и это работало нормально.Внезапно, когда я устанавливаю определенный тип объекта (содержащий информацию о конфигурации), атрибут вообще не отображается в JSP.Другие атрибуты, которые я установил, все еще там, но объект конфигурации полностью отсутствует.Я распечатал список имен атрибутов, а имя, которое я использовал, отсутствует даже там (хотя другие имена для других установленных мной атрибутов присутствуют).

Что может вызвать это?В моем классе конфигурации нет ничего необычного или странного.Буду очень признателен за любые идеи о том, что может вызвать такое поведение.Я гуглил и искал и не могу ничего найти.

ETA: Если это имеет значение, то имя атрибута - "конфигурация".Я не смог найти ничего о том, что это зарезервированное слово или что-то еще ... Я установил этот атрибут в сервлете в той же функции, что и некоторые другие, такие как «пользователь».Затем я перенаправляю на JSP, который пытается получить как пользователя, так и конфигурацию.Так что все происходит одновременно.С пользователем все в порядке, хотя конфигурация даже не отображается в списке имен атрибутов.

ETA2: в журналах постоянно происходит исключение:

java.lang.Exception
    at pms.SessionListener.printStackTrace(Unknown Source)
    at pms.SessionListener.attributeAdded(Unknown Source)
    at org.apache.catalina.session.StandardSession.setAttribute(StandardSession.java:1498)
    at org.apache.catalina.session.StandardSession.setAttribute(StandardSession.java:1390)
    at org.apache.catalina.session.StandardSessionFacade.setAttribute(StandardSessionFacade.java:154)
    at PMS.getTaskInfo(Unknown Source)
    at PMS.doGet(Unknown Source)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:621)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:306)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:240)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:161)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:164)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:108)
    at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:558)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:379)
    at org.apache.coyote.http11.Http11AprProcessor.process(Http11AprProcessor.java:282)
    at org.apache.coyote.http11.Http11AprProtocol$Http11ConnectionHandler.process(Http11AprProtocol.java:357)
    at org.apache.tomcat.util.net.AprEndpoint$SocketProcessor.run(AprEndpoint.java:1687)
    at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(Unknown Source)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
    at java.lang.Thread.run(Unknown Source)

Ответы [ 2 ]

6 голосов
/ 01 апреля 2011

Согласно комментариям к вопросу:

Сессия абсолютно там, и я могу получить другие атрибуты, которые были установлены в сервлете одновременно, из сессии вJSP.Это просто один конкретный атрибут, который не будет отображаться.Я обнаружил, что во время сеанса не было ничего такого, но не то, почему один атрибут не будет работать, когда другие работают.

Затем что-то было удалено или обнулено.

session.removeAttribute("name");

или

session.setAttribute("name", null);

или даже в JSP

<c:set var="name" value="${null}" scope="session" />

Или это может быть себя , который установилnull вместо полноценного объекта.

Чтобы лучше определить одно и другое, я бы позволил атрибуту реализовать HttpSessionBindingListener и выгрузил стек на valueUnbound().

public class Foo implements HttpSessionBindingListener {

    @Override 
    public void valueBound(HttpSessionBindingEvent event) {
        System.out.println("Value bound"); // Logger?
    }

    @Override 
    public void valueUnbound(HttpSessionBindingEvent event) {
        System.err.println("Value unbound"); // Logger?
        Thread.dumpStack();
    }

    // ...
}
4 голосов
/ 01 апреля 2011

Существует множество возможностей того, что может пойти не так.

  • Может быть два разных сеанса.
  • Возможно, какой-то код удаляет ваш объект конфигурации из сеанса.
  • Другие?

Вот способ, которым вы можете проверить, чтобы увидеть, что именно происходит.

Существует два отдельных интерфейса слушателя, которые вы можете реализовать для прослушиванияконкретные события сеанса: javax.servlet.http.HttpSessionListener и javax.servlet.http.HttpSessionAttributeListener

Я бы реализовал эти два интерфейса с помощью класса, который будет регистрировать, чтопроисходит во время каждого события и из какого сеанса происходит событие.

Вы должны иметь возможность легко добавлять своих слушателей в файл web.xml, чтобы tomcat фактически установил их в качестве слушателей ваших сеансов.

РЕДАКТИРОВАТЬ

Вот класс, который вы можете поместить в ваш web.xml как слушатель ваших сессий.И BalusC, и я рекомендовали вам попробовать этот подход для устранения проблемы.Пожалуйста, просто пошутите над нами и дайте нам знать, если вы видите что-нибудь интересное в способе установки вашего атрибута «конфигурации»?

import javax.servlet.http.HttpSessionActivationListener;
import javax.servlet.http.HttpSessionAttributeListener;
import javax.servlet.http.HttpSessionBindingEvent;
import javax.servlet.http.HttpSessionBindingListener;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;

public class SessionListener implements HttpSessionListener, HttpSessionAttributeListener, HttpSessionBindingListener, HttpSessionActivationListener {

public void valueBound(HttpSessionBindingEvent event) {
    System.out.println("valueBound: " + event.getName() + " : " + event.getValue());
    System.out.println("  session: " + event.getSession().getId());
    this.printStackTrace();
}

public void valueUnbound(HttpSessionBindingEvent event) {
    System.out.println("valueUnbound: " + event.getName() + " : " + event.getValue());
    System.out.println("  session: " + event.getSession().getId());
    this.printStackTrace();
}

public void attributeAdded(HttpSessionBindingEvent event) {
    System.out.println("attributeAdded: " + event.getName() + " : " + event.getValue());
    System.out.println("  session: " + event.getSession().getId());
    this.printStackTrace();
}

public void attributeRemoved(HttpSessionBindingEvent event) {
    System.out.println("attributeRemoved: " + event.getName() + " : " + event.getValue());
    System.out.println("  session: " + event.getSession().getId());
    this.printStackTrace();
}

public void attributeReplaced(HttpSessionBindingEvent event) {
    System.out.println("attributeReplaced: " + event.getName() + " : " + event.getValue());
    System.out.println("  session: " + event.getSession().getId());
    this.printStackTrace();
}

public void sessionCreated(HttpSessionEvent event) {
    System.out.println("sessionCreated: " + event.getSession().getId());
    this.printStackTrace();
}

public void sessionDestroyed(HttpSessionEvent event) {
    System.out.println("sessionDestroyed: " + event.getSession().getId());
    this.printStackTrace();
}

public void sessionDidActivate(HttpSessionEvent event) {
    System.out.println("sessionDidActivate: " + event.getSession().getId());
    this.printStackTrace();
}

@Override
public void sessionWillPassivate(HttpSessionEvent event) {
    System.out.println("sessionWillPassivate: " + event.getSession().getId());
    this.printStackTrace();
}

private void printStackTrace() {
    try {
        if (true) {
            throw new Exception();
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
}
}

Пожалуйста, добавьте приведенный выше класс в свой код, а затем добавьте следующее в свою сеть.XML-файл между вашими сопоставлениями фильтров и сопоставлениями сервлетов:

<listener>
    <listener-class><your.package.name>SessionListener</listener-class>
</listener>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...