Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/jsp/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Jsp 在servlet中处理多个请求,并为每个请求提供正确的响应_Jsp_Session_Servlets_Request_Client Server - Fatal编程技术网

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

Jsp 在servlet中处理多个请求,并为每个请求提供正确的响应,jsp,session,servlets,request,client-server,Jsp,Session,Servlets,Request,Client Server,我正在处理一个JSP项目(不使用任何框架)。我到了无法找出问题原因的地步。 实现逻辑: 当一个请求被发送到servlet时,它调用一个函数a从数据库中获取动态内容,并将其传递回发出请求的客户机 问题: 当多个请求到达servlet时,它们从函数A获取数据(它从数据库获取表单细节),并将数据传递给错误的客户端。所以在客户端机器中绘制错误的表单 当涉及多个客户端时,如何处理请求和响应。解决此问题的最佳做法是什么。搜索互联网后,我得到了单例模式和代理类将有助于解决这个问题…任何人有任何想法,请帮助我解

我正在处理一个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();
        }
    }
}


}
`//在jsp页面中获取值
字符串val=request.getParameter(“mod_值”);
//调用函数从数据库中获取值
List dataModel=QueryFunction.getPageDetails(val);
//使用此数据模型显示表单

for(int i=0;i看起来您遇到了线程问题

默认情况下,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进行的业务不是线程安全的

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


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

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

当一个线程正在使用连接、语句和结果集时,另一个线程可能会ocme并重写它们。这将导致不一致

这里没有将所有字段设置为静态的逻辑方法。要安全关闭资源,可以使用
try(){}
block

//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();
        }
    }
}*/


}
//QueryFunction类
公共类查询函数{
//公共静态连接connect=null;//不!
//公共静态CallableStatement语句=null;
//公共静态结果集rset=null;
公共静态同步列表getPageDetails(字符串obj){
List dataModel=new ArrayList();
try(Connection connect=DbConnection.GetConnection();CallableStatement语句=(CallableStatement)connect.prepareCall(“{call Get_form_template(?)}”);)
{
语句.设置字符串(1,obj);
try(ResultSet rset=statement.executeQuery();){
while(rset.next()){
DrawForm form=新DrawForm();
//获取数组模型中的值
dataModel.add(表单);
}   
}               
}捕获(可丢弃){
wth.printStackTrace();
}/*最后{
close();
}*/
返回数据模型;
}
//不需要这样做!但如果您坚持,请将连接、结果集和语句作为输入参数传递
/*私有静态void close(){
if(connect!=null){
试一试{
connect.close();
}捕获(SQLE异常){
e、 printStackTrace();
}
}
如果(rset!=null){
试一试{
rset.close();
}捕获(SQLE异常){
e、 printStackTrace();
}
}
if(语句!=null){
试一试{
语句。close();
}捕获(SQLE异常){
e、 printStackTrace();
}
}
}*/
}

try(){}
将自动关闭所有可关闭的it防护。

如果您从servlet中获取错误信息,则这与您的实现有关。对servlet的请求会自动创建一个单独的线程。如果您将用户或客户端标识符分配给servlet类中的成员变量,则可能会发生这种情况。换句话说,不要这样做在servlet中保留任何因请求而异的状态。这可以解释问题,因为servlet是单例的,并且在所有请求中共享。这只是一个初步猜测,因为您没有显示任何代码。不知道问题出在哪里…我将描述过程…客户端请求一个页面…请求转到另一个jsp(假设为B).在B页上,它调用函数a,该函数从数据库检索表单详细信息,并将结果集存储在模型列表中,然后将列表传递给用户。使用该列表,表单将绘制在B页上。我已经放置了我正在使用的一段代码。请查看它的共享代码
QueryFunction.getPageDetails(val)
,看起来它不是线程安全的。另外,为了确保它是否与此部件相关,请通过同步块将其称为
synchronized(sync_obj){QueryFunction.getPageDetails(val);对于(…){…}
(确保所有
数据模型
属性引用也在同步块中(类似于for look)将
sync_obj
声明为静态字段,如
static final Object sync_obj=new Object()
确保它是静态的
我在函数中添加了synchronize关键字。它工作正常。只需确认如果3000个用户同时点击,会不会导致任何问题。比如,当多次点击发生时,它会增加用户的表单加载时间。
synchronize
模块刚刚通知您e
getPageDetails
不是线程安全的。稍后对于您提到的3000个用户,都需要排队,这是不好的(是可能会导致用户太多延迟)。与其绕过/屏蔽问题,不如修复它。
getPageDetails
应该编码为