友情提示:如果本网页打开太慢或显示不完整,请尝试鼠标右键“刷新”本网页!阅读过程发现任何错误请告诉我们,谢谢!! 报告错误
喜书网 返回本书目录 我的书架 我的书签 TXT全本下载 进入书吧 加入书签

JSP入门教程(DOC格式)-第19章

按键盘上方向键 ← 或 → 可快速上下翻页,按键盘上的 Enter 键可回到本书目录页,按键盘上方向键 ↑ 可回到本页顶部!
————未阅读完?加入书签已便下次继续阅读!





…………………………………………………………Page 98……………………………………………………………

                                     



调用 anni。dao。ForumDao 的pagedQuery()方法返回我们需要的信息,这 

里只用 domain 中定义的类已经无法满足我们了(显示的信息包含了三个 

表的信息),为了方便起见我们直接使用了 Map 来传递数据。  



public List getAll() throws Exception {  

    Connection conn = null;  

    Statement state = null;  

    List list = new ArrayList();  

  

    try  {  

        conn = DbUtils。getConn();  

        state = conn。createStatement();  

  

        String sql = 〃select 〃 +  

                〃t。id; 〃 +  

                〃t。title; 〃 +  

                〃(select count(id) from ment where  

thread=t。id) as reply; 〃 +  

                〃(select username from user where id=t。user) as  

author; 〃 +  

                〃t。hit; 〃 +  

                〃(select top 1 create_time from ment where  

thread=t。id order by create_time desc) as create_time; 〃 +  

                〃(select top 1 u。username from ment c;user u  

where c。thread=t。id and c。user=u。id 〃 +  

                〃order by create_time desc) as user 〃 +  

            〃from thread t 〃 +  

            〃order by user desc〃 ;  

  

        ResultSet rs = state。executeQuery(sql);  

        while  (rs。next()) {  

            Map map = new HashMap();  

            map。put(〃id〃; rs。getLong(1)); // 主键  

            map。put(〃title〃; rs。getString(2)); // 标题  

            map。put(〃reply〃; rs。getInt(3)); // 回复数  

            map。put(〃author〃; rs。getString(4)); // 作者  

            map。put(〃hit〃; rs。getInt(5)); // 点击数  

            map。put(〃updateDate〃; rs。getTimestamp(6)); // 最后发 

言时间  

            map。put(〃user〃; rs。getString(7)); // 最后发言人  

  

            list。add(map);  

        }  

    } finally  {  



                                 98 / 148  


…………………………………………………………Page 99……………………………………………………………

                                  



           DbUtils。close(null; state; conn);  

       }  

       return list;  

   }        



   或许有人会奇怪为什么不直接使用 ResultSet。这其实是一种理念问题, 

   如果你返回 ResultSet 到 jsp 页面,的确免去了封装成 Map 的步骤,但是 

   同时产生了两个问题。  



   第一,数据库操作对应的代码蔓延到前台页面,有违我们分层设计的初衷。 

   如果觉得我们这是过度设计的话,那么第二个问题则是更严重的,将 

   ResultSet 放到 jsp 上很难控制何时关闭数据库连接,如果发生了异常可 

   能来不及关闭数据连接,用不了多长时间就会耗尽资源了。  



   ForumDao 中,勉强拼凑出三个表连接查询的 sql,还不清楚性能是否有保 

   证。  



2。  显示主题详细信息  



   点击主题标题/forum。do?method=view&id=1,会进入显示对应详细信息的 

   页面/view。jsp。顶部显示的是主题帖子的标题,发布时间,作者和内容。 

   主题内容下面列出所有的回复内容,页面底部是回复使用的表单,只有登 

   录之后才能使用。  



   ForumServlet 中的view()方法用来获得我们需要的主题信息和对应的回 

   复信息。  



   /**  

    * 显示帖子内容。  

    */  

   private void view(HttpServletRequest request; HttpServletResponse  

   response) throws Exception {  

       long id = Long。parseLong(request。getParameter(〃id〃));  

       Map thread = forumDao。viewThread(id);  

       List list = forumDao。getmentsByThread(id);  

       request。setAttribute(〃thread〃; thread);  

       request。setAttribute(〃list〃; list);  

       request。getRequestDispatcher(〃/view。jsp〃)。forward(request;  

   response);  

   }      



   我们从请求中获得主题的 id,获得主题详细信息和对应的回复信息列表, 

   这两项都是使用 Map 传递数据传递到 view。jsp 页面中再使用 el 和 jstl 

   显示出来。  



                              99 / 148  


…………………………………………………………Page 100……………………………………………………………

                                        



    在显示主题详细信息时,顺便讲主题的点击数加一。  



   public Map viewThread(long id) throws Exception {  

       Connection conn = null;  

       PreparedStatement state = null;  

       Map map = new HashMap();  

     

       try  {  

           conn = DbUtils。getConn();  

           state = conn。prepareStatement(〃select  

    t。id;t。title;t。content;t。create_time;u。username 〃 +  

               〃from thread t;user u where t。user=u。id and t。id=?〃);  

           state。setLong(1; id);  

     

           ResultSet rs = state。executeQuery();  

           if  (rs。next()) {  

               map。put(〃id〃; rs。getLong(1)); // 主键  

               map。put(〃title〃; rs。getString(2)); // 标题  

               map。put(〃content〃; rs。getString(3)); // 内容  

               map。put(〃createTime〃; rs。getTimestamp(4)); // 发布时 

    间  

               map。put(〃username〃; rs。getString(5)); // 作者名  

           }  

     

           // 增加点击数  

           state = conn。prepareStatement(〃update thread set  

   hit=hit+1 where id=?〃);  

           state。setLong(1; id);  

           state。executeUpdate();  

       } finally  {  

           DbUtils。close(null; state; conn);  

       }  

       return map;  

    }     



    我们把这个更新操作放到查询之后,使用 update 将 hit 字段加一,也是 

    为了避免在异常情况下找不到对应主题时,不必出现更新异常。  



3。  发布新主题和发布回复  



    这两项对应了 anni。web。ThreadServlet 和 anni。web。mentServlet 中 

    的post()方法。  



                                    100 / 148  


…………………………………………………………Page 101……………………………………………………………

                                     



      为了简易起见,我们仅仅在页面上使用 javascript 检验输入的数据不能 

      为空。  



      提交之后会调用对应 dao 中的 save()方法将数据保存进数据库。最后页 

      面重定向到/forum。do?method=list 或/forum。do?method=view&id=1。实 

      际上它们都是单纯的 create 操作(CRUD 中的C)。  



10。3。3。 显示在线用户列表  



我们使用了 HttpSessionBindingListener 来实现在线用户列表。详细介绍见 

第 8。2 节  “使用HttpSessionBindingListener”。  



/list。jsp 和/view。jsp 两个页面上的在线用户列表显示效果完全一样,如果有 

可能的话,我们希望将这些重复的部分从原来的页面中剥离出来,集中在一起让 

其他页面调用,这样更容易管理和维护。  



为了实现这一功能,我们需要借用另一个 jsp 指令(directive):include。  



   



这里的 file 可以使用相对路径,也可以使用绝对路径。这里的绝对路径与使用 

forward 时一致,都是以应用目录为根目录,参考这里的讨论第 3。4。1。2 节 “绝 

对路径”。  



我们顺便再看一下/include/onlineUser。jsp 的内容:  



  

  

  在线用户  

    

      

     ;{item}  

      

    

   



这就是一个单独的 jsp 页面,可以在里边使用 jsp 指令(directive),el,甚 

至是 taglib。  



不过 taglib 还是要在使用前定义的,因为每个页面都使用了相同的 taglib 定义 

和其他一些相同的 html 配置(编码,css 等),我们也把这部分提取成一个 jsp 

页面,让其他页面引用。这个页面也放在 include 目录下,meta。jsp 的内容如 

下。  



                                  101 / 148  


…………………………………………………………Page 102……………………………………………………………

                                    



  

  

  

   



meta。jsp 里定义了我们使用的 taglib,设置了默认的 contextPath,gb2312 的 

编码格式和 forum。css 样式表。在其他页面里对它进行引用就可以让其他页面内 

容也得到里边定义的功能,包括标签库定义和使用 c:set 设置的变量。  



  

      

    index  

   



include 之间的 jsp 中的定义和变量都是可以相互调用的,但是我们必须为每个 

jsp 页面都指定正确的编码格式。这依然是为了处理中文乱码,meta。jsp 中没有 

指定编码格式就是因为这也里没有
返回目录 上一页 下一页 回到顶部 0 0
未阅读完?加入书签已便下次继续阅读!
温馨提示: 温看小说的同时发表评论,说出自己的看法和其它小伙伴们分享也不错哦!发表书评还可以获得积分和经验奖励,认真写原创书评 被采纳为精评可以获得大量金币、积分和经验奖励哦!