Кэширование переменной страницы JSP - PullRequest
1 голос
/ 03 февраля 2010

Я столкнулся с проблемой кэширования на стороне сервера страниц JSP.

Предположим, у меня есть внутренняя страница с ошибкой, представляющая собой пользовательский JSP, который будет отображать уникальный идентификатор при каждом посещении / запросе. Этот уникальный идентификатор также регистрируется в журнале сервера для отладки. Тем не менее, я заметил, что если я реализую идентификатор ошибки, используя:

<%!private String <b>abc</b> = UUID.randomUUID().toString();%>

После нескольких запросов ... переменная abc , кажется, кэшируется на стороне сервера, и это значение продолжает появляться.

Как ни странно, на той же странице я также показываю время, когда ошибка встречается с

XXXError encountered on <%=Calendar.getInstance().getTime().toString()%>

, который никогда не кэшируется и всегда отображает текущее время.

Итак, я провел небольшой эксперимент, вместо того, чтобы показывать время, используя приведенное выше, я использовал

<%!private String etime = Calendar.getInstance().getTime().toString();%>

и напечатайте на экране эту строку, и SNAP, она кэшируется после нескольких вызовов.

Итак, мой вопрос: как мне остановить сервер от кэширования этих переменных?

Ответы [ 2 ]

4 голосов
/ 03 февраля 2010

Грубо говоря, это объявлено как переменная экземпляра класса сервлета, к которому в конце концов компилируется страница JSP. Э.Г.

public class pagename_jsp_servlet extends HttpServlet {
    private String abc = UUID.randomUUID().toString();

    protected void service(HttpServletRequest ...

Поскольку JSP обычно компилируются только один раз во время запуска (или после изменения, если включено горячее развертывание на сервере), тот же самый тот же экземпляр сервлета будет общим для всех запросов! Ты не хочешь этого делать.

В конце концов, вы не должны использовать скриптлетов на страницах JSP. Java-код принадлежит реальному классу Java. В этом конкретном случае вы можете использовать EL-функцию или класс бинов или класс сервлетов .

Функция EL наконец-то будет выглядеть так:

<c:set var="uuid" value="${uuid:random()}" />
<p>UUID: ${uuid}</p>

Класс бобов будет выглядеть так:

public class UUIDBean {
    public String getRandom() {
        return UUID.randomUUID().toString();
    }
}

, который можно использовать как:

<jsp:useBean id="uuid" class="com.example.UUIDBean" />
<p>First UUID: ${uuid.random}</p>
<p>Next UUID: ${uuid.random}</p>

Класс сервлета должен отображаться на url-pattern, охватывающем страницу JSP (или наоборот), и должен иметь метод doGet(), реализованный для предварительной обработки запросов перед отображением данных на странице JSP:

UUID uuid = UUID.randomUUID().toString();
request.setAttribute("uuid", uuid);
request.getRequestDispatcher("page.jsp").forward(request, response);

перенаправленная страница JSP может выглядеть так:

<p>UUID from servlet: ${uuid}</p>

Далее, <%=Calendar.getInstance().getTime().toString()%> лучше заменить следующим образом:

<jsp:useBean id="now" class="java.util.Date" />
<p>The date is now: ${now}
<p>The date in yyyy-MM-dd format: <fmt:formatDate value="${now}" pattern="yyyy-MM-dd" />

Это делает код намного чище и лучше обслуживаемым.

0 голосов
/ 03 февраля 2010

После просмотра сгенерированных .java кодов. Получилось

часть объявлена ​​как переменная-член, поэтому вызывается только при инициализации сеанса. Поэтому после инициализации сеанса он никогда не вызывается снова.

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

...