`
lighter
  • 浏览: 501001 次
  • 性别: Icon_minigender_1
  • 来自: 广州
社区版块
存档分类
最新评论

小心给servlet忽悠了

阅读更多
你真的会写线程安全的servlet吗?

很多人认为servlet随便怎样写可以的,反正是线程安全的,没有什么关系的.那我们来看看下面的这一个例子吧.
首先要看一下小段的servlet代码,如下:
public class Test extends HttpServlet {
   String name;

   protected void doPost (HttpServletRequest req,
                       HttpServletResponse res) {
     name = req.getParameter("name");
     ...
     out.println(name + ", thanks for visiting!");
   }
}


我相信不少人的代码在经意或不经意间都这样写过,然后自己一个跑一下程序,可以啦,然后就不再理会啦,上面的程序是有问题的,假如有两个用户同时用到这一段代码的程序的功能,就有可能会出现如下这种情况:

引用
Thread 1: assign "A" to name
Thread 2: assign "B" to name
Thread 1: print "B, thanks for visiting!"
Thread 2: print "B, thanks for visiting!"


怎样改写呢?其实也比较简单的,比较出名的找bug的工具Fortify推荐如下一种方式如下:
public class Test extends HttpServlet {

   protected void doPost (HttpServletRequest req, HttpServletResponse res) {
	RequestHandler handler = new RequestHandler();
	handler.handle(req, res);
   }
}

public class RequestHandler {

   String name;

   public void handle(HttpServletRequest req, HttpServletResponse res) {
     name = req.getParameter("name");
     ...
     out.println(name + ", thanks for visiting!");
   }
}


请记得这一句话:
引用
Do not use Servlet member fields for anything but constants. (i.e. make all member fields static final).


刚才今天我的一个同事也写了类似上面的有bug的那一个servlet程序,我也改造过来了;
不过是用了另一种方式实现的,用的是ThreadLocal这一个关键类,伪代码如下:
public class Test extends HttpServlet {
	private static final ThreadLocal parameterLocal = new ThreadLocal();  
	
	private static final ThreadLocal filesLocal = new ThreadLocal();      
	
	protected Map getFiles() {
		Map files = (HashMap)filesLocal.get();
		if(files==null){
			files = new HashMap();
			filesLocal.set(files);
		}
		return files;
	}

	protected  Map getParameters() {
		Map parameters = (HashMap)parameterLocal.get();
		if(parameters==null){
			parameters = new HashMap();
			parameterLocal.set(parameters);
		}
		return parameters;
	}

	public void doPost(HttpServletRequest request, HttpServletResponse response) {
			.....//可以通过getParameters()返回Map对象
			log.info(getParameters().get("possess"));
	
			Iterator iterator = getFiles().values().iterator(); //可以通过getFiles()返回Map对象
			FileItem item = (FileItem) iterator.next();
			.....
	}
}


分享到:
评论
2 楼 CherryRemind 2008-01-08  
Servlet 不用成员变量,变量放在method里面, 遇到过类似问题
1 楼 qiuriyuchen 2007-12-14  
晕,不知在搞什么,这样不就可以了吗  
public class Test extends HttpServlet { 
      
     
       protected void doPost (HttpServletRequest req, 
                           HttpServletResponse res) { 
        String  name = req.getParameter("name"); 
         ... 
         out.println(name + ", thanks for visiting!"); 
       } 
  } 

相关推荐

    servlet基础与servlet容器模型

    Servlet是一个Java类,遵循javax.servlet.Servlet接口,它允许开发者扩展服务器的功能。当用户向Web服务器发送一个请求时,Servlet会接收到这个请求,处理数据,然后返回响应。Servlet的主要生命周期方法包括:`init...

    日志管理系统SERVLET SERVLET SERVLET

    刚刚接触java时做的日志管理系统,做的很简单,适合初学着 servlet servlet servlet servlet servlet日志管理系统 servlet servlet servlet servlet servlet日志管理系统 servlet servlet servlet servlet servlet...

    javax.servlet jar包---解决找不到javax.servlet.*等问题

    它允许开发者用Java编写服务器端程序,这些程序可以处理来自HTTP客户端的请求,并将结果返回给客户端。 2. **javax.servlet包中的主要类和接口** - `Servlet`: 这是所有Servlet的基类,定义了Servlet的基本行为,...

    servlet线程安全问题

    在 Servlet 中,实例变量的使用需要非常小心,因为实例变量可能会被多个线程同时访问。如果不注意实例变量的使用,可能会导致难以发现的错误。例如,在上面的例子中,如果将 output 变量定义为实例变量,那么当多个...

    用于servlet程序的开发的servlet-jar包

    Servlet是Java平台上的一个核心组件,它允许开发者创建动态web应用程序。Servlet API是Java Servlet规范的一部分,它定义了服务器端程序如何与HTTP协议交互以及如何处理来自web客户端的请求并返回响应。`servlet.jar...

    servlet源码 servlet-api-src javax.servlet.Servlet源码

    Servlet是Java Web开发中的核心组件,它是一种服务器端的接口,用于处理来自客户端(通常是Web浏览器)的请求并返回响应。在Java EE中,Servlet API是实现这些功能的基础框架。`javax.servlet.Servlet`是Servlet的...

    javaEE servlet-api

    Servlet API还提供了Filter的概念,允许开发者在请求到达Servlet之前和响应离开Servlet之后对其进行拦截和处理。`javax.servlet.Filter`接口定义了`doFilter()`方法,这使得我们可以实现如认证、日志记录、数据过滤...

    Servlet中文API文档 servlet

    Servlet是Java平台上的一个核心技术,用于构建动态Web应用程序。Servlet API是Java Servlet规范的一部分,它定义了服务器端Java程序如何与HTTP协议交互,以及如何处理来自Web客户端的请求并生成响应。这份"Servlet...

    Servlet实验报告.pdf

    4. Servlet 将处理结果返回给客户端。 六、Servlet 方法 1. init() 方法:在 Servlet 生命周期中第一个被调用的方法,用于初始化 Servlet。 2. destory() 方法:在 Servlet 生命周期中最后一个被调用的方法,用于...

    Servlet基础知识总结

    初始化参数可以在`web.xml`中通过`<init-param>`元素配置,它们会被传递给Servlet实例中的`init()`方法。这些参数通常用于配置Servlet的行为,例如设置数据库连接信息等。 ```xml <servlet> <servlet-name>...

    servlet api servlet api

    <servlet-name>MyServlet</servlet-name> <servlet-class>com.example.MyServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>MyServlet</servlet-name> <url-pattern>/myservice </servlet...

    javax.servlet.jar下载

    Files contained in javax.servlet.jar: META-INF/MANIFEST.MF javax/servlet/http/LocalStrings.properties javax.servlet.http.HttpSessionBindingListener.class javax.servlet....

    serlvet 源码 servlet-src 源文件

    4. **ServletConfig接口**:在Servlet初始化时,Servlet容器会传递一个ServletConfig对象给Servlet,这个对象包含了Servlet的配置信息,如Servlet名称、初始化参数等。 5. **ServletContext接口**:表示整个Web应用...

    servlet 笔记

    ### Servlet基础知识及应用详解 #### 一、Servlet概述 Servlet是一种服务器端的Java技术,用于扩展应用程序的功能。它主要用于Web应用程序开发,可以处理客户端发送到Web服务器的各种请求,并且能够生成动态网页。...

    servlet api 与servlet src

    Servlet API与Servlet源码(SRC)是Java Web开发中的核心组成部分,主要应用于服务器端的动态网页处理。在本文中,我们将深入探讨这两个概念及其在Java EE(以前的J2EE)环境中的应用。 Servlet API是Java Servlet...

    jakarta-servletapi-4-src.zip servlet源码

    《深入理解Jakarta Servlet API 4.0源码》 Servlet技术是Java Web开发的核心,它为Web应用程序提供了服务器端的编程接口。Jakarta Servlet API 4.0是Servlet规范的最新版本,它包含了对HTTP协议处理、生命周期管理...

    Servlet

    Servlet可以处理请求、更新模型,然后使用`RequestDispatcher`将控制权传递给JSP,由JSP生成HTML响应。 八、源码分析 对于学习和调试Servlet,理解其内部源码非常有益。例如,`HttpServletRequest`和`...

    Servlet3.0参考手册

    Servlet3.0是Java Web开发中的一个重要里程碑,它在Servlet2.5的基础上引入了许多新特性,极大地提高了开发效率和灵活性。这份"Servlet3.0参考手册"无疑为开发者提供了全面的API参考和实用指南。 首先,Servlet3.0...

Global site tag (gtag.js) - Google Analytics