【问题标题】:post method call one java class is initialize every request [duplicate]post方法调用一个java类初始化每个请求[重复]
【发布时间】:2016-09-30 08:26:27
【问题描述】:

我使用 jsp 和 servlet 创建了一个小型 Web 应用程序。我的 ajax post 方法每三秒调用一次 java 类。我想知道每 3 秒,java 类变量 isBootRunning,istest1Running,istest1Running 是否初始化为“null”。 如果每次请求都会初始化,如何防止这种初始化。

我的 JSP:

setInterval(function(){
            TestReport(); 
        }, 3000); 
function TestReport(){
var tbname = $("#tbname").attr('class');
var userName = $("#userName").attr('class');
var name = tbname;
var url ="TestReport";
var params = {
        tbname: tbname,
        userName:userName
};
$.post('TestReport', {
    tbname: tbname,
    userName:userName,
}, function(responseText) {
    alert(responseText);
});
}

我的 Servlet:

public class TestReport extends HttpServlet {
private static final long serialVersionUID = 1L;
String isBootRunning = null;
String istest1Running = null;
String istest2Running = null;
    protected void doPost(HttpServletRequest request,
            HttpServletResponse response) throws ServletException, IOException {

        File f1 = new File("myfirstpath");//this directory is visible for 10 mins only 
        File f2 = new File("mythirdpath");//this directory is visible for 10 mins only
        File f3 = new File("mythirdpath");//this directory is visible for 10 mins only

        if (f1.exists() && f1.isDirectory()) {
            isBootRunning = "Running";
            istest1Running = "Scheduled";
            istest2Running = "Scheduled";
        } else if(f2.exists() && f2.isDirectory()){
            istest1Running = "Running";
            istest2Running = "Scheduled";
            if(isBootRunning=="Running"){
                //here my logic
            }
        } else if(f2.exists() && f2.isDirectory()){

            istest2Running = "Running";
            if(isBootRunning=="Running"){
                //here my logic
            }
            if(istest1Running=="Running"){
                //here my logic
            }
        }
    }
}

【问题讨论】:

  • servlet 类只被 web 容器实例化一次,所以你的变量永远不会被重新初始化。您可以登录验证。

标签: java ajax jsp servlets


【解决方案1】:

您正面临这个问题,因为每次您向 servlet 发出新的 ajax 请求时,之前请求的结果都不会被存储/保存。
这个问题可以使用 HttpSession 解决。您必须在会话对象中保存和获取字符串对象 isBootRunning、istest1Running、istest2Running,如下所示:

protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    try{
        HttpSession session =null;
        if(request.getSession().isNew()){
             session= request.getSession();//new session
        }else{
             session= request.getSession(false);//current session
        }
        if(null != session && null != session.getAttribute("isBootRunning") && null != session.getAttribute("istest1Running")  && null != session.getAttribute("istest2Running")){ 
            yourLogic(session);//compute your logic for not null values
        }
        else{
            session.setAttribute("isBootRunning", "");
            session.setAttribute("istest1Running", "");
            session.setAttribute("istest2Running", "");

            yourLogic(session);//compute your logic for null values
        }

    }catch(Exception e){
        e.printStackTrace();
    }
}

private void yourLogic(HttpSession session) {
    File f1 = new File("myfirstpath");//this directory is visible for 10 mins only 
    File f2 = new File("mythirdpath");//this directory is visible for 10 mins only
    File f3 = new File("mythirdpath");//this directory is visible for 10 mins only

    String isBootRunning = (String)session.getAttribute("isBootRunning");
    String istest1Running = (String)session.getAttribute("istest1Running");;
    String istest2Running = (String)session.getAttribute("istest2Running");;
    if (f1.exists() && f1.isDirectory()) {
        session.setAttribute("isBootRunning", "Running");
        session.setAttribute("istest1Running", "Scheduled");
        session.setAttribute("istest2Running", "Scheduled");
    } else if(f2.exists() && f2.isDirectory()){
        session.setAttribute("istest1Running", "Scheduled");
        session.setAttribute("istest2Running", "Scheduled");
        if(isBootRunning=="Running"){
            //here my logic
        }
    } else if(f2.exists() && f2.isDirectory()){
        session.setAttribute("istest2Running", "Scheduled");
        istest2Running = "Running";
        if(isBootRunning=="Running"){
            //here my logic
        }
        if(istest1Running=="Running"){
            //here my logic
        }
    }
}

在这里,您的 String 对象存储在 session 对象中。并且使用 session 是非常安全的,因为 session 管理是在你的 web 容器中完成的,它永远不会破坏用户的完整性。
这将阻止为以后的请求初始化对象。

【讨论】:

  • 恕我直言,这不应该在会话中完成,因为会话不会在客户端之间共享。
  • @PatrykRogosch,为什么你应该分享这个会话。我们从不在客户之间共享任何会话。例如:您登录到您的银行帐户,那么只会为您创建和维护一个会话。(每个用户一个会话)
  • 我仍然声称他希望对这些变量具有“全局”可见性(至少他在代码中呈现的内容)。在这种情况下,会话不会对您有所帮助。
  • 我已经尝试并实现了代码,它运行良好,我建议您通过一些视频教程和网站,如javatpoint.com/servlet-tutorial 来清除您与 servlet 相关的概念。
【解决方案2】:

你必须写才能得到变量:

    String isBootRunning = (String) getServletContext().getAttribute("isBootRunning");

你必须写来设置变量:

    getServletContext().setAttribute("isBootRunning", isBootRunning);

【讨论】:

  • 问题在于初始化,检查问题。每次他向您的 servlet 发出新的 ajax 请求时,字符串对象都会设置为 null。
  • 这可能是一种可能的解决方案,但是每个用户/客户端/用户名都可以访问相同的上下文对象,并且所有用户都将具有相同的字符串对象值。所以这不好。
【解决方案3】:

另一件事是当前的设计非常糟糕(可能的竞争条件)。应用程序/Web 容器是多线程的。由于您没有使用任何同步化,因此当请求由另一个线程提供服务时,您可能看不到结果。

【讨论】:

  • 您需要了解问题在于维护 String 对象 isBootRunning、istest1Running 和 istest2Running 的状态。同步永远不会解决这个问题!
  • 我不能同意。如果您添加同步,所有线程将共享相同的状态。
  • 同步只是意味着一次只有一个线程可以访问共享资源。这里没有同步的概念,因为 String 对象不是共享的。对于向 servlet 发出的每个新请求,都会创建一个新线程,并拥有一个 java 类对象的新实例,因此它们不共享。想象一下,根据您的建议,这将是多么复杂,开发人员必须始终考虑同步而不是实现业务逻辑。如果您允许同步,那么一次只有一个线程可以访问您的 Web 应用程序。例如 SingleThreadModel。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-07-17
  • 1970-01-01
  • 1970-01-01
  • 2011-05-11
  • 1970-01-01
  • 1970-01-01
  • 2018-01-27
相关资源
最近更新 更多