1

JSP ページのサーバー側キャッシングで問題が発生しました。

訪問/リクエストされるたびに一意の ID を表示するカスタム JSP である内部エラー ページがあるとします。この一意の ID は、デバッグ用にサーバー ログにも記録されます。ただし、次を使用してエラー ID を実装すると、次のようになることに気付きました。

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

いくつかのリクエストの後...変数abcがサーバー側にキャッシュされているようで、同じ値がポップアップし続けます。

奇妙なことに、同じページに、エラーが発生した時間も表示します

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

キャッシュされることはなく、常に現在の時刻が表示されます。

そこで、上記を使用して時間を表示する代わりに、少し実験を行いました。

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

その文字列を画面に表示して SNAP を実行すると、数回呼び出した後にキャッシュされます。

私の質問は、サーバーがこれらの変数をキャッシュしないようにするにはどうすればよいですか?

4

2 に答える 2

4

大まかに訳すと、これは、最終的にコンパイルされる JSP ページのサーブレット クラスのインスタンス変数として宣言されています。例えば

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

    protected void service(HttpServletRequest ...

JSP は通常、起動時 (サーバーでの hotdeploy が有効な場合は変更後) に 1 回だけコンパイルされるため、まったく同じサーブレット インスタンスがすべての要求で共有されます。あなたはそれをしたくありません。

結局、 JSP ページでスクリプトレットを使用するべきではありません。Java コードは実際の Java クラスに属します。この特定のケースでは、EL 関数Bean クラス、またはサーブレット クラスを使用できます。

EL関数は最終的に次のようになります。

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

Bean クラスは次のようになります。

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>

サーブレット クラスは、JSP ページをカバーするようにマップする必要がありurl-pattern(またはその逆) 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" />

これにより、コードがよりクリーンになり、保守性が向上します。

于 2010-02-03T11:37:07.900 に答える
0

生成された.javaコードを確認した後。判明した

partはメンバー変数として宣言されているため、セッションの初期化時にのみ呼び出されます。したがって、セッションの初期化後に実際に再度呼び出されることはありません。

関数内に呼び出しを配置し​​、代わりにその関数を呼び出すことで回避策を実行することにしましたが、正常に機能しているようです。より良いアプローチでお気軽にお答えください。

于 2010-02-03T06:59:28.300 に答える