Jsp 在servlet中处理多个请求,并为每个请求提供正确的响应
我正在处理一个JSP项目(不使用任何框架)。我到了无法找出问题原因的地步。 实现逻辑: 当一个请求被发送到servlet时,它调用一个函数a从数据库中获取动态内容,并将其传递回发出请求的客户机 问题: 当多个请求到达servlet时,它们从函数A获取数据(它从数据库获取表单细节),并将数据传递给错误的客户端。所以在客户端机器中绘制错误的表单 当涉及多个客户端时,如何处理请求和响应。解决此问题的最佳做法是什么。搜索互联网后,我得到了单例模式和代理类将有助于解决这个问题…任何人有任何想法,请帮助我解决这个问题Jsp 在servlet中处理多个请求,并为每个请求提供正确的响应,jsp,session,servlets,request,client-server,Jsp,Session,Servlets,Request,Client Server,我正在处理一个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
模块刚刚通知您egetPageDetails
不是线程安全的。稍后对于您提到的3000个用户,都需要排队,这是不好的(是可能会导致用户太多延迟)。与其绕过/屏蔽问题,不如修复它。getPageDetails
应该编码为