在 servlet 中处理多个请求并对每个请求提供正确的响应
Handle multiple request in servlet and provide correct response to each request
我正在做一个 JSP 项目(不使用任何框架)。我到了无法找出问题原因的地步。
实现逻辑:
当请求发送到 servlet 时,它调用函数 A 从数据库中获取动态内容并将其传递回请求来自的客户端。
问题:
当多个请求到达 servlet 时,它们从函数 A 中获取数据(它从数据库中获取表单详细信息)并将数据传递给错误的客户端。所以在客户端机器上绘制了错误的表格。
涉及多个客户端时如何处理请求和响应。解决此问题的最佳做法是什么。在互联网上搜索后我得到了单例模式和代理 class 将有助于解决这个问题....任何人有任何想法请帮助我解决这个问题。
`// 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();
}
}
}
}
看起来你有线程问题。
默认情况下 java 网络引擎(比方说 tomcat)并行处理请求。这意味着一旦有对服务器的请求,服务器就会接受它,而另一个请求正在进行中。(还要考虑连接 limit/pool 和积压)
问题出在你提到的A方法上。我认为在全球范围内使用了可以与所有人共享的东西 requests/thread-calls.
考虑以下示例:
//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),最后一个 returns 响应 8(预期 99)
我觉得你说的方法A做的业务不是线程安全的
您可以标记 method_a synchronized 以验证它。但不是密封并行环境,你可能会找到一个正确的解决方案来修复它。
你可以分享你的服务器代码,这样我们会更好地发现问题。
问题来自 static/shared 个字段。就像我提供的一个例子。
当一个线程正在使用连接、语句和结果集时,另一个线程可以占用并覆盖它们。这样会造成不一致。
这里没有将所有字段设为静态的合乎逻辑的方法。为了安全地关闭资源,您可以使用 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(){}
将自动关闭它保护的任何可关闭对象。
我正在做一个 JSP 项目(不使用任何框架)。我到了无法找出问题原因的地步。 实现逻辑: 当请求发送到 servlet 时,它调用函数 A 从数据库中获取动态内容并将其传递回请求来自的客户端。
问题: 当多个请求到达 servlet 时,它们从函数 A 中获取数据(它从数据库中获取表单详细信息)并将数据传递给错误的客户端。所以在客户端机器上绘制了错误的表格。
涉及多个客户端时如何处理请求和响应。解决此问题的最佳做法是什么。在互联网上搜索后我得到了单例模式和代理 class 将有助于解决这个问题....任何人有任何想法请帮助我解决这个问题。
`// 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();
}
}
}
}
看起来你有线程问题。
默认情况下 java 网络引擎(比方说 tomcat)并行处理请求。这意味着一旦有对服务器的请求,服务器就会接受它,而另一个请求正在进行中。(还要考虑连接 limit/pool 和积压)
问题出在你提到的A方法上。我认为在全球范围内使用了可以与所有人共享的东西 requests/thread-calls.
考虑以下示例:
//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),最后一个 returns 响应 8(预期 99)
我觉得你说的方法A做的业务不是线程安全的
您可以标记 method_a synchronized 以验证它。但不是密封并行环境,你可能会找到一个正确的解决方案来修复它。
你可以分享你的服务器代码,这样我们会更好地发现问题。
问题来自 static/shared 个字段。就像我提供的一个例子。
当一个线程正在使用连接、语句和结果集时,另一个线程可以占用并覆盖它们。这样会造成不一致。
这里没有将所有字段设为静态的合乎逻辑的方法。为了安全地关闭资源,您可以使用 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(){}
将自动关闭它保护的任何可关闭对象。