Обработка нескольких запросов в сервлете и предоставление правильного ответа на каждый запрос - PullRequest
0 голосов
/ 29 мая 2018

Я работаю над проектом JSP (без использования какой-либо платформы).Я пришел к тому, что не могу разобраться в причине проблемы.Логика реализации: Когда запрос отправляется сервлету, он вызывает функцию A, чтобы получить динамический контент из базы данных и передать его обратно клиенту, откуда поступил запрос.

Проблема: Когда к сервлету приходит несколько запросовони получают данные из функции 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();
        }
    }
}


}

Ответы [ 2 ]

0 голосов
/ 05 июня 2018

Проблемы возникают из статических / общих полей.Точно так же, как один пример, который я предоставил.

Пока поток использует соединение, оператор и набор результатов, так что другой поток может 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(){} автоматически закроет все закрываемые им охранники.

0 голосов
/ 31 мая 2018

Похоже, у вас проблема с потоками.

По умолчанию веб-движки Java (скажем, tomcat) обрабатывают запросы параллельно.Это означает, что когда есть запрос к серверу, сервер принимает его, в то время как другие запросы выполняются (также с учетом лимита / пула соединений и невыполненных заданий)

Проблема связана с упомянутым вами методом А.Я думаю, что что-то используется в глобальной области видимости, которое совместно используется со всеми запросами / вызовами потоков.

Рассматривая следующий пример:

//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 синхронизированным , чтобы подтвердить его.Но вместо того, чтобы запечатывать параллельную среду, вы можете найти правильное решение для ее исправления.

Вы можете поделиться кодом своего сервера, чтобы мы могли находить проблемы лучше.

...