这是示例代码,说明了实例变量和请求属性的用法:
@WebServlet(name = "Upload", urlPatterns = {"/upload"})
@MultipartConfig()
public class Upload extends HttpServlet {
private String txt;
protected void processRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
try{
String txt2 = (String) request.getAttribute("txt2");
//txt and txt2 variables are available for processing.
..........
} finally {
txt = null;//Prepare variable for next request.
}
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
.....
request.setAttribute("txt2", someValue);
//vs
txt = someValue;
processRequest(request, response);
}
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
.....
processRequest(request, response);
}
}
现在我知道实例变量永远不应该在servlet中声明,因为在concurent请求之间共享相同的servlet。但是请求属性呢?使用它们是否安全?
答案 0 :(得分:1)
不确定初始化变量是什么意思。在servlet上你或者在哪里?
根据您的需要,可能会涉及到您无法控制合同的API(因为它们不是您的API)。
例如,当过滤器链处理请求时。也许一个过滤器对先前在链中执行的过滤器设置的数据感兴趣。您没有办法在过滤器链合同上传递数据。请求属性可能是一个选项。使用ThreadLocal可能是另一种,但它具有性能影响,并不总是适合。
另一个例子,也许您将一个请求从servlet转发到另一个请求。同样,您将无法选择使用您定义的任何成员变量。
此外,如果您考虑在servlet上添加成员变量,请记住Servlet不是线程安全的。你会怎么做?同步请求处理,每个servlet只处理一个请求?
答案 1 :(得分:1)
您的servlet将在并发请求中服务数百个,每个请求将使用相同的servlet共享实例,因此使用私有实例变量将导致不一致的行为。除非您同步对它的访问,否则会导致访问此私有字段的争用更多,从而减慢响应时间,从而产生瓶颈。
虽然将绑定到单个请求中的属性存储将允许您避免此类问题,而且它旨在克服与您类似的问题。