在线等,只要点通我,马上给分,看了篇jsp安全的文章,从昨天晚上到现在没搞清楚,想骂街了都....

IFindit 2007-03-20 11:18:03
在线等,只要点通我,马上给分,如果是作者的文章有问题骂死他了,我看了快一天了,没明白.....,我笨?....


已经看到有人发了相同的帖子(http://topic.csdn.net/t/20021030/10/1133570.html),但是我还是没看懂,高人解释一下,暂且引用一下它的问题和我的一样:
看到一篇帖子,说了一个jsp线程不安全的问题,然后提出了一种将实例变量变成局部变量的方式,不是太明白。贴出来和大家讨论一下。

<%@ page import="
javax.naming.*,
java.util.*,
java.sql.*,
weblogic.common.*
" %>

<%
String name
String product;
long quantity;

name=request.getParameter("name");
product=request.getParameter("product");
quantity=request.getParameter("quantity"); /* (1)*/
savebuy();
%>

<%!
public void savebuy()
{
/*进行数据库操作,把数据保存到表中*/
try {
Properties props = new Properties();
props.put("user","scott");
props.put("password","tiger");
props.put("server","DEMO");

Driver myDriver = (Driver) Class.forName("weblogic.jdbc.oci.Driver").newInstance();
conn = myDriver.connect("jdbc:weblogic:oracle", props);
stmt = conn.createStatement();

String inssql = "insert into buy(empid, name, dept) values (?, ?, ?,?)";
stmt = conn.prepareStatement(inssql);

stmt.setString(1, name);
stmt.setString(2, procuct);
stmt.setInt(3, quantity);
stmt.execute();
}
catch (Exception e)
{
System.out.println("SQLException was thrown: " + e.getMessage());
}
finally //close connections and statements in a finally block
{
try {
if(stmt != null)
stmt.close();
if(conn != null)
conn.close();
} catch (SQLException sqle) {
System.out.println("SQLException was thrown: " + sqle.getMessage());
}
}
}
%>

上面的程序模拟网上购物中的一部分,把用户在浏览器中输入的用户名,购买的物品名称,数量保存到表BUY中。在savebuy()函数中用到了实例变量,所以它不是线程安全的.因为:程序中的每一条语句都不是原子操作,如name=request.getParameter("name");在执行是会对应多个机器指令,在任何时候都可能因系统调度而转入睡眠状态,让其他的线程继续执行.如果线程A在执行到(1)的时候转入睡眠状态,线程B开始执行并改变QUANTITY的值,那么当又到A执行时,它会从调用savebuy()函数开始执行,这样它保存到表中的QUANTITY是被线程B改过的值,那么线程A对应的用户所实际购买的数量与保持到表中的数据不一致.这是个很严重的问题.

三、解决方法
(3)采用局部变量代替实例变量,函数savebuy()声明如下:
因为在savebuy()中使用的是传给他的形参,是在堆栈中分配的,所以是线程安全的.
public void savebuy(String name,String product, int quantity)
{
......
}

调用方式改为:
<%
String name
String product;
long quantity;

name=request.getParameter("name");
product=request.getParameter("product");
quantity=request.getParameter("quantity"); /* (2) */
savebuy(name,product,quantity)
%>
**************************************************************************
以上为帖子的大致内容,我不明白的地方是:
如果在/* (2) */ 发生作者所说的问题,那不也是不对的吗?
...全文
2107 17 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
17 条回复
切换为时间正序
请发表友善的回复…
发表回复
zhao_tk 2008-08-21
  • 打赏
  • 举报
回复
这贴成精华了,,,真费解
cnoolon 2008-06-16
  • 打赏
  • 举报
回复
[Quote=引用 15 楼 eongowoo 的回复:]
没有研究过线程, jsp在编译过就是servlet了, 而每个线程都会有一个实例在内存中, 好像不会发生
线程B的值赋给线程A.
[/Quote]线程又实例的说法吗,不要误导别人。如果是servlet或jsp的成员变量的话,确实存在多线程安全性问题。
eongowoo 2008-06-10
  • 打赏
  • 举报
回复
没有研究过线程, jsp在编译过就是servlet了, 而每个线程都会有一个实例在内存中, 好像不会发生
线程B的值赋给线程A.
xiaoxiaowuhen 2008-04-07
  • 打赏
  • 举报
回复
记得一个面试量,jsp 中怎样设定线程安全的.就是在页面顶部加一句话,好像后来就不考了,不知道有没有关系?
e_xu 2007-12-16
  • 打赏
  • 举报
回复
d
IFindit 2007-03-20
  • 打赏
  • 举报
回复
星星是星星,一眼看出问题的实质,在此多谢,终于搞明白了....
feng13555 2007-03-20
  • 打赏
  • 举报
回复
学习一下
IFindit 2007-03-20
  • 打赏
  • 举报
回复
那篇文章的来源是http://www.javafan.net/menu/j2ee/200701/20070109153848.html它把最重要的“!”给丢了,真是晕死
IFindit 2007-03-20
  • 打赏
  • 举报
回复
我也在查相关资料,觉得interpb(曾曾胡,深怕情多累美人!) 说得有些道理...
craig_wolfdon 2007-03-20
  • 打赏
  • 举报
回复
我觉得除非是程序里面的并发性的问题,jsp可能在设计的时候就已经把这方面的事处理好了,可能不用我们关心,
interpb 2007-03-20
  • 打赏
  • 举报
回复
你自己写一个 简单的jsp 然后看看tomcat生成的相应的servlet 就可以了

interpb 2007-03-20
  • 打赏
  • 举报
回复
String name
String product;
long quantity; 方法里面的变量是局部变量
IFindit 2007-03-20
  • 打赏
  • 举报
回复
所以这三个变量都是局部变量也就是 servlet service 方法里面的变量
我觉得应该是servlet service 中的成员变量呀
interpb 2007-03-20
  • 打赏
  • 举报
回复
<%
String name
String product;
long quantity;
%>

我觉得的写的不对

上面的三个变量的定义是在<% %> 里面的

所以这三个变量都是局部变量也就是 servlet service 方法里面的变量

不是什么所谓的实例变量 Jsp里面声明实例变量要在<%! %>里面才可以

可以自己写一个jsp 然后查看tomcat生成的servlet文件

就可以知道

sertvlet是以多线程的方式运行 使用文中/*1*/做法 不会造成数据混淆

所以觉得作者的看法 有带商榷 下面继续

IFindit 2007-03-20
  • 打赏
  • 举报
回复
我现在觉得这篇文章有问题是不是?
IFindit 2007-03-20
  • 打赏
  • 举报
回复
是的呀,如果那样,解决方法中仍然会存在同样的问题,如果执行完1后,另一线程执行改变了quantity的值, 再传到函数中也是已经改变了呀。。。。。
yeah920 2007-03-20
  • 打赏
  • 举报
回复
实例变量就是,当
String name
String product;
long quantity;

很多人访问到这里时,
有可能,我的name把你的name覆盖了。因为是公用的。

81,122

社区成员

发帖
与我相关
我的任务
社区描述
Java Web 开发
社区管理员
  • Web 开发社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧