Day07論壇2

  1. 環境準備+版塊相關功能

版塊列表 1(個請求)javascript

ForumAction.list()css

顯示單個版塊(主題列表) 1html

ForumAction.show()java

------瀏覽器

發新帖 2dom

TopicAction.addUI()eclipse

TopicAction.add()jsp

顯示單個主題(主帖+回帖列表) 1編輯器

TopicAction.show()ide

------

回帖 2

ReplyAction.addUI()

ReplyAction.add()

步驟:建立Actionà寫裏面的方法(方法名,返回值) à建立頁面à配置(Action註釋和struts.xml)à建立serviceà配置(ServiceImpl註釋和在BaseAction中注入service) à寫具體的Action方法和service方法à套用靜態頁面

1.先實現版塊列表功能:

(這裏ForumAction和ForumManageAction公用service)

ForumAction:

import cn.itcast.oa.base.BaseAction;

import cn.itcast.oa.domain.Forum;

@Controller

@Scope("prototype")

public class ForumAction extends BaseAction<Forum>{

 

    /** 版塊列表 */

    public String list() throws Exception {

        List<Forum> forumList = forumService.findAll();

        ActionContext.getContext().put("forumList", forumList);

        return "list";

    }

    

    /** 顯示單個版塊(主題列表) */

    public String show() throws Exception {

        return "show";

    }

}

TopicAction:

@Controller

@Scope("prototype")

public class TopicAction extends BaseAction<Topic>{

 

    /** 顯示單個主題 */

    public String show() throws Exception {

        return "show";

    }

    

    /** 發新帖頁面*/

    public String addUI() throws Exception {

        return "addUI";

    }

    

    /** 發新帖 */

    public String add() throws Exception {

        return "toShow";    //轉到當前這個 新主題的頁面

    }    

}

 

ReplyAction:

@Controller

@Scope("prototype")

public class ReplyAction extends BaseAction<Reply>{

 

    /** 發表回覆頁面 */

    public String addUI() throws Exception {

        return "addUI";

    }

    

    /** 發表回覆 */

    public String add() throws Exception {

        return "toTopicShow";    //轉到當前回覆所屬的主題顯示頁面

    }

}

(ForumAction對應的)list.jsp:

        <div class="ForumPageTableBorder" style="margin-top: 25px;">

        <s:iterator value="forumList">

            <table width="100%" border="0" cellspacing="0" cellpadding="0">

            

                <!--表頭-->

                <tr align="center" valign="middle">

                    <td colspan="3" class="ForumPageTableTitleLeft">版塊</td>

                    <td width="80" class="ForumPageTableTitle">主題數</td>

                    <td width="80" class="ForumPageTableTitle">文章數</td>

                    <td width="270" class="ForumPageTableTitle">最後發表的主題</td>

                </tr>

                <tr height="1" class="ForumPageTableTitleLine"><td colspan="9"></td></tr>

                <tr height="3"><td colspan="9"></td></tr>

            

                <!--版面列表-->

                <tbody class="dataContainer" datakey="forumList">

                <tr height="78" align="center" class="template">

                    <td width="3"></td>

                    <td width="75" class="ForumPageTableDataLine">

                        <img src="${pageContext.request.contextPath}/style/images/forumpage3.gif" />

                    </td>

                    <td class="ForumPageTableDataLine">

                        <ul class="ForumPageTopicUl">

                            <li class="ForumPageTopic">

                            <s:a cssClass="ForumPageTopic" action="forum_show?id=%{id}">${name}</s:a></li>

                            <li class="ForumPageTopicMemo">${description}</li>

                        </ul>

                    </td>

                    <td class="ForumPageTableDataLine"><b>${topicCount}</b></td>

                    <td class="ForumPageTableDataLine"><b>${articleCount}</b></td>

                    <td class="ForumPageTableDataLine">

                        <ul class="ForumPageTopicUl">

                            <li><font color="#444444">主題:</font>

                                <s:a cssClass="ForumTitle" action="topic_show?id=%{lastTopic.id }">${lastTopic.title}</s:a>

                            </li>

                            <li><font color="#444444">做者:</font> ${lastTopic.author.name}</li>

                            <li><font color="#444444">時間:</font> <s:date name="lastTopic.postTime" format="yyyyMMdd HH:mm:ss"/></li>

                        </ul>

                    </td>

                    <td width="3"></td>

                </tr>

                </tbody>

                <!-- 版面列表結束 -->

                

                <tr height="3"><td colspan="9"></td></tr>

            </table>

        </s:iterator>

        </div>

Struts.xml:

<!-- 論壇:版塊相關 -->

    <action name="forum_*" class="forumAction" method="{1}">

        <result name="list">/WEB-INF/jsp/forumAction/list.jsp</result>

        <result name="show">/WEB-INF/jsp/forumAction/show.jsp</result>

    </action>

      

    <!-- 論壇:主題相關 -->

    <action name="topic_*" class="topicAction" method="{1}">

        <result name="show">/WEB-INF/jsp/topicAction/show.jsp</result>

        <result name="addUI">/WEB-INF/jsp/topicAction/addUI.jsp</result>

        <result name="toShow" type="redirectAction">topic_show?id=${id}</result>

    </action>

      

    <!-- 論壇:回覆相關 -->

    <action name="reply_*" class="replyAction" method="{1}">

        <result name="addUI">/WEB-INF/jsp/replyAction/addUI.jsp</result>

        <result name="toTopicShow" type="redirectAction">topic_show?id=${id}</result>

    </action>


效果:

2.再實現單個版塊(主題列表)功能:(暫時不作分頁)

ForumAction:

@Controller

@Scope("prototype")

public class ForumAction extends BaseAction<Forum>{

 

    /** 版塊列表 */

    public String list() throws Exception {

        List<Forum> forumList = forumService.findAll();

        ActionContext.getContext().put("forumList", forumList);

        return "list";

    }

    

    /** 顯示單個版塊(主題列表) */

    public String show() throws Exception {

        //準備數據:forum

        Forum forum = forumService.getById(model.getId());

        ActionContext.getContext().put("forum", forum);

        

        //準備數據:topicList

        List<Topic> topicList = topicService.findByForum(forum);

        ActionContext.getContext().put("topicList", topicList);

        return "show";

    }

}

topicServiceImpl:

@Service

@Transactional

@SuppressWarnings("unchecked")

public class TopicServiceImpl extends DaoSupportImpl<Topic> implements TopicService{

 

    /**

     * 查詢指定版塊的主題列表,最新狀態的排到前面,置頂帖排到最前面

     */

    public List<Topic> findByForum(Forum forum) {

        return getSession().createQuery(//

                "from Topic t where t.forum = ? order by (case t.type when 2 then 2 else 0 end) desc, t.lastUpdateTime desc")//

                .setParameter(0, forum)//

                .list();

    }

}

其中Topic.java是這樣的:

/**

* 實體:主貼

* @author Tan

*

*/

public class Topic extends Article{

 

    /** 普通貼 */

    public static final int TYPE_NORMAL = 0;

    /** 精品貼 */

    public static final int TYPE_BEST = 1;

    /** 置頂貼 */

    public static final int TYPE_TOP = 2;

      

    

    private String title;    //標題

    private int type;    //類型

    private int replyCount;    //回覆數量

    private Date lastUpdateTime;    //最後文章的發表時間

    

    private Forum forum;    //版塊 主貼與版塊:多對一

    private Set<Reply> replies = new HashSet<Reply>();    //回覆 主貼與回覆:多對一

    private Reply lastReply;    //最後回覆

……

}

Topic還繼承了Article.java:

/**

* 實體:文章

* @author Tan

*

*/

public abstract class Article {

 

    private Long id;

    private String content;    //內容(TEXT類型)

    private Date postTime;    //發表時間

    private String ipAddr;    //ip地址

    

    private User author;    //做者

……

需求頁面是這樣的:

ForumAction中的show.jsp:

<!-- 標題顯示 -->

<div id="Title_bar">

<div id="Title_bar_Head">

<div id="Title_Head"></div>

<div id="Title"><!--頁面標題-->

<img border="0" width="13" height="13" src="${pageContext.request.contextPath}/style/images/title_arrow.gif"/>${forum.name }】中的主題列表

</div>

<div id="Title_End"></div>

</div>

</div>

 

<div id="MainArea">

    <div id="PageHead"></div>

    <center>

        <div class="ItemBlock_Title1" style="width: 98%;">

            <font class="MenuPoint"> &gt; </font>

            <s:a action="forum_list">論壇</s:a>

            <font class="MenuPoint"> &gt; </font>

            ${forum.name }

            <span style="margin-left:30px;"><a href="${pageContext.request.contextPath}/BBS_Topic/saveUI.html">

                <img align="absmiddle" src="${pageContext.request.contextPath}/style/blue/images/button/publishNewTopic.png"/></a>

            </span>

        </div>

        

        <div class="ForumPageTableBorder">

            <table width="100%" border="0" cellspacing="0" cellpadding="0">

                <!--表頭-->

                <tr align="center" valign="middle">

                    <td width="3" class="ForumPageTableTitleLeft">

                        <img border="0" width="1" height="1" src="${pageContext.request.contextPath}/style/images/blank.gif" />

                    </td>

                    <td width="50" class="ForumPageTableTitle"><!--狀態/圖標-->&nbsp;</td>

                    <td class="ForumPageTableTitle">主題</td>

                    <td width="130" class="ForumPageTableTitle">做者</td>

                    <td width="100" class="ForumPageTableTitle">回覆數</td>

                    <td width="130" class="ForumPageTableTitle">最後回覆</td>

                    <td width="3" class="ForumPageTableTitleRight">

                        <img border="0" width="1" height="1" src="${pageContext.request.contextPath}/style/images/blank.gif" />

                    </td>

                </tr>

                <tr height="1" class="ForumPageTableTitleLine"><td colspan="8"></td></tr>

                <tr height=3><td colspan=8></td></tr>

                    

                <!--主題列表-->

                <tbody class="dataContainer" datakey="topicList">

                <s:iterator value="topicList">

                    <tr height="35" id="d0" class="template">

                        <td></td>

                        <td class="ForumTopicPageDataLine" align="center"><img src="${pageContext.request.contextPath}/style/images/topicType_${topic.type}.gif" /></td>

                        <td class="Topic"><s:a cssClass="Default" action="topic_show?id=%{id}">${title}</s:a></td>

                        <td class="ForumTopicPageDataLine">

                            <ul class="ForumPageTopicUl">

                                <li class="Author">{author.name}</li>

                                <li class="CreateTime"><s:date name="postTime" format="yyyyMMdd HH:mm:ss"/> </li>

                            </ul>

                        </td>

                        <td class="ForumTopicPageDataLine Reply" align="center"><b>${replyCount}</b></td>

                        <td class="ForumTopicPageDataLine">

                            <ul class="ForumPageTopicUl">

                                <li class="Author">${lastReply.author.name }</li>

                                <li class="CreateTime"><s:date name="lastReply.postTime" format="yyyyMMdd HH:mm:ss"/></li>

                            </ul>

                        </td>

                        <td></td>

                    </tr>

                </s:iterator>

                </tbody>

                    <!--主題列表結束-->    

效果頁面:

  1. 主題相關功能

以前已經實現了版塊列表和單個版塊展現(主題列表)的功能,由於尚未數據,因此主題展現的功能暫且不作,先作主題添加的功能(發新帖).

主題添加(發新帖):

添加頁面:

發新帖的請求是從版塊的單個版塊展現(主題列表)發出的:

還要修改一下ForumAction對應的show.jsp中的連接地址:

<div class="ItemBlock_Title1" style="width: 98%;">

    <font class="MenuPoint"> &gt; </font>

     <s:a action="forum_list">論壇</s:a>

    <font class="MenuPoint"> &gt; </font>

            ${forum.name }

    <span style="margin-left:30px;">

<s:a action="topic_addUI?forumId=%{#forum.id }">

     <img align="absmiddle" src="${pageContext.request.contextPath}/style/blue/images/button/publishNewTopic.png"/>

</s:a>

    </span>

</div>

  • Tips: topic_addUI?forumId=%{#forum.id }

    這裏要將forum的id傳遞給TopicAction.雖然本頁面是ForumAction對應的show.jsp頁面,但由於此連接要轉到TopicAction,而此id並非Topic的id,因此要寫成forumId,毫不能寫成Id. forumId.%{#forum.id}這是OGNL表達式,加#是由於在ForumAction,forum被put進了map域中.

Forum forum = forumService.getById(model.getId());

ActionContext.getContext().put("forum", forum);

相應的,在TopicAction中要用屬性驅動的方式封裝這個參數

@Controller

@Scope("prototype")

public class TopicAction extends BaseAction<Topic>{

 

    private Long forumId;

    

    /** 顯示單個主題 */

    public String show() throws Exception {

        return "show";

    }

    

    /** 發新帖頁面*/

    public String addUI() throws Exception {

        //準備數據:forum

        Forum forum = forumService.getById(forumId);

        ActionContext.getContext().put("forum", forum);

        return "addUI";

    }

    

    /** 發新帖 */

    public String add() throws Exception {

        return "toShow";    //轉到當前這個 新主題的頁面

    }

    //-----------------------------------

    public Long getForumId() {

        return forumId;

    }

 

    public void setForumId(Long forumId) {

        this.forumId = forumId;

    }

}

TopicAction對應的add UI.jsp:

……

<!--顯示錶單內容-->

<div id="MainArea">

<s:form action="topic_add" cssStyle="margin: 0; padding: 0;">

    <s:hidden name="forumId"></s:hidden>

    <div id="PageHead"></div>

    <center>

        <div class="ItemBlock_Title1">

            <div width=85% style="float:left">

                <font class="MenuPoint"> &gt; </font>

                <s:a action="forum_list">論壇</s:a>

                <font class="MenuPoint"> &gt; </font>

                <s:a action="forum_show?id=%{#forum.id}">${forum.name}</s:a>

                <font class="MenuPoint"> &gt;&gt; </font>

                發表新主題

            </div>

        </div>

        <div class="ItemBlockBorder">

            <table border="0" cellspacing="1" cellpadding="1" width="100%" id="InputArea">

                <tr>

                    <td class="InputAreaBg" height="30"><div class="InputTitle">標題</div></td>

                    <td class="InputAreaBg"><div class="InputContent">

                        <s:textfield name="title" cssClass="InputStyle" cssStyle="width:100%"/></div>

                    </td>

                </tr>

                <tr height="240">

                    <td class="InputAreaBg"><div class="InputTitle">內容</div></td>

                    <td class="InputAreaBg"><div class="InputContent"><s:textarea name="content" cssStyle="width:600px;height:200px"></s:textarea></div></td>

                </tr>

                <tr height="30">

                    <td class="InputAreaBg" colspan="2" align="center">

                        <input type="image" src="${pageContext.request.contextPath}/style/blue/images/button/submit.PNG" style="margin-right:15px;"/>

                        <a href="javascript:history.go(-1);"><img src="${pageContext.request.contextPath}/style/blue/images/button/goBack.png"/></a>

                    </td>

                </tr>

            </table>

        </div>

    </center>

</s:form>

……

  • Tips: <s:a action="forum_show?id=%{#forum.id}">${forum.name}</s:a>

同理,這裏要將forum的id傳遞給ForumAction對應的show(),雖然本頁面是TopicAction對應的addUI頁面,但由於此連接要轉到ForumAction,而此id這好是forum的id,因此寫成id便可,不用再寫成forumId了. %{#forum.id}這是OGNL表達式,加#是由於在TopicAction中forum被put進了map域中.

Forum forum = forumService.getById(forumId);

ActionContext.getContext().put("forum", forum);

主題添加:

在發表新主題的同時,版塊的一些屬性也會受到影響,因此還要維護版塊的某些屬性.

特殊屬性的說明

Forum

topicCount

主題數量

articleCount

文章數量(主題+回覆)

lastTopic

最後發表的主題

Topic

replyCount

回覆數量

lastReply

最後發表的回覆

lastUpdateTime

最後更新時間(主題發表的時間或最後回覆的時間)

 

特殊屬性的維護

   

發表新主題

發表新回覆

Forum

topicCount

1

 

articleCount

1

1

lastTopic

更新爲當前的新主題

 

Topic

replyCount

0

1

lastReply

null

更新爲當前的新回覆

lastUpdateTime

本主題的發表時間

更新爲當前新回覆的發表時間

TopicAction:

@Controller

@Scope("prototype")

public class TopicAction extends BaseAction<Topic>{

 

    private Long forumId;

    

    /** 顯示單個主題 */

    public String show() throws Exception {

        return "show";

    }

    

    /** 發新帖頁面*/

    public String addUI() throws Exception {

        //準備數據:forum

        Forum forum = forumService.getById(forumId);

        ActionContext.getContext().put("forum", forum);

        return "addUI";

    }

    

    /** 發新帖 */

    public String add() throws Exception {

        //封裝對象

        Topic topic = new Topic();

        //須要在action中封裝的數據:

        //>>a.表單中的參數

        topic.setTitle(model.getTitle());

        topic.setContent(model.getContent());

        topic.setForum(forumService.getById(forumId));//addUI.jsp表單中的隱藏域,forumId傳遞過來了

        //>>b.在顯示層才能得到的數據

        topic.setAuthor(getCurrentUser());    //當前登陸的用戶

        topic.setIpAddr(getRequestIp());    //客戶端的IP地址

        

        //調用業務方法

        topicService.save(topic);

 

        return "toShow";    //轉到當前這個新主題的頁面

    }

}

Tips:

action中就封裝這些屬性便可:表單中的參數和在顯示層才能獲取到的數據,其餘數據到業務層再設置.看需求頁面分析從頁面傳遞過來的值:

GetCurrentUser()getRequestIp()比較經常使用,因此封裝到BaseAction中比較好.

//--------------------工具方法----------------

    /**

     * 獲取當前用戶

     */

    public User getCurrentUser() throws Exception {

        return (User) ActionContext.getContext().getSession().get("user");

    }

    

    /**

     * 獲取客戶端的ip地址

     */

    public String getRequestIp() throws Exception {

        return ServletActionContext.getRequest().getRemoteAddr();

    }

TopicServiceImpl:

@Service

@Transactional

@SuppressWarnings("unchecked")

public class TopicServiceImpl extends DaoSupportImpl<Topic> implements TopicService{

 

    /**

     * 查詢指定版塊的主題列表,最新狀態的排到前面,置頂帖排到最前面

     */

    public List<Topic> findByForum(Forum forum) {

        return getSession().createQuery(//

                "from Topic t where t.forum = ? order by (case t.type when 2 then 2 else 0 end) desc, t.lastUpdateTime desc")//

                .setParameter(0, forum)//

                .list();

    }

 

    

    /**

     * 重寫save()

     */

    public void save(Topic topic) {

        //設置屬性並保存

        topic.setType(topic.TYPE_NORMAL);    //普通帖

        topic.setReplyCount(0);

        topic.setLastReply(null);

        topic.setPostTime(new Date());    //當前時間

        topic.setLastUpdateTime(topic.getPostTime());    //默認爲主題的發表時間

        

        getSession().save(topic);

            

        //更新相關信息

        Forum forum = topic.getForum();    

        forum.setTopicCount(forum.getTopicCount()+1);    //主題數量

        forum.setArticleCount(forum.getArticleCount()+1);    //回覆數量(主題+回覆)

        forum.setLastTopic(topic);    //最後發表主題

        

        getSession().update(forum);

    }

}

由於topicaction中的show()和對用的頁面還沒寫,因此發完新帖後提交,顯示的是空白頁面,此時在空白頁面中右鍵屬性:

Id爲空值,因此要在TopicAction中傳id過去:

    ……

/** 發新帖 */

    public String add() throws Exception {

        //封裝對象

        Topic topic = new Topic();

        //須要在action中封裝的數據:

        //>>a.表單中的參數

        topic.setTitle(model.getTitle());

        topic.setContent(model.getContent());

        topic.setForum(forumService.getById(forumId));

        //>>b.在顯示層才能得到的數據

        topic.setAuthor(getCurrentUser());    //當前登陸的用戶

        topic.setIpAddr(getRequestIp());    //客戶端的IP地址

        

        //調用業務方法

        topicService.save(topic);

        

        ActionContext.getContext().put("topicId", topic.getId());

        return "toShow";    //轉到當前這個新主題的頁面

    }

Struts.xml:

<!-- 論壇:主題相關 -->

    <action name="topic_*" class="topicAction" method="{1}">

        <result name="show">/WEB-INF/jsp/topicAction/show.jsp</result>

        <result name="addUI">/WEB-INF/jsp/topicAction/addUI.jsp</result>

        <result name="toShow" type="redirectAction">topic_show?id=${#topicId}</result>

    </action>

這樣再提交時,便有了id:

顯示置頂帖,精華帖,普通貼圖標的小技巧:

將相應圖片名稱改爲相應type值:

在ForumAction對應的show.jsp頁面中引入圖片時便可這麼寫:

<img src="${pageContext.request.contextPath}/style/images/topicType_${type}.gif" />

效果圖:

主題展現(TopicAction中的show()):

TopicAction:

……

public class TopicAction extends BaseAction<Topic>{

    ……

    /** 顯示單個主題 */

    public String show() throws Exception {

        //準備數據:topic

        Topic topic = topicService.getById(model.getId());

        ActionContext.getContext().put("topic", topic);

        

        //準備數據:replyList

        List<Reply> replyList =replyService.findByTopic(topic);

        ActionContext.getContext().put("replyList", replyList);

        

        return "show";

    }

……

}

ReplyServiceImpl:

public class ReplyServiceImpl extends DaoSupportImpl<Reply> implements ReplyService{

……

    /**

     * 查詢指定主題的回覆,最新回覆排到最後

     */

    public List<Reply> findByTopic(Topic topic) {

        return getSession().createQuery(//

                "from Reply r where r.topic = ? order by r.postTime")//

                .setParameter(0, topic)//

                .list();

    }

    ……

}

對應靜態頁面:

TopicAction對應的show.jsp:

……

<!--內容顯示-->    

<div id="MainArea">

    <div id="PageHead"></div>

    <center>

        <div class="ItemBlock_Title1" style="width: 98%">

            <font class="MenuPoint"> &gt; </font>

            <s:a action="forum_list">論壇</s:a>

            <font class="MenuPoint"> &gt; </font>

            <s:a action="forum_show?id=%{#topic.forum.id}">${topic.forum.name }</s:a>

            <font class="MenuPoint"> &gt;&gt; </font>

            帖子閱讀

            <span style="margin-left:30px;"><s:a action="topic_addUI?forumId=%{#topic.forum.id}">

                <img align="absmiddle" src="${pageContext.request.contextPath}/style/blue/images/button/publishNewTopic.png"/></s:a>

            </span>

        </div>

        

        <div class="ForumPageTableBorder dataContainer" datakey="replyList">

        

            <!--顯示主題標題等-->

            <table width="100%" border="0" cellspacing="0" cellpadding="0">

                <tr valign="bottom">

                <td width="3" class="ForumPageTableTitleLeft">&nbsp;</td>

                    <td class="ForumPageTableTitle"><b>本帖主題:${topic.title }</b></td>

                    <td class="ForumPageTableTitle" align="right" style="padding-right:12px;">

                        <s:a class="detail" action="reply_addUI?topicId=%{#topic.id}"><img border="0" src="${pageContext.request.contextPath}/style/images/reply.gif" />回覆</s:a>

                        <a href="moveUI.html"><img border="0" src="${pageContext.request.contextPath}/style/images/edit.gif" />移動到其餘版塊</a>

                        <a href="#" onClick="return confirm('要把本主題設爲精華嗎?')"><img border="0" src="${pageContext.request.contextPath}/style/images/forum_hot.gif" />精華</a>

                        <a href="#" onClick="return confirm('要把本主題設爲置頂嗎?')"><img border="0" src="${pageContext.request.contextPath}/style/images/forum_top.gif" />置頂</a>

                        <a href="#" onClick="return confirm('要把本主題設爲普通嗎?')"><img border="0" src="${pageContext.request.contextPath}/style/images/forum_comm.gif" />普通</a>

                    </td>

                    <td width="3" class="ForumPageTableTitleRight">&nbsp;</td>

                </tr>

                <tr height="1" class="ForumPageTableTitleLine"><td colspan="4"></td></tr>

            </table>

 

            <!-- ~~~~~~~~~~~~~~~ 顯示主帖 ~~~~~~~~~~~~~~~ -->

            <div class="ListArea">

                <table border="0" cellpadding="0" cellspacing="1" width="100%">

                    <tr>

                        <td rowspan="3" width="130" class="PhotoArea" align="center" valign="top">

                            <!--做者頭像-->

                            <div class="AuthorPhoto">

                                <img border="0" width="110" height="110" src="${pageContext.request.contextPath}/style/images/defaultAvatar.gif"

                                    onerror="this.onerror=null; this.src='${pageContext.request.contextPath}/style/images/defaultAvatar.gif';" />

                            </div>

                            <!--做者名稱-->

                            <div class="AuthorName">${topic.author.name }</div>

                        </td>

                        <td align="center">

                            <ul class="TopicFunc">

                                <!--操做列表-->

                                <li class="TopicFuncLi">

                                    <a class="detail" href="${pageContext.request.contextPath}/BBS_Topic/saveUI.html"><img border="0" src="${pageContext.request.contextPath}/style/images/edit.gif" />編輯</a>

                                    <a class="detail" href="#" onClick="return confirm('肯定要刪除本帖嗎?')"><img border="0" src="${pageContext.request.contextPath}/style/images/delete.gif" />刪除</a>

                                </li>

                                <!-- 文章標題 -->

                                <li class="TopicSubject">

                                    <s:property value="#topic.title" escape="true"/>

                                </li>

                            </ul>

                        </td>

                    </tr>

                    <tr><!-- 文章內容 -->

                        <td valign="top" align="center">

                            <div class="Content">${topic.content }</div>

                        </td>

                    </tr>

                    <tr><!--顯示樓層等信息-->

                        <td class="Footer" height="28" align="center" valign="bottom">

                            <ul style="margin: 0px; width: 98%;">

                                <li style="float: left; line-height:18px;"><font color=#C30000>[樓主]</font>

                                    <s:date name="#topic.postTime" format="yyyy-MM-dd HH:mm:ss"/>

                                </li>

                                <li style="float: right;"><a href="javascript:scroll(0,0)">

                                    <img border="0" src="${pageContext.request.contextPath}/style/images/top.gif" /></a>

                                </li>

                            </ul>

                        </td>

                    </tr>

                </table>

            </div>

            <!-- ~~~~~~~~~~~~~~~ 顯示主帖結束 ~~~~~~~~~~~~~~~ -->

 

 

            <!-- ~~~~~~~~~~~~~~~ 顯示回覆列表 ~~~~~~~~~~~~~~~ -->

            <s:iterator value="replyList" status="status">

            <div class="ListArea template">

                <table border="0" cellpadding="0" cellspacing="1" width="100%">

                    <tr>

                        <td rowspan="3" width="130" class="PhotoArea" align="center" valign="top">

                            <!--做者頭像-->

                            <div class="AuthorPhoto">

                                <img border="0" width="110" height="110" src="${pageContext.request.contextPath}/style/images/defaultAvatar.gif"

                                    onerror="this.onerror=null; this.src='${pageContext.request.contextPath}/style/images/defaultAvatar.gif';" />

                            </div>

                            <!--做者名稱-->

                            <div class="AuthorName">${author.name }</div>

                        </td>

                        <td align="center">

                            <ul class="TopicFunc">

                                <!--操做列表-->

                                <li class="TopicFuncLi">

                                    <a class="detail" href="${pageContext.request.contextPath}/BBS_Topic/saveUI.html"><img border="0" src="${pageContext.request.contextPath}/style/images/edit.gif" />編輯</a>

                                    <a class="detail" href="#" onClick="return confirm('肯定要刪除本帖嗎?')"><img border="0" src="${pageContext.request.contextPath}/style/images/delete.gif" />刪除</a>

                                </li>

                                <%-- <!-- 文章表情與標題 -->

                                <li class="TopicSubject">

                                    <img width="19" height="19" src="${pageContext.request.contextPath}/style/images/face/${reply.faceIcon}"/>

                                    ${reply.title}

                                </li> --%>

                            </ul>

                        </td>

                    </tr>

                    <tr><!-- 文章內容 -->

                        <td valign="top" align="center">

                            <div class="Content">${content}</div>

                        </td>

                    </tr>

                    <tr><!--顯示樓層等信息-->

                        <td class="Footer" height="28" align="center" valign="bottom">

                            <ul style="margin: 0px; width: 98%;">

                                <li style="float: left; line-height:18px;"><font color=#C30000>[${status.count}]</font>

                                    <s:date name="postTime" format="yyyy-MM-dd HH:mm:ss"/>

                                </li>

                                <li style="float: right;"><a href="javascript:scroll(0,0)">

                                    <img border="0" src="${pageContext.request.contextPath}/style/images/top.gif" /></a>

                                </li>

                            </ul>

                        </td>

                    </tr>

                </table>

            </div>

            </s:iterator>

            <!-- ~~~~~~~~~~~~~~~ 顯示回覆列表結束 ~~~~~~~~~~~~~~~ -->

        </div>

 

        <div class="ForumPageTableBorder" style="margin-top: 25px;">

            <table width="100%" border="0" cellspacing="0" cellpadding="0">

                <tr valign="bottom">

                    <td width="3" class="ForumPageTableTitleLeft">&nbsp;</td>

                    <td class="ForumPageTableTitle"><b>快速回復</b></td>

                    <td width="3" class="ForumPageTableTitleRight">&nbsp;</td>

                </tr>

                <tr height="1" class="ForumPageTableTitleLine">

                    <td colspan="3"></td>

                </tr>

            </table>

        </div>

    </center>

            

    <!--快速回復-->

    <div class="QuictReply">

    <form action="">

        <div style="padding-left: 3px;">

            <table border="0" cellspacing="1" width="98%" cellpadding="5" class="TableStyle">

                <!-- <tr height="30" class="Tint">

                    <td width="50px" class="Deep"><b>標題</b></td>

                    <td class="no_color_bg">

                        <input type="text" name="title" class="InputStyle" value="回覆:昨天發如今表單裏刪除的圖片" style="width:90%"/>

                    </td>

                </tr> -->

                <tr class="Tint" height="200">

                    <td valign="top" rowspan="2" class="Deep"><b>內容</b></td>

                    <td valign="top" class="no_color_bg">

                        <textarea name="content" style="width: 95%; height: 300px"></textarea>

                    </td>

                </tr>

                <tr height="30" class="Tint">

                    <td class="no_color_bg" colspan="2" align="center">

                        <input type="image" src="${pageContext.request.contextPath}/style/blue/images/button/submit.PNG" style="margin-right:15px;"/>

                    </td>

                </tr>

            </table>

        </div>

    </form>

    </div>

</div>

……

Tips: <s:property value="#topic.title" escape="true"/>

escape="true"這是轉義的意思.

主題顯示頁面的頂部,有快速回復的按鈕:

相應連接action="reply_addUI?topicId=%{#topic.id}

既然是回覆,就要指定要回復的主題.因此要傳遞topicId.在ReplyAction中以屬性驅動的方式封裝該參數:

private Long topicId;

public Long getTopicId() {

    return topicId;

}

    

public void setTopicId(Long topicId) {

    this.topicId = topicId;

}

  1. 回覆

回覆和發帖差很少.

ReplyAction:

@Controller

@Scope("prototype")

public class ReplyAction extends BaseAction<Reply>{

 

    private Long topicId;

 

    /** 發表回覆頁面 */

    public String addUI() throws Exception {

        //準備數據

        Topic topic = topicService.getById(topicId);

        ActionContext.getContext().put("topic", topic);

        return "addUI";

    }

    

    /** 發表回覆 */

    public String add() throws Exception {

        Reply reply = new Reply();

        //封裝對象

        //a.表單中的參數

        reply.setContent(model.getContent());

        reply.setTopic(topicService.getById(topicId));

        

        //b.在顯示層才能獲取的信息

        reply.setAuthor(getCurrentUser());    //當前登陸的用戶

        reply.setIpAddr(getRequestIp());    //客戶的ip地址

        

        //調用業務方法

        replyService.save(reply);

        

        return "toTopicShow";    //轉到當前回覆所屬的主題顯示頁面

    }

    

    //---------------------

    public Long getTopicId() {

        return topicId;

    }

    

    public void setTopicId(Long topicId) {

        this.topicId = topicId;

    }

}

ReplyServiceImpl:

@Service

@Transactional

public class ReplyServiceImpl extends DaoSupportImpl<Reply> implements ReplyService{

 

    /**

     * 重寫save(),處理特殊屬性

     */

    public void save(Reply reply) {

        reply.setPostTime(new Date());    //發表時間爲當前時間

        reply.setDeleted(false);    //默認爲未刪除

        

        getSession().save(reply);

        //處理Forum和Topic中的特殊屬性

        Topic topic = reply.getTopic();

        Forum forum = topic.getForum();

        

        forum.setArticleCount(forum.getArticleCount()+1);    //版塊的文章數量(主題+回覆)

        

        topic.setReplyCount(topic.getReplyCount()+1);    //主題回覆數量

        topic.setLastReply(reply);    //主題的最後回覆

        topic.setLastUpdateTime(reply.getPostTime());    //主題的最後更新時間 默認爲最後回覆時間

        

        getSession().update(forum);

        getSession().update(topic);

    }

}

頁面需求: (其中表情和標題是不須要的)

ReplyAction對應的addUI.jsp:

……

<!--顯示錶單內容-->

<div id="MainArea">

<s:form action="reply_add" sccStyle="margin: 0; padding: 0;">

    <s:hidden name="topicId"></s:hidden>

    <div id="PageHead"></div>

    <center>

        <div class="ItemBlock_Title1">

            <div width=85% style="float:left">

                <font class="MenuPoint"> &gt; </font>

                <s:a action="forum_list">論壇</s:a>

                <font class="MenuPoint"> &gt; </font>

                <s:a action="forum_show?id=%{#topic.forum.id}">${topic.forum.name }</s:a>

                <font class="MenuPoint"> &gt;&gt; </font>

                帖子回覆

            </div>

        </div>

        <div class="ItemBlockBorder">

            <table border="0" cellspacing="1" cellpadding="1" width="100%" id="InputArea">

                <tr>

                    <td class="InputAreaBg" height="30"><div class="InputTitle">帖子主題</div></td>

                    <td class="InputAreaBg"><div class="InputContent">${topic.title }</div></td>

                </tr>

                <tr height="240">

                    <td class="InputAreaBg"><div class="InputTitle">內容</div></td>

                    <td class="InputAreaBg"><div class="InputContent"><s:textarea name="content" cssStyle="width:650px;height:200px;"></s:textarea></div></td>

                </tr>

                <tr height="30">

                    <td class="InputAreaBg" colspan="2" align="center">

                        <input type="image" src="${pageContext.request.contextPath}/style/blue/images/button/submit.PNG" style="margin-right:15px;"/>

                        <a href="javascript:history.go(-1);"><img src="${pageContext.request.contextPath}/style/blue/images/button/goBack.png"/></a>

                    </td>

                </tr>

            </table>

        </div>

    </center>

</s:form>

</div>

……

在主題展現列表頁面的底部,有快速回復的功能,因此得修改TopicAction對應的show.jsp:

<!--快速回復-->

    <div class="QuictReply">

    <s:form action="reply_add?topicId=%{#topic.id}">

        <div style="padding-left: 3px;">

            <table border="0" cellspacing="1" width="98%" cellpadding="5" class="TableStyle">

                <tr class="Tint" height="200">

                    <td valign="top" rowspan="2" class="Deep"><b>內容</b></td>

                    <td valign="top" class="no_color_bg">

                        <s:textarea name="content" cssStyle="width: 95%; height: 300px"></s:textarea>

                    </td>

                </tr>

                <tr height="30" class="Tint">

                    <td class="no_color_bg" colspan="2" align="center">

                        <input type="image" src="${pageContext.request.contextPath}/style/blue/images/button/submit.PNG" style="margin-right:15px;"/>

                    </td>

                </tr>

            </table>

        </div>

    </s:form>

    </div>

Struts.xml:

<!-- 論壇:主題相關 -->

    <action name="topic_*" class="topicAction" method="{1}">

        <result name="show">/WEB-INF/jsp/topicAction/show.jsp</result>

        <result name="addUI">/WEB-INF/jsp/topicAction/addUI.jsp</result>

        <result name="toShow" type="redirectAction">topic_show?id=${#topicId}</result>

    </action>

      

    <!-- 論壇:回覆相關 -->

    <action name="reply_*" class="replyAction" method="{1}">

        <result name="addUI">/WEB-INF/jsp/replyAction/addUI.jsp</result>

        <result name="toTopicShow" type="redirectAction">topic_show?id=${topicId}</result>

    </action>

Tips: topic_show?id=${#topicId}

這兩個模塊,發帖和發表回覆的請求發出時,頁面跳轉的過程是同樣的:addUI.jspàaction中的add()àshow.jsp

最後跳轉到show.jsp時,都須要topic的id值.

當發表新主題時,從addUI.jsp開始,就一直沒有將topic的id值傳遞過來(傳遞的是forumId),因此纔在TopicAction中將topicId給put進map域中,因此取出時要加#;

而發表回覆時,從addUI.jsp開始,就傳遞了topicId,因此直接取出來就好,不須要加#.

小技巧:eclipse有自動編譯的功能,但有時候會失靈.所以某些時候,看着代碼沒錯,但頁面顯示就是不對.這時能夠在代碼中空白位置加個空格再保存,目的是讓eclipse再次自動編譯,而後刷新頁面就能夠看到效果了.

四.在BBS中使用FCKeditor

在線編輯器:

    老版:FCKeditor(Html + Css + JavaScript + Servlet處理上傳的文件)

    新版:CKeditor

就是用JS實現的一個網頁版的html代碼生成器,最終的結果是一段html代碼。

原理是動態生成html代碼。

使用步驟:

1.導入fckeditor.js文件à2.顯示文本域à3.顯示爲FCKeditor

測試_20130706.html:

<html>

    <head>

        <meta http-equiv="content-type" content="text/html; charset=utf-8">

        

        <!-- 1,導入js文件 -->

        <script type="text/javascript" src="fckeditor.js"></script>

 

        

    </head>

    <body>

 

        <!-- 2,顯示文本域 -->

        <form action="">

            <textarea name="content"> </textarea>

        

            <!-- 3,顯示爲FCKeditor -->

            <script type="text/javascript">

                var oFCKeditor = new FCKeditor( 'content' ) ; // 參數就是提交表單時的參數名(name的值)

                

                // 必需要指定的屬性。

                //用於指定fckeditor的核心文件的存放路徑(editor文件夾所在的路徑)。

                // 要求必定要以'/'結尾。

                oFCKeditor.BasePath    = "./";

 

                // 一些配置

                oFCKeditor.Height    = 300 ;

                oFCKeditor.Width    = 700 ;

                //oFCKeditor.Value    = 'itcast' ;

                oFCKeditor.ToolbarSet = "bbs"; // 提定工具欄的功能項配置,默認是Default

                

                // oFCKeditor.Create() ; // 建立FCKeditor並在當前位置顯示出來。

                oFCKeditor.ReplaceTextarea(); // 替換指定的textarea爲FCKeditor

            </script>

 

            <br><input type="submit" value="提交">

        </form>

        <hr>

        <a href="#">return</a>

    </body>

</html>

效果以下:

Tips:FCKeditor有本身默認的配置文件,要修改一些屬性(好比功能選項,表情等)的話,一般都要採用這樣的方式:本身建一個配置文件,如myconfig.js,在默認配置文件fckconfig.js中聲明還要加載myconfig.js,而後再把想要修改的配置寫到

myconfig.js中(不想改的不寫),就行了.

原理:默認先加載默認配置文件,聲明後還會加載本身寫的配置文件,這時前面加載的配置會被後面加載的相同的配置所覆蓋.

在默認配置文件中聲明還要加載本身寫的配置文件:

myonfig.js:

 

// 1. 自定義 ToolbarSet

FCKConfig.ToolbarSets["simple"] = [

    ['Bold','Italic','Underline'],

    ['Link','Unlink'],

    ['Image','Smiley','SpecialChar'],

    ['FontName'],

    ['FontSize'],

    ['TextColor','BGColor'],

] ;

 

FCKConfig.ToolbarSets["bbs"] = [

    ['NewPage','RemoveFormat'],

    ['Bold','Italic','Underline'],

    ['Subscript','Superscript'],

    ['JustifyLeft','JustifyCenter','JustifyRight'],

    ['Link','Unlink'],

    ['Image','Smiley','SpecialChar'],

    ['Table'],

    ['OrderedList','UnorderedList','-','Outdent','Indent'],

    ['FontName'],

    ['FontSize'],

    ['TextColor','BGColor'],

    ['FitWindow']

] ;

 

FCKConfig.ToolbarSets["admin"] = [

    ['Source','DocProps','-','Save','NewPage','Preview','-','Templates'],

    ['Cut','Copy','Paste','PasteText','PasteWord','-','Print','SpellCheck'],

    ['Undo','Redo','-','Find','Replace','-','SelectAll','RemoveFormat'],

    ['Bold','Italic','Underline','StrikeThrough','-','Subscript','Superscript'],

    ['OrderedList','UnorderedList','-','Outdent','Indent','Blockquote','CreateDiv'],

    ['JustifyLeft','JustifyCenter','JustifyRight','JustifyFull'],

    ['Form','Checkbox','Radio','TextField','Textarea','Select','Button','ImageButton','HiddenField'],

    ['Link','Unlink','Anchor'],

    ['Image','Flash','Table','Rule','Smiley','SpecialChar','PageBreak'],

    ['Style','FontFormat','FontName','FontSize'],

    ['TextColor','BGColor'],

    ['FitWindow','ShowBlocks','-','About']        // No comma for the last row.

] ;

 

// 是否開啓簡單功能與高級功能顯示

if(typeof(FCKConfig.EnableAdvanceTable) == "undefined"){ // 在頁面中調用fckeditor時指定的 EnableAdvanceTable 的值會先被調用。

    FCKConfig.EnableAdvanceTable = false; // 默認爲false

}

FCKConfig.AdvanceTableNum = 0;

FCKConfig.AdvanceTable = [1,3,7,8,9,12];

 

// 2. 添加中文字體與大小

FCKConfig.FontNames     ='宋體;楷體_GB2312;黑體;隸書;Times New Roman;Arial' ;

FCKConfig.FontSizes ='9/最小;12/較小;16/中等;20/較大;36/最大;54/更大;';

 

// 3. 修改 "回車" 和 "shift + 回車" 的樣式

FCKConfig.EnterMode = 'br' ;            // p | div | br

FCKConfig.ShiftEnterMode = 'p' ;    // p | div | br

 

// 4. 更換表情圖片

FCKConfig.SmileyPath    = FCKConfig.BasePath + 'images/smiley/wangwang/' ; // 表情圖片所在的文件夾

// 列出表情圖片的文件名

FCKConfig.SmileyImages    = ['0.gif','1.gif','2.gif','3.gif','4.gif','5.gif','6.gif','7.gif','8.gif','9.gif','10.gif','11.gif','12.gif','13.gif','14.gif','15.gif','16.gif','17.gif','18.gif','19.gif','20.gif','21.gif','22.gif','23.gif','24.gif','25.gif','26.gif','27.gif','28.gif','29.gif','30.gif','31.gif','32.gif','33.gif','34.gif','35.gif','36.gif','37.gif','38.gif','39.gif','40.gif','41.gif','42.gif','43.gif','44.gif','45.gif','46.gif','47.gif','48.gif','49.gif','50.gif','51.gif','52.gif','53.gif','54.gif','55.gif','56.gif','57.gif','58.gif','59.gif','60.gif','61.gif','62.gif','63.gif','64.gif','65.gif','66.gif','67.gif','68.gif','69.gif','70.gif','71.gif','72.gif','73.gif','74.gif','75.gif','76.gif','77.gif','78.gif','79.gif','80.gif','81.gif','82.gif','83.gif','84.gif','85.gif','86.gif','87.gif','88.gif','89.gif','90.gif','91.gif','92.gif','93.gif','94.gif','95.gif','96.gif','97.gif','98.gif','test.gif'] ;

FCKConfig.SmileyColumns = 8 ;

FCKConfig.SmileyWindowWidth        = 668 ;

FCKConfig.SmileyWindowHeight    = 480 ;

 

// 5. 設置容許上傳的圖片類型的擴展名列表

FCKConfig.ImageUploadAllowedExtensions    = ".(jpg|gif|jpeg|png|bmp)$" ;        // empty for all

 

// 其它須要修改的配置 ...

FCKConfig.LinkDlgHideTarget        = true; // false ;

FCKConfig.LinkDlgHideAdvanced    = true; // false ;

 

FCKConfig.ImageDlgHideLink        = true; // false ;

FCKConfig.ImageDlgHideAdvanced    = true; // false

 

FCKConfig.LinkUpload = false;

這是老師寫好的myconfig.js,能夠用現成的,還想要修改字體,圖片等的話能夠在裏面自行修改.

  • 實際操做: (也就兩步,都是複製粘貼的工做)

將整個fckedit文件拷貝到WebContent根目錄下:

而後打開topicAction對應的addUI.jsp(發帖頁面) ,show.jsp(主題展現頁面的底部有快速回復功能) 和replyAction對應的addUI.jsp(發表回覆頁面),在這三個頁面的頂部加入下面這些代碼:

<%-- 使用FCKeditor --%>

<script type="text/javascript"

    src="${pageContext.request.contextPath}/fckeditor/fckeditor.js"></script>

<script type="text/javascript">

    $(function() {

        var oFCKeditor = new FCKeditor('content'); // 參數就是提交表單時的參數名

// 必需要指定的屬性。用於指定fckeditor的核心文件的存放路徑(editor文件夾所在的路徑)。要求必定要以'/'結尾。

        oFCKeditor.BasePath = "${pageContext.request.contextPath}/fckeditor/";

        oFCKeditor.Width = "90%";//指定寬度

        oFCKeditor.ToolbarSet = "bbs"; // 提定工具欄的功能項配置,默認是Default

        oFCKeditor.ReplaceTextarea(); // 替換指定的textareaFCKeditor

    });

</script>

Tips:這三個頁面的文本域的name值都爲content;

這段代碼原本是必定要出如今文本域以後的,否則會提示找不到name值爲content的文本域.之因此能這麼作,是由於加了$(function(){});代表等頁面加載完成以後再執行這些代碼.

在eclipse自帶的瀏覽器中顯示不出來--.

效果以下:

五.導入演示數據(爲實現和展現分頁效果爲準備)

他沒給演示數據….本身手動添加,,,,,-------…

相關文章
相關標籤/搜索