评论:

评论是一个非常典型的示例,使用到了知启蒙登录组件。

评论功能描述

1、详情评论:用户注册登录之后,可以对文章详情等进行评论。

2、评论回复:用户注册登录之后,可以对其他用户的留言进行回复。

3、评论回复删除:用户注册登录之后,可以对自己账户进行的回复和评论进行删除。

4、评论回复点赞:用户注册登录之后,可以对所有的评论留言进行点赞或者取消点赞。

评论组件源码工程结构

源码资源目录

  • src/dbo用于存放数据对象源码,由知启蒙普通评论组件数据库字典.dbo设计并生成。
  • src/mian用于存放编写评论组件的功能源码,如action等。

引入外部库资源目录

  • JRE System Library约定的[JavaSE-1.7]环境。
  • Referenced Libraries引用库目录[lib]下所有包。
  • 库目录[lib]存放引用库文件。并通过[Build Path]加载到Referenced Libraries。

工程配置相关目录

  • 配置目录[conf]存放工程配置文件,[zhiqim.xml]是必须的。在zhiqim.xml的[config]选项中可以增加多个配置文件,如本示例httpd.xml和logging.xml。
  • 文档目录[document]存放工程文档,如数据库字典、工程导出配置文件[export/project.exp.xml]。
  • 日志目录[logs]存放调试、运行时生成的日志。
  • 资源目录[resource]存放WEB容器ZML上下文环境的配置文件、ZML页面文件等。包括上下文环境配置[/conf/config.xml][/conf/config.zml]等。
  • 发布目录[release]存放导出的执行程序和源码。
  • zhiqim_comment_common
  • src/dbo
  • org.zhiqim.comment.commen.dbo
  • CmtcComment.java
  • org.zhiqim.comment.commen.ex
  • CmtcCommentEx.java
  • src/main
  • org.zhiqim.comment.common
  • CommentCommonAction.java
  • CommentCommonPresenter.java
  • JRE System Library [JavaSE-1.7]
  • Referenced Libraries
  • zhiqim.jar
  • zhiqim_orm.jar
  • zhiqim_zml.jar
  • zhiqim_httpd.jar
  • zhiqim_ui.jar
  • zhiqim_mysql5.0.8.jar
  • zhiqim_account.jar
  • zhiqim_mail.jar
  • zhiqim_sms.jar
  • conf
  • zhiqim.xml
  • httpd.xml
  • logging.xml
  • document
  • 知启蒙普通评论组件数据库字典.dbo
  • lib
  • libex
  • logs
  • resource
  • conf
  • config.zml
  • config.xml
  • zinc
  • zview
  • comment_common
  • answer.zml
  • comment.zml
  • release
  • src
评论组件配置说明
一、/conf/zhiqim.xml配置:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE ZHIQIM-CONFIG PUBLIC "-//ZHIQIM //DTD Zhiqim-Config Configuration 1.5.0//EN" "http://zhiqim.org/xmldtds/zhiqim_config_1_5_0.dtd"> <zhiqim-config> <group id="boot" desc="系统启动配置"> <item key="name" value="知启蒙评论" type="protected" desc="系统名称" /> <item key="version" value="V1.5.0" type="protected" desc="系统版本" /> <item key="port" value="60066" type="protected" desc="系统监听端口,用于启动监听和命令关闭工程" /> <item key="process" value="zhiqim_comment_common" type="protected" desc="使用的进程名,MAC系统下该配置无效" /> <item key="args" value="-server -Xms64m -Xmx512m" type="protected" desc="JVM参数" /> <item key="libex" value="./libex" type="protected" desc="除./lib目录外额外需要加载的库目录,多个逗号隔开" /> <item key="include" value="*/lib/*,*/bin" type="protected" desc="扫描包含库模式,多个用逗号隔开,星号表示通配符" /> </group> <group id="config" desc="系统其他配置文件,./开头表示工程相对路径下,绝对路径使用/或d:/等(Windows也使用顺斜杠作路径)"> <item key="logging" value="./conf/logging.xml" type="protected" desc="日志配置文件" /> <item key="httpd" value="./conf/httpd.xml" type="protected" desc="WEB配置" /> </group> <group id="service" desc="系统服务配置,有依赖时注意顺序,系统按顺序加载,按倒序销毁"> <item key="logging" value="org.zhiqim.kernel.logging.LogServer" type="protected" desc="日志服务" /> <item key="cutter" value="org.zhiqim.kernel.logging.LogLinuxNohupCutter" type="protected" desc="日志Linux切割服务" /> <item key="orm" value="org.zhiqim.orm.ORMServer" type="protected" desc="主数据库服务" /> <item key="resource" value="org.zhiqim.httpd.HttpServer" type="protected" desc="web服务" /> <item key="mail" value="org.zhiqim.mail.MailSender" type="protected" desc="邮件发送服务"/> <item key="sms" value="org.zhiqim.sms.SMSSender" type="protected" desc="短信发送服务"/> </group> <group id="orm" desc="MYSQL数据库连接方式"> <item key="dbType" value="mysql" type="protected" desc="数据库类型,支持mysql|oracle|mssql|postgresql|sqlite|hsql" /> <item key="driver" value="org.zhiqim.mysql5_0_8.jdbc.Driver" type="protected" desc="数据库驱动" /> <item key="url" value="jdbc:mysql://127.0.0.1:3306/zhiqim_comment_common?useUnicode=true&characterEncoding=UTF-8" type="protected" desc="数据库Url" /> <item key="user" value="root" type="protected" desc="数据库用户名" /> <item key="pass" value="root" type="protected" desc="数据库密码" /> <item key="minPoolSize" value="2" type="protected" desc="线程池最小值" /> <item key="maxPoolSize" value="10" type="protected" desc="线程池最大值" /> <item key="maxKeepTime" value="7001" type="protected" desc="每连接最大保持时长,大于该值将重建连接,单位秒" /> </group> <group id="mail" desc="邮件服务器配置"> <item key="smtp.host" value="smtp.exmail.qq.com" type="protected" desc="SMTP服务器地址" /> <item key="smtp.port" value="25" type="protected" desc="SMTP服务器端口" /> <item key="smtp.auth" value="true" type="protected" desc="SMTP服务器是否需要身份验证" /> <item key="smtp.auth.name" value="account@zhiqim.com" type="protected" desc="SMTP服务器验证用户名" /> <item key="smtp.auth.pass" value="Redxyz2013" type="protected" desc="SMTP服务器验证密码" /> <item key="from.address" value="account@zhiqim.com" type="protected" desc="SMPT邮件发送地址" /> <item key="from.name" value="知启蒙账号中心" type="protected" desc="SMPT邮件发送者名称" /> </group> <group id="sms" desc="短信发送配置"> <item key="apiUrl" value="http://sms.redxyz.com/smsSend.htm" type="protected" desc="短信发送链接" /> <item key="appId" value="1702200939340082" type="protected" desc="商家编码" /> <item key="appSecret" value="N22L15535LNNCY9D" type="protected" desc="商家密钥" /> <item key="templateCode" value="SMS_47935217" type="protected" desc="模板编码" /> <item key="signName" value="知启蒙" type="protected" desc="短信签名" /> </group> </zhiqim-config>
二、/conf/httpd.xml配置:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE ZHIQIM-CONFIG PUBLIC "-//ZHIQIM //DTD Zhiqim-Config Configuration 1.5.0//EN" "http://zhiqim.org/xmldtds/zhiqim_config_1_5_0.dtd"> <zhiqim-config> <group id="resource" desc="WEB容器服务配置"> <item key="context" value="resource.root" type="protected" desc="HTTP服务下包括的上下文环境,多个用逗号隔开" /> <item key="scheme" value="HTTP" type="protected" desc="HTTP或HTTPS协议" /> <item key="port" value="80" type="protected" desc="监听端口" /> <item key="minPoolSize" value="5" type="protected" desc="HTTP处理线程池最小值" /> <item key="maxPoolSize" value="10" type="protected" desc="HTTP处理线程池最大值" /> </group> <group id="resource.root" desc="Web界面"> <item key="domain" value="" type="protected" desc="域名" /> <item key="path" value="/" type="protected" desc="上下文环境路径,必填" /> <item key="resourceType" value="directory" type="protected" desc="资源目录类型classpath|directory,无资源时可不配置" /> <item key="resourcePath" value="./resource" type="protected" desc="资源目录,无资源时可不配置" /> <item key="welcomeUrl" value="/index.htm" type="protected" desc="欢迎页,无资源时可不配置,/开头" /> <item key="upload.rootDir" value="./upload" type="protected" desc="上传组件根目录" /> <item key="uploadone.rootDir" value="./upload" type="protected" desc="上传组件根目录" /> </group> </zhiqim-config>
三、/conf/logging.xml配置:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE ZHIQIM-CONFIG PUBLIC "-//ZHIQIM //DTD Zhiqim-Config Configuration 1.5.0//EN" "http://zhiqim.org/xmldtds/zhiqim_config_1_5_0.dtd"> <zhiqim-config> <group id="logging" desc="信息日志配置"> <item key="logging.info" value="debug-info" type="protected" desc="信息日志配置" /> <item key="logging.error" value="error-fatal" type="protected" desc="错误日志配置" /> <item key="logging.database" value="debug-fatal" type="protected" desc="数据库日志配置" /> </group> <group id="logging.info" desc="信息日志配置"> <item key="console.out" value="true" type="protected" desc="是否输出到控制台" /> <item key="file.out" value="true" type="protected" desc="是否输出到文件" /> <item key="file.path" value="./logs/info.log" type="protected" desc="输出到文件路径" /> </group> <group id="logging.error" desc="错误日志配置"> <item key="console.out" value="true" type="protected" desc="是否输出到控制台" /> <item key="file.out" value="true" type="protected" desc="是否输出到文件" /> <item key="file.path" value="./logs/error.log" type="protected" desc="输出到文件路径" /> </group> <group id="logging.database" desc="数据库日志配置"> <item key="must.name" value="database.log" type="protected" desc="指定日志名称,为空表示不指定" /> <item key="console.out" value="true" type="protected" desc="是否输出到控制台" /> <item key="file.out" value="true" type="protected" desc="是否输出到文件" /> <item key="file.path" value="./logs/database/database.log" type="protected" desc="输出到文件路径" /> </group> </zhiqim-config>
四、/resource/conf/config.xml配置:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE ZHIQIM-CONTEXT PUBLIC "-//ZHIQIM //DTD Zhiqim-Context Configuration 1.5.0//EN" "http://zhiqim.org/xmldtds/zhiqim_context_1_5_0.dtd"> <zhiqim-context> <!-- 组件配置 --> <component name="账号组件" path="/org/zhiqim/account/resource"/> <!-- 访客部分 --> <action name="首页" path="/index.htm" redirect="/commentCommon.htm"/> <action name="评论首页" path="/commentCommon.htm" view="/zview/comment_common/comment.zml" redirect="/commentCommon.htm" class="org.zhiqim.comment.common.CommentCommonAction" /> <action name="回复" interceptor="chkZacLogin" path="/answer.htm" view="/zview/comment_common/answer.zml" class="org.zhiqim.comment.common.CommentCommonAction"/> </zhiqim-context>
评论组件类的编写
一、CommentCommonAction.java
package org.zhiqim.comment.common; import java.util.List; import org.zhiqim.account.ZacSessionUser; import org.zhiqim.comment.common.dbo.CmtcComment; import org.zhiqim.comment.common.ex.CmtcCommentEx; import org.zhiqim.httpd.HttpRequest; import org.zhiqim.httpd.context.extend.GetPostAction; import org.zhiqim.httpd.util.Sessions; import org.zhiqim.httpd.validate.ones.IsLen; import org.zhiqim.httpd.validate.ones.IsNotEmpty; import org.zhiqim.httpd.validate.ones.IsNumericLen; import org.zhiqim.kernel.Global; import org.zhiqim.kernel.util.DateTimes; import org.zhiqim.kernel.util.Ids; import org.zhiqim.orm.ZTable; import org.zhiqim.orm.ZView; import org.zhiqim.orm.dbo.Selector; public class CommentCommonAction extends GetPostAction { @Override protected void validate(HttpRequest request) {// 评论页面验证 request.addValidate(new IsNotEmpty("commentGroup", "评论组编号不能为空")); request.addValidate(new IsLen("commentContent", "评论不能为空且不超过4000字", 1, 4000)); request.addValidate(new IsNumericLen("verificationCode", "验证码必须是4位数字", 4, 4)); } @Override protected void doGet(HttpRequest request) throws Exception {// 页面 int commentNum = Global.get(ZTable.class).count(CmtcComment.class); request.setAttribute("commentNum", commentNum); Selector selector = new Selector(); selector.addOrderbyDesc("commentId"); List commentExs = Global.get(ZView.class).list(CmtcCommentEx.class, selector); request.setAttribute("commentExs", commentExs); long commentId = request.getParameterLong("commentId"); //回复弹窗 if (!(commentId == -1)) { CmtcComment comment = Global.get(ZTable.class).item(CmtcComment.class, commentId); request.setAttribute("comment", comment); } } @Override protected void doPost(HttpRequest request) throws Exception {// 评论页面处理 // 验证码校对 String verificationCode = request.getParameter("verificationCode"); String vcode = Sessions.getSessionVerificationCode(request); if (!verificationCode.equals(vcode)) { request.returnHistory("验证码不正确或已失效,请新输入!"); return; } long commentGroup = request.getParameterLong("commentGroup"); String commentContent = request.getParameterNoFilter("commentContent"); long userId = request.getSessionUser(ZacSessionUser.class).getUserId(); long commentAuthorId = request.getParameterLong("commentAuthorId"); if (commentAuthorId == -1) commentAuthorId = 0; // 插入到COMMENT表 CmtcComment comment = new CmtcComment(); comment.setCommentGroup(commentGroup); comment.setCommentId(Ids.longId()); comment.setCommentContent(commentContent); comment.setCommentUserId(userId); comment.setCommentCreated(DateTimes.getDateTimeString()); comment.setCommentAuthorId(commentAuthorId); comment.setCommentGoodNum(0); comment.setCommentGoodUserId(""); Global.get(ZTable.class).insert(comment); if (commentAuthorId > 0) request.setRedirectParent("/commentCommon.htm"); } }
二、CommentCommonPresenter.java
package org.zhiqim.comment.common; import org.zhiqim.account.ZacSessionUser; import org.zhiqim.comment.common.dbo.CmtcComment; import org.zhiqim.httpd.HttpRequest; import org.zhiqim.httpd.validate.ones.IsNotEmpty; import org.zhiqim.kernel.Global; import org.zhiqim.kernel.annotation.AnAlias; import org.zhiqim.orm.ZTable; import org.zhiqim.orm.dbo.Updater; @AnAlias("CommentCommonPresenter") public class CommentCommonPresenter { /** 点赞 */ public static void doCommentCommonGood(HttpRequest request) throws Exception { ZacSessionUser sessionUser = request.getSessionUser(ZacSessionUser.class); if (sessionUser == null) { request.setResponseError("请先登录"); return; } // 检查参数 request.addValidate(new IsNotEmpty("commentId", "请选择一个评论")); if (!request.chkValidate()) { request.setResponseError(request.getAlertMsg()); return; } long commentId = request.getParameterLong("commentId"); long userId = sessionUser.getUserId(); CmtcComment comment = Global.get(ZTable.class).item(CmtcComment.class, commentId); int commentGoodNum = comment.getCommentGoodNum(); String commentGoodUserId = comment.getCommentGoodUserId(); if (!(commentGoodUserId.indexOf(Long.toString(userId)) == -1)) { request.setResponseError("已经点过赞啦"); return; } Updater updater = new Updater(); updater.addMust("commentId", commentId); updater.addField("commentGoodNum", commentGoodNum + 1); updater.addField("commentGoodUserId", commentGoodUserId + userId + ","); Global.get(ZTable.class).update(CmtcComment.class, updater); } /** 取消点赞 */ public static void doCommentCommonGoodCancel(HttpRequest request) throws Exception { ZacSessionUser sessionUser = request.getSessionUser(ZacSessionUser.class); if (sessionUser == null) { request.setResponseError("请先登录"); return; } // 检查参数 request.addValidate(new IsNotEmpty("commentId", "请选择一个评论")); if (!request.chkValidate()) { request.setResponseError(request.getAlertMsg()); return; } long commentId = request.getParameterLong("commentId"); long userId = sessionUser.getUserId(); CmtcComment comment = Global.get(ZTable.class).item(CmtcComment.class, commentId); int commentGoodNum = comment.getCommentGoodNum(); String commentGoodUserId = comment.getCommentGoodUserId(); if (commentGoodUserId.indexOf(Long.toString(userId)) == -1) { request.setResponseError("还没点过赞哦"); return; } Updater updater = new Updater(); updater.addMust("commentId", commentId); updater.addField("commentGoodNum", commentGoodNum - 1); updater.addField("commentGoodUserId", commentGoodUserId.replaceFirst(userId + ",", "")); Global.get(ZTable.class).update(CmtcComment.class, updater); } /** 删除评论 */ public static void doCommentCommonDeleteComment(HttpRequest request) throws Exception { // 检查参数 request.addValidate(new IsNotEmpty("commentId", "请选择一个评论")); if (!request.chkValidate()) { request.setResponseError(request.getAlertMsg()); return; } long commentId = request.getParameterLong("commentId"); Global.get(ZTable.class).delete(CmtcComment.class, commentId); } }