简体   繁体   English

意外的Servlet缓存

[英]Unexpected Servlet caching

I have a Tomcat7 web App consisting of an HTML file with form, as well as a Servlet and a Java bean. 我有一个Tomcat7 Web应用程序,该应用程序由带有表单的HTML文件,Servlet和Java Bean组成。 The HTML form calls the Servlet, which takes the request parameters, does some preparations, creates an instance of the bean and calls it's String doSearch(String arg1, int arg2) method. HTML表单调用Servlet,该Servlet接受请求参数,进行一些准备,创建bean的实例并调用它的String doSearch(String arg1,int arg2)方法。 Each time the Servlet is called, it sets the bean to null and creates a new Instance. 每次调用Servlet时,它将Bean设置为null并创建一个新的Instance。

The problem is that in each session the former results (created by the bean) stay visible (which should not appear). 问题在于,在每个会话中,以前的结果(由Bean创建)都保持可见(不应显示)。 I don't use any static variables or classes. 我不使用任何静态变量或类。

When I run the code as Java Program it works as expected. 当我将代码作为Java程序运行时,它可以按预期工作。 The only way to get rid of the old results for now is restarting Tomcat 暂时摆脱旧结果的唯一方法是重新启动Tomcat

Any help is greatly appreciated. 任何帮助是极大的赞赏。

Here is the code for my servlet: 这是我的servlet的代码:

public class LingoServlet extends HttpServlet {
private static final long serialVersionUID = 1L;

/**
 * @see HttpServlet#HttpServlet()
 */
public LingoServlet() {
    super();
}

String HTML_HEAD = "" + "<!DOCTYPE HTML PUBLIC \"" + "-//W3C//DTD HTML " + "4.01 Transitional//EN\" "
        + "\"http://www.w3.org/TR/html4/loose.dtd\">" + "<html>" + "<head><link rel=\"stylesheet\" "
        + "type=\"text/css\" href=\"default.css\">" + "<meta http-equiv=\"cache-control\" content=\"max-age=0\" />"
        + "<meta http-equiv=\"cache-control\" content=\"no-cache\" />"
        + "<meta http-equiv=\"expires\" content=\"0\" />"
        + "<meta http-equiv=\"expires\" content=\"Tue, 01 Jan 1980 1:00:00 GMT\" />"
        + "<meta http-equiv=\"pragma\" content=\"no-cache\" />" + "<title>Lingo Helper</title>"
        + "<meta http-equiv=\"Content-Type\" " + "content=\"text/html; charset=UTF-8\">" + "</head>" + "<body>";
String BODY = "<h1>Results:</h1>";
String FOOTER = "</html>";

// Prevent caching by destroying it first.
LingoSearcher ls = null;

HttpServletRequest req = null;
HttpServletResponse res = null;
PrintWriter pw = null;

/**
 * @see HttpServlet#doGet(HttpServletRequest req, HttpServletResponse res)
 */

protected void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {
    // PrintWriter pw = null;
    LingoSearcher ls = null;
    PrintWriter pw = res.getWriter();

    String wl = req.getParameter("wl").trim();
    String wc = req.getParameter("wc").trim().toLowerCase();

    int wlength = Integer.parseInt(wl);

    LingoSearcher searcher = new LingoSearcher();

    try {
        BODY = BODY + "<div id=\"scroll\">" + "<pre>" + ls.doSearch(wc, wlength) + "</pre></div>";

    } catch (Exception e) {
        String msg = "An error occured. Please check your input" + " parameters and try again.<br/>"
                + "If the prblem persists please report the error" + "as 122";
        pw.println(msg);
    }
    pw.print(HTML_HEAD);
    pw.print(BODY);
    pw.print(FOOTER);
    pw.flush();
    pw.close();
    res = null;
    req = null;
}

} }

Your code actually looks okay (though it has a lot of architectural problems and potential NPEs, etc.), except for this part: 您的代码实际上看起来还不错(尽管它存在很多体系结构问题和潜在的NPE等),但以下部分除外:

// Prevent caching by destroying it first.
LingoSearcher ls = null;

HttpServletRequest req = null;
HttpServletResponse res = null;
PrintWriter pw = null;

Something tells me you have changed the code before posting it, because those class-level members are never used. 有人告诉我您在发布代码之前已更改了代码,因为从未使用这些类级别的成员。 You have shadowed them all in your doGet method, so the local names take precedence.If you had not shadowed them – that is, if you had used the class-level members then you would have been retaining references to objects (especially the request and response objects) longer than they should live. 您已经在doGet方法中对其进行了全部阴影处理,因此本地名称具有优先权。如果您没有对其进行阴影处理-即,如果您使用了类级成员,则将保留对对象的引用(尤其是请求和响应对象)的生存期超过了应有的生存期。

In web applications, servlets are (usually) created a single time and live for the life of the application (until it is undeployed). 在Web应用程序中,(通常)一次性创建Servlet,并在应用程序的整个生命周期内将其保留(直到取消部署为止)。 Your servlets should be completely free of class-level members unless they are properly thread-safe. 您的servlet应该完全没有类级别的成员,除非它们是适当的线程安全的。

Instead of a Servlet use a JSP and declare a bean with scope of "page" That solved my problem. 代替Servlet,使用JSP并声明范围为“ page”的bean,这解决了我的问题。 Avoid the use of Servlets anyway. 无论如何都要避免使用Servlet。 JSP's are much easier and have many options. JSP更加容易并且有很多选择。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM