流已关闭的错误,我用debug查看,错误在Article类里的setAll方法中,大家帮我看看。
数据库里的信息是没问题的,执行到setCont(rs.getString("cont"));那句就出错。
貌似不是这句有问题,
我把这句拿到setAll方法里的第一行,就不报错了。
我更改了set方法的顺序,不一定在哪句就报错“流已关闭了”
谁帮我看看到底是怎么个事。。
       //JSP里的语句<%!
        /*展示树状结构的贴子,其中DB是一个封装类,负责拿到和关闭Connection Statement ResultSet等等
          *查询数据库,找到子贴并将子贴创建成Article对象加入到ArrayList中 void Tree(Connection cnn,ArrayList<Article> articles,int id,int grade)
{
Statement sm = DB.getStatement(cnn);
ResultSet rs = DB.executeQuery(sm,"select * from bbs where pid ="+id);

try
{
while(rs.next())
{
Article a = new Article();
a.setAll(rs);  //为Article的成员变量赋值
a.setGrade(grade);
articles.add(a);
if(!a.isLeaf())
{
                                        //递归  一直找该贴的子帖
Tree(cnn,articles,a.getId(),grade+1);
}
}
} catch (SQLException e)
{
e.printStackTrace();
} finally
{
//DB.close(rs);   关闭rs   跟这里没关系,我注释掉后照样报错流已关闭
//DB.close(sm);   关闭sm
}
}
%><%
ArrayList<Article> articles = new ArrayList<Article> ();
Connection cnn = DB.getConnection();
Tree(cnn,articles,0,0);
DB.close(cnn);  //关闭数据库连接

%>
/**  Article类
 */import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Date;public class Article
{
private int id;
private int pid;
private int rootid;
private String title;
private String cont;
private Date date;
private boolean isleaf;
private int grade;

/*中间是一大堆简单的set和get方法,我这里省略掉了先*/        //setAll是将所有的成员变量赋值 调用省略掉的N个set方法 public void setAll(ResultSet rs)
{
try
{
             //把报错那行移到第一行就不报错了为什么,颠倒这几行语句的话,不一定到哪行就报错“流已关闭”
setCont(rs.getString("cont"));
setId(rs.getInt("id"));
setPid(rs.getInt("pid"));
setRootid(rs.getInt("rootid"));
setTitle(rs.getString("title"));
setleaf(rs.getInt("isleaf") == 0 ? true : false);
setDate(rs.getTimestamp("pdate"));
     //一执行到下面这句就报错,debug直接跳到catch语句,但我把这句拿到上面就不报错了。为什么?
                        setCont(rs.getString("cont"));
setGrade(0);

} catch (SQLException e)
{
                        //就是这里报错,报错写到“流已关闭”
System.out.println("fffffffffffffffffffffffffff");
}
}
}

解决方案 »

  1.   

    此回复为自动发出,仅用于显示而已,并无任何其他特殊作用
    楼主【jingulang】截止到2008-07-19 11:52:45的历史汇总数据(不包括此帖):
    发帖的总数量:28                       发帖的总分数:840                      每贴平均分数:30                       
    回帖的总数量:413                      得分贴总数量:159                      回帖的得分率:38%                      
    结贴的总数量:27                       结贴的总分数:820                      
    无满意结贴数:2                        无满意结贴分:40                       
    未结的帖子数:1                        未结的总分数:20                       
    结贴的百分比:96.43 %               结分的百分比:97.62 %                  
    无满意结贴率:7.41  %               无满意结分率:4.88  %                  
    值得尊敬
      

  2.   

    看起来没问题喵,楼主的rs是在什么地方关闭的?会不会是getTimestamp方法里有调用close?
      

  3.   

    你 rs.getString("cont") 这句执行了两次,换成下面方法试试:import java.sql.ResultSet;
    import java.sql.SQLException;
    import java.util.Date;public class Article
    {
        private int id;
        private int pid;
        private int rootid;
        private String title;
        private String cont;
        private Date date;
        private boolean isleaf;
        private int grade;
        
        /*中间是一大堆简单的set和get方法,我这里省略掉了先*/    //setAll是将所有的成员变量赋值 调用省略掉的N个set方法    public void setAll(ResultSet rs)
        {
            try
            {
                 //把报错那行移到第一行就不报错了为什么,颠倒这几行语句的话,不一定到哪行就报错“流已关闭”
                String cont = rs.getString("cont");  //////
                setCont(cont);
                setId(rs.getInt("id"));
                setPid(rs.getInt("pid"));
                setRootid(rs.getInt("rootid"));
                setTitle(rs.getString("title"));
                setleaf(rs.getInt("isleaf") == 0 ? true : false);
                setDate(rs.getTimestamp("pdate"));
                //一执行到下面这句就报错,debug直接跳到catch语句,但我把这句拿到上面就不报错了。为什么?
                setCont(cont);
                setGrade(0);
            } catch (SQLException e)
            {
                //就是这里报错,报错写到“流已关闭”
                System.out.println("fffffffffffffffffffffffffff");
            }        
        }
    }
      

  4.   

    另外注意:无论从效率还是数据访问安全性上看 rs.getString("cont") 这样从结果集中读同一个字段数据的操作最好只作一次,因为 JDBC 规范要求每个字段的数据只允许读一次,虽然有些数据库例如 MySQL 允许读一次以上(它 JDBC 驱动的实现上有点小问题),但不意味着其它数据库也允许。
      

  5.   

    你这个rs.getString("cont"));是不是二进制字段?
    如果是,那这个字段必须按照你select出的顺序来取,或者如你这里所做的,将该字段提前。
    否则的确是会抛“流已关闭”的异常。
      

  6.   

    看这个,跟顺序有关系
    http://blog.chinaunix.net/u2/69227/showart_719748.html
      

  7.   

    8,9楼说的是一个问题
    不过我没明白什么是二进制字段  
    我的表里无非就是number  varchar2  long  date  这4种类型什么属于二进制字段啊rs.getString("cont"))我这里存的是汉字  cont字段是long型  (我用的是Oracle)另外4楼提的方法我只能明天试了  我现在在网吧。。
      

  8.   


    如果是“二进制”类型字段,特别是 Oracle 是有读取顺序的问题,按字段在结果集中出现的顺序依次读取就行(同样要保证每个字段的值只读取一次)。
      

  9.   

    select * from bbs where pid ="+id
    这个是关键,你应该手工编写字段出现的顺序,且严格按照字段出现的顺序读取。
    原因是,某些JDBC驱动做的不是很好,比如SQL Server JDBC 2.0的驱动就有这个毛病。解决方法
    1 换 JDBC 3.0的驱动,最新的驱动应该都支持重复读取和不按顺序读取
    2 按照我前面的建议,指定字段出现顺序,并严格按照顺序读取
      

  10.   

    String cont = rs.getString("cont");  //////
                setCont(cont);
                setId(rs.getInt("id"));
                setPid(rs.getInt("pid"));
                setRootid(rs.getInt("rootid"));
                setTitle(rs.getString("title"));
                setleaf(rs.getInt("isleaf") == 0 ? true : false);
                setDate(rs.getTimestamp("pdate"));
      

  11.   

    确实跟顺序有关只是我的数据库里没二进制字段啊但我数据库里rs.getString("cont")这个字段里  有乱码   莫非这些乱码是二进制字段吗我插的是汉字  但到数据库里就是乱码了是不是request.setCharacterEncoding("gbk");这句可以解决乱码问题?
      

  12.   

    这就更加说明问题了,MYSQL当中的LONG,大文本字段,就是相当于oracle当中的CLOB。