登陆 | 注册
你现在的位置:我的论坛 >> java >> 避免JSP/Servlet的并发问题
避免JSP/Servlet的并发问题

    JSP/Servlet 同时多次调用实际上是对同一个实例的服务方法的多次调用。这说明Servlet的类变量实际上由同时访问该servlet的所有用户共享。所以 JSP/Servlet 一般不应该有可写的类变量,否则必须要有同步机制来实现。但是即使进行呢同步也不应该这么做,因为有可能有疏忽。

    我曾经花很长时间想知道为什么我的Web页面会随机的显示其他用户的个人注册信息,最后发现程序员把profile对象放到呢servlet类变量中,而没有放到session或request变量中。如果第二个用户访问应用而且在第一个用户前结束任务,第一个用户就会突然看到第二个用户的有关数据。

    如果采用了成熟的第三方框架,比如struts 就不会出现这个问题。因为这些成熟的第三方框架在容器中为用户的每一次请求创建了新的组件实例。

楼主 创建:08-11-23 11:41:47 更新:08-11-23 11:41:47
发表回复

1/1(共1页)
大狗熊

/***
 * decompile from org.apache.jasper.runtime.HttpJspBase
 
*/
package com.dangdang.web;

import java.io.IOException;
import javax.servlet.ServletConfig;
import javax.servlet.jsp.HttpJspPage;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;


public abstract class Page extends HttpServlet implements HttpJspPage
{
    
protected Page(){}


    
//override the HttpServlet class
    @Override
    
public final void init(ServletConfig config) throws ServletException
    {
        
super.init(config);
        
this.jspInit();
        
this._jspInit();
    }

    @Override
    
public final void destroy()
    {
        
this.jspDestroy();
        
this._jspDestroy();
    }

    @Override
    
public final void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
    {     
        
this.getAction(request,response).execute();
        
this._jspService(request, response);
    }
    
    
public abstract Action getAction(HttpServletRequest request, HttpServletResponse response);
    
    
//do nothing only implements the  HttpJspPage interface
    public void jspInit(){}
    
public void jspDestroy(){}
    
    
//web controller override the following three methods
    public void _jspInit(){}
    
protected void _jspDestroy(){}
    
public void _jspService(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException{}  
    
}


package com.dangdang.web;

import com.dangdang.util.Log;
import java.lang.reflect.Field;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public abstract class Action 
{
    
protected HttpServletRequest request;
    
protected HttpServletResponse response;
    
    
public Action(HttpServletRequest request, HttpServletResponse response)
    {
        
this.request=request;
        
this.response=response;
    }
    
    
protected abstract void processRequest();
    
    
final void execute()
    {
        
this.processRequest();
        
        
try
        {
            Field[] fs 
= this.getClass().getDeclaredFields();
            
            
for(Field f : fs)
                
if(f.getModifiers() == 1)
                {
                    f.setAccessible(
true);
                    request.setAttribute(f.getName(), f.get(
this));
                }
        }
        
catch(Exception e)
        { 
            Log.Write(e.getMessage()); 
        }
    }
}

package controller;

import com.dangdang.web.Action;
import com.dangdang.web.Page;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class Index extends Page
{
    @Override
    
public Action getAction(HttpServletRequest request, HttpServletResponse response)
    {
        
return new Action(request,response)
        {
            
public String message;
            
            @Override
            
protected void processRequest()
            {
                
this.message = request.getParameter("message");
            }
        };
    }
}

1楼 创建:08-11-25 22:19:41 更新:08-11-25 22:19:41
发表回复
1 共1条
Copyright (C) 2004-2008, All Rights Reserved