处理servlet中的多个请求,并为每个请求提供正确的响应

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了处理servlet中的多个请求,并为每个请求提供正确的响应相关的知识,希望对你有一定的参考价值。

我正在开发一个JSP项目(不使用任何框架)。我来到了一个我无法弄清问题原因的地步。实现逻辑:当请求发送到servlet时,它调用函数A从数据库中获取动态内容并将其传递回请求来自的客户端。

问题:当多个请求进入servlet时,它们从函数A获取数据(它从数据库中获取表单详细信息)并将数据传递给错误的客户端。在客户机错误的形式绘制。

当涉及多个客户端时,如何处理请求和响应。什么是解决这个问题的最佳实践。搜索互联网后我得到单身模式和代理类将有助于解决这个问题....任何人有任何想法请帮我解决这个问题。

`// Getting value in jsp page
String val = request.getParameter("mod_value");
//calling function to get values from database
List<DrawForm> dataModel = QueryFunction.getPageDetails(val);
// Using this dataModel displaying the form
for(int i=0;i<dataModel.size();i++){
//Display form
}`





//QueryFunction Class
public class QueryFunction{
public static Connection connect = null;
public static CallableStatement statement = null;
public static ResultSet rset = null;

public static synchronized List<DrawForm> getPageDetails(String obj){

    List<DrawForm> dataModel = new ArrayList<>();

    try
    {   
        connect = DbConnection.GetConnection();
        statement = (CallableStatement)connect.prepareCall("{call 
        Get_form_template(?)}");
        statement.setString(1, obj);
        rset  = statement.executeQuery();
        while(rset.next()){
          DrawForm form = new DrawForm();
          // getting values in the array model
          dataModel.add(form);
        }                       
    }catch (Exception e) {
        e.printStackTrace();
    }finally {
        close();
    }       
    return dataModel;
}
private static void close() {
    if (connect != null) {
         try {
            connect.close();
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

     if (rset != null) {
         try {
             rset.close();
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

     if (statement != null) {
         try {
             statement.close();
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
}


}
答案

问题来自静态/共享字段。就像我提供的一个例子一样。

当一个线程使用连接,语句和结果集时,另一个线程可以使用ocme并覆盖它们。这将导致不一致。

没有逻辑方法可以将所有字段都设置为静态。为了安全地关闭资源,您可以使用try(){}块。

//QueryFunction Class
public class QueryFunction{
//public static Connection connect = null;//god no!
//public static CallableStatement statement = null;
//public static ResultSet rset = null;

public static synchronized List<DrawForm> getPageDetails(String obj){

    List<DrawForm> dataModel = new ArrayList<>();

    try(Connection connect = DbConnection.GetConnection();CallableStatement statement = (CallableStatement)connect.prepareCall("{call Get_form_template(?)}");)
    {
        statement.setString(1, obj);
        try(ResultSet rset  = statement.executeQuery();){
          while(rset.next()){
            DrawForm form = new DrawForm();
            // getting values in the array model
            dataModel.add(form);
          }   
        }               
    }catch (Throwable wth) {
        wth.printStackTrace();
    }/*finally {
        close();
    }*/
    return dataModel;
}
//no need for this!, but if you insist, pass the connection, resultset and statement as input args
/*private static void close() {
    if (connect != null) {
         try {
            connect.close();
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

     if (rset != null) {
         try {
             rset.close();
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

     if (statement != null) {
         try {
             statement.close();
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
}*/


}

try(){}将自动关闭任何可关闭的守卫。

另一答案

看起来你有线程问题。

默认情况下,java web引擎(比如tomcat)处理并行请求。这意味着一旦有服务器请求,服务器接受它,而另一个请求正在进行中。(还考虑连接限制/池和积压)

问题是关于你提到的A方法。我认为在全局范围内使用了某些东西,它可以与所有请求/线程调用共享。

考虑以下示例:

//the _c is shrable between threads
//this is not thread-safe
int _c=0;
public int method_a(){
    return _c++;//not thread safe!!!
}

//is called for each http calls
//request and response are associated to this call
//using them are safe
public void doGet(request,response){
int val=method_a();
//printing the val...
}

如上例所示,即使您调用100个http调用,也可能第二个调用请求响应值为80(预期为1),最后一个返回为8(预期为99)

我认为您使用方法A进行的业务不是线程安全的。

您可以标记method_a synchronized来验证它。但是,您可以找到正确的解决方案来解决并行环境,而不是密封并行环境。

您可以共享服务器的代码,以便我们更好地发现问题。

以上是关于处理servlet中的多个请求,并为每个请求提供正确的响应的主要内容,如果未能解决你的问题,请参考以下文章

Servlet 异步处理

必须在Servlet上启用异步支持,并为异步请求处理中涉及的所有过滤器启用

一个请求和多个servlet-mapping匹配,会去执行哪个servlet???

Servlet:一个Servlet处理多个请求

Servlet

如何使用 Spring/Servlets 支持批量 Web api 请求处理