首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > JAVA > Java Web开发 >

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

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

在线等,只要点通我,马上给分,看了篇jsp安全的文章,从昨天晚上到现在没搞清楚,想骂街了都....
在线等,只要点通我,马上给分,如果是作者的文章有问题骂死他了,我看了快一天了,没明白.....,我笨?....


已经看到有人发了相同的帖子(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)       */       发生作者所说的问题,那不也是不对的吗?  


[解决办法]
<%
String name
String product;
long quantity;
%>

我觉得的写的不对

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

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

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

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

就可以知道

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

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


[解决办法]
你自己写一个 简单的jsp 然后看看tomcat生成的相应的servlet 就可以了

热点排行