此文为转载:http://www.diybl.com/course/1_web/webjs/2007113/82989.html 现在,让我们看一下最复杂的一个业务对象,forum,它是一个论坛的核心部分,贴子(其实这个单词是论坛的意思)当然其关系到的业务逻辑及其它东东也最多了!我们从BEAN开始研究:(右边为一条数据库表的记录,注意其中有许多Default值) private String id; //主键 402881e513bdc8550113bdefb43c0014 private String parentID; //父级ID NULL值 private String mainID; //MainID 402881e513bdc8550113bdefb43c0014 private long boardID; //版区ID 2 private String boardName; java private int reNum; //回复数 0 private int face; //表情 0 private String userID; //用户ID 4028818208ed006b0108ed020bd50001 private String userName; webmaster private String nickName; webmaster private String title; //标题 dffdsfds private String detail;//文件名称 P_2_402881e513bdc8550113bdefb43c0014.txt private String sign;//签名 NULL private int artSize;//字数 58 private int click;//点击数 5 private long postTime;//发贴时间 1184302609453 private long lastTime;//最后回复时间 1184302609453 private String ipAddress;//IP地址 127.0.0.1 private int isNew;//是否是主贴(这个取名有点问题) 1 private long elite;//是否精华 0 private long eliteID;//精华目录ID 0 private int agree;//赞成 0 private int beAgainst;//反对 1 private int canNotDel;不是水贴标志 0 private int delSign;//删除标志 0 private String delUserID;//删除者 NULL private String delUserName; NULL private long delTime; 0 private String delIP; NULL private String amend;//删除附加信息 NULL private String doEliteName;//加入精华者用户名 NULL private long doEliteTime;//加入精华时间 0 private int haveAttachFile;//是否有附件 0 private List attachFileName = new ArrayList();//附件文件名列表 NULL private String lastPostUserName;//最后回复用户名 --- private String lastPostTitle;//最后回复帖子标题 NULL private String lastPostNickName; --- private long isTop;//置顶标志 0 private int isLock;//锁定标志 0 private int auditing;//审核标志 0 private int auditingAttachFile;//附件审核标志 0 private int isVote;//是否投票贴标志 0 private int isHidden;//是否隐藏贴标志 0 private int editType;//编辑器类型 0 private String quoteText;//引用文字 NULL private int postType;//发贴类型 0 private int titleColor;//标题color 5 private int canNotRe;//已经是否回复标志 0 private long commend;//推荐标志 0 private int isHiddenValue;//隐藏贴参数 0 private int userBlog;//加入个人文集标志 0 private int indexStatus;//索引标志 0 private int quoteEditType;//引用文字编辑器类型 0 private int emailInform;//通知发信到哪里(不用) 0 private int msgInform;//消息到谁(不用) 0 private String voteID;//投票ID NULL private String tagID;//版区Tag 0 private String tagName;//版区Tag名称 NULL private int isGuest;//是否游客发贴 0 private int previewAttach;//附件预览标志 1 对于ForumMain-mysql.hbm.xml, 我们看下这个另外的hibernate自定义类型类,它与SplitList类似...... 而在数据库中:(请多看看数据库中的数据) PRIMARY KEY (`ID`), UNIQUE KEY `ID` (`ID`), KEY `MainID` (`MainID`), KEY `BoardID` (`BoardID`), KEY `LastTime` (`LastTime`), KEY `PostTime` (`PostTime`), KEY `UserID` (`UserID`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8; 进入到forumservice中,有一大堆方法:(不加javadoc的话应该不会有100个吧!吓人!) public Forum saveOrUpdateForum(Forum forum) throws BbscsException; public Forum saveForum(Forum forum) throws BbscsException; public Forum updateForum(Forum forum) throws BbscsException; public Forum findForumByID(String id); public Forum findForumByID(String id, long bid);//根据ID,Bid取得Forum对象 public long getForumNum(long bid, int isNew, int delSign, int auditing, int auditingAttachFile);//取得帖子数量 public long getForumNum(long bid);//取得正常帖子数量 public long getForumMainNum(long bid);//取得主帖数量 public long getForumDelNum(long bid);//取得已删除帖子数量 public long getForumAuditingNum(long bid);//取得未审核帖子数量 public long getForumTopicNum(long bid, String mainID, int delSign, int auditing);//取得同一主题帖子数量 public long getForumTopicNum(long bid, String mainID);//取得一个主题的帖子数量(正常的) public long getForumTopicDelNum(long bid, String mainID);//取得一个主题已删除帖子数量 public long getForumTopicAuditingNum(long bid, String mainID);//取得一个主题未审核帖子数量 public List findForums(long bid, int isNew, int delSign, int auditing, OrderObj[] oo);//取得帖子列表 public PageList findForums(long bid, int isNew, int delSign, int auditing, int auditingAttachFile, OrderObj[] oo, Pages pages); public PageList findForumsMainWWW(long bid, Pages pages);//取得主帖分页列表(WWW方式,发帖时间排序) public PageList findForumsMainLastRe(long bid, Pages pages);//取得主帖分页列表(顶帖方式,回复时间排序) public PageList findForumsAll(long bid, Pages pages);//取得正常帖子分页列表,不分主从 public PageList findForumsDel(long bid, Pages pages);// 取得已删除帖子分页列表 public PageList findForumsAuditing(long bid, Pages pages);// 取得未审核帖子分页列表 public PageList findForumsTopic(long bid, String mainID, int delSign, int auditing, OrderObj[] oo, Pages pages);//取得同一主题帖子分页列表 public PageList findForumsTopic(long bid, String mainID, Pages pages); public List findForumsTopicAll(long bid, String mainID, int delSign, int auditing, OrderObj[] oo); public List findForumsTopicDel(long bid, String mainID);//取得已删除同一主题帖子列表 public List findForumsTopicAuditing(long bid, String mainID);取得未审核同一主题帖子列表 public List findForumsElite(long bid, long elite, long eliteId);取得精华帖列表 public long getSearchNum(long bid, String con, String text, int delSign, int auditing);取得搜索帖子数量 public PageList getSearchList(long bid, String con, String text, int delSign, int auditing, String orderby, int ascOrDesc, Pages pages);取得搜索结果分页列表 public long getSearchNum(long bid, String con, String text);取得搜索帖子数量(不带条件) public PageList getSearchList(long bid, String con, String text, Pages pages); public long getForumOwnerNum(String userID);取得自己的帖子数量 public PageList findForumsOwner(String userID, int isNew, Pages pages);取得自己的帖子分页列表 public void removeForum(String id, long bid) throws BbscsException;删除Forum对象 public void removeForum(String id) throws BbscsException; public void removeForum(Forum forum) throws BbscsException; public Forum createForum(Forum forum) throws BbscsException;发帖 public Forum createForum(Forum forum, Board board, UserInfo ui, UploadFile uploadFile) throws BbscsException; public Forum createReForum(Forum forum, Forum mainForum, Board board, UserInfo ui, UploadFile uploadFile, boolean isQuote) throws BbscsException;回帖 public Forum createForumUpFile(Forum forum, UploadFile uploadFile) throws BbscsException; public Forum editForum(Forum forum) throws BbscsException;帖子修改 public long getForumNumCommend(long bid, long commen); public long getForumNumCommend(long commend); public PageList findForumsCommend(long bid, long commen, Pages pages); public PageList findForumsCommend(long commend, Pages pages); public boolean isReedUser(long bid, String mainID, String userID); public void delaPost(Forum forum, Board board, UserInfo ui) throws BbscsException;删除一个帖子 public void savePostElite(Forum forum, UserInfo ui) throws BbscsException; public void saveForums(List forums) throws BbscsException; public void saveForumsEliteDel(List forums) throws BbscsException; public Forum createVoteForum(Forum forum, Board board, Vote vote, UserInfo ui,String voteItem) throws BbscsException; public long getForumOwnerNum(long bid, String userID, String mainID);搂主帖子数 public PageList findForumsOwner(long bid, String userID, String mainID, Pages pages);只看楼主 public void removeAttachFile(Forum forum, List fileNames) throws BbscsException;删除附件 public void removeAllAttachFile(Forum forum) throws BbscsException;删除某个帖子所有附件 public void delForumsNotAuditingAttachFile(List ids) throws BbscsException;删除未通过审核的帖子附件 public long getForumNumHotTopic(long bid, int reNum, int click); public PageList findForumsHotTopic(long bid, int reNum, int click, Pages pages); public void removeToHistory(long atime) throws BbscsException; public void delPosts(List forums, Board board) throws BbscsException; public List findForumsInIds(long bid, List ids); public List findForumsInIds(List ids); public void delPostReal(Forum forum) throws BbscsException; public void delPostsReal(List ids) throws BbscsException; public void delWastePost(long bid) throws BbscsException; public PageList findForumsAllManage(long bid, Pages pages); public void saveForumsResume(List ids, Board board) throws BbscsException; public void saveForumsAuditingAttachFile(List ids) throws BbscsException; public long getForumsAuditingAttachFileNum(long bid); public PageList findForumsAuditingAttachFile(long bid, Pages pages); public List findForumsTopicAuditingAttachFile(long bid, String mainID); public void saveForumChangeUser(Forum forum, int[] titleType, int[] values) throws BbscsException; public void saveForumChangeUser(Forum forum, int titleType, int values) throws BbscsException; public void createCommendPage(long commend) throws BbscsException; public void saveForumCommend(int createOrDel, Board board, Forum forum) throws BbscsException; public List findForumsByIndexStatus(int indexStatus); public List findForumsAllNew(int num); public List findForumsAllNewCache(int num); public PageList findForumsAll(long bid, String tagID, Pages pages); public PageList findForumsMainWWW(long bid, String tagID, Pages pages); public PageList findForumsMainLastRe(long bid, String tagID, Pages pages); public void saveForumBuy(long bid, String postId, Forum f, UserInfo buyFromUi) throws BbscsException; public long getForumBuyNumByPostId(String postId); public ForumBuy findForumBuyByPostIdFromId(String postId, String fromId); public Forum saveEditForum(Forum forum) throws BbscsException; public void saveMoveForum(Forum forum, Board toboard) throws BbscsException; public void saveMoveForum(long frombid, String mainid, Board toboard) throws BbscsException; public String getForumDetail(Forum forum, boolean forcefromfile); 我们进入ForumServiceImp类: 首先它注入了许多DAO和其它服务,如:forumDAO,userInfoDAO,forumUploadFile,sysListObjCache,sysConfig,userInfoFileIO,subscibeFactory,subscibeDAO,boardDAO,subscibeQueue,forumBuyDAO,voteDAO,voteItemDAO,commendDAO,commendFileIO,forumHistoryDAO,forumConfig,postCache....当然,还有logger,真得太吓人了,太多东东了! public Forum createForum(Forum forum) throws BbscsException { Board board = this.getBoardDAO().getBoardByID(forum.getBoardID());//得到版区 UserInfo ui = this.getUserInfoDAO().findUserInfoById(forum.getUserID());//得到用户信息 return createForum(forum, board, ui, null);//让别人去完成! } @SuppressWarnings("unchecked") //因为有些非JDK5.0的开源库如hibernate, 函数返回的一定是List,而不会是List,这时候IDE就会爆出很多warning。用SuppressWarning("unchecked")可以让IDE安静一些。 public Forum createForum(Forum forum, Board board, UserInfo ui, UploadFile uploadFile) throws BbscsException { try { if (Constant.POST_STORAGE_MODE == 0) {//贴子存储方式,其实在web.xml中有设定 forum = this.getForumDAO().saveOrUpdateForum(forum); } else { String detail = forum.getDetail();//现在用这种方式 forum = this.getForumDAO().saveOrUpdateForum(forum); String postFileName = "P_" + forum.getBoardID() + "_" + forum.getId() + ".txt";//可见safe文件夹下的post下的.... File postFile = new File(this.getForumConfig().getForumPath(forum.getBoardID(), forum.getPostTime()) + postFileName); FileUtils.writeStringToFile(postFile, detail, Constant.CHARSET);//写入文件 forum.setDetail(postFileName);//而写入数据库的只是文件名 } if (uploadFile != null) { String fileName = "File_" + forum.getId() + "_" + System.currentTimeMillis()//当前时间 + "." + FilenameUtils.getExtension(uploadFile.getFileName());//文件后缀 String toFilePath = BBSCSUtil.getUpFilePath(forum.getBoardID(), forum.getPostTime());//以前讲过的,应该生成safe/upload/... /** public static String getUpFilePath(long bid, long adate) { StringBuffer sb = new StringBuffer(); sb.append(Constant.ROOTPATH); sb.append(getUpFileWebPath(bid, adate)); File ft = new File(sb.toString()); if (!ft.exists()) { ft.mkdirs(); } return sb.toString(); } public static String getUpFileWebPath(long bid, long adate) { StringBuffer sb = new StringBuffer(); sb.append("upload/"); sb.append((bid % 20)); sb.append("/"); sb.append(bid); sb.append("/"); sb.append(Util.formatDate4(new Date(adate))); sb.append("/"); return sb.toString(); } */ this.getForumUploadFile().saveUploadFile(toFilePath + fileName, uploadFile, this.getSysConfig());//帖子上传文件 forum.setHaveAttachFile(1);//有附件 forum.getAttachFileName().add(fileName);//List里加入内容! if (board.getAuditAttach() == 1) { forum.setAuditingAttachFile(1); } } forum.setMainID(forum.getId()); forum = this.getForumDAO().saveOrUpdateForum(forum);//刷新一下 if (board.getAuditPost() == 0 && board.getAddUserPostNum() == 1) { // 不需要审核,并且版区为增加用户发帖数量 ui.setArticleNum(ui.getArticleNum() + 1); ui.setExperience(ui.getExperience() + 2); // 发帖增加经验值2点。 ui = this.getUserInfoDAO().saveUserInfo(ui);//用户信息更新 this.getUserInfoFileIO().writeUserFile(ui);//用户信息写入文件!见safe/user } if (forum.getEmailInform() != 0 || forum.getMsgInform() != 0) { if (this.getSubscibeDAO().findSubscibeByPostID(forum.getId(), ui.getId(), forum.getBoardID()) == null) { Subscibe subs = this.getSubscibeFactory().getInstance(forum.getBoardID()); subs.setBoardID(forum.getBoardID()); subs.setCreateTime(new Date()); subs.setEmailinform(forum.getEmailInform()); subs.setMsginform(forum.getMsgInform()); subs.setNickName(ui.getNickName()); subs.setPostID(forum.getId()); subs.setPostTitle(forum.getTitle()); subs.setUserEmail(ui.getEmail()); subs.setUserID(ui.getId()); subs.setUserName(ui.getUserName()); subs.setUserLocale(ui.getUserLocale()); this.getSubscibeDAO().saveSubscibe(subs);//订阅服务! } } this.getSysListObjCache().remove(Constant.FORUM_NEW_CACHE_NAME);//文章Cache,remove方法来自Cache接口! return forum; } catch (Exception ex) { logger.error(ex); throw new BbscsException(ex); } } 我们看下ForumConfig的getForumPath:(注意:forum.getBoardID()--->bid,forum.getPostTime()-->adate) 这个服务类注入的是private String safePath; public String getSafePath() { return safePath; } public void setSafePath(String safePath) { this.safePath = safePath; } 它有两个方法:getForumPathOld与getForumPath其实完全一样!555 public String getForumPath(long bid, long adate) { StringBuffer sb = new StringBuffer(); sb.append(this.getSafePath()); if (!this.getSafePath().endsWith("/")) { sb.append("/"); } sb.append("post/"); sb.append(bid % 20); //bid%20的余数 2 sb.append("/"); sb.append(bid); //2 sb.append("/"); sb.append(Util.formatDate4(new Date(adate)));//20070713 sb.append("/"); sb.append(adate % 100);//余数 53 sb.append("/"); File ft = new File(sb.toString()); if (!ft.exists()) { ft.mkdirs(); } return sb.toString(); } 这里有个Util:来自com.laoer.bbscs.comm包,里面有许多格式时间的方法: public static String formatDateTime(Date date) { SimpleDateFormat outFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); return outFormat.format(date); } public static String formatDate2(Date myDate) { SimpleDateFormat formatter = new SimpleDateFormat("yyyy/MM/dd"); String strDate = formatter.format(myDate); return strDate; } public static String formatDate3(Date myDate) { SimpleDateFormat formatter = new SimpleDateFormat("MM-dd HH:mm"); String strDate = formatter.format(myDate); return strDate; } public static String formatDate4(Date myDate) { SimpleDateFormat formatter = new SimpleDateFormat("yyyyMMdd"); String strDate = formatter.format(myDate); return strDate; }//用的是这个啰! public static String formatDate5(Date myDate) { String strDate = getYear(myDate) + "-" + getMonth(myDate) + "-" + getDay(myDate); return strDate; } public static String formatDate6(Date myDate) { SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm"); String strDate = formatter.format(myDate); return strDate; } 而另外一个是文件上传操作!贴子附件上传和用户信息写入文件两种:它们都在com.laoer.bbscs.fio中,有三个接口:CommendFileIO,ForumUploadFile,UserInfoFileIO,另外,这个包里也提供了一个javabean:UploadFile,有两个上传文件需要用到的属性fileName和InputStream类型的inputStream,它们提供了对外实用方法..我们一个一个看它们的实现过程,CommendFileIO是推荐内容,我们曾讲过,safe/include/...两个文件,而本forum用到的是另外两个: ForumUploadFile中有 public void saveUploadFile(String toFileName, UploadFile uploadFile, SysConfig sysConfig) throws IOException; //sysConfig用于获得系统的配置参数!,这里也用到了UploadFile这个javabean! public void delUploadFile(Forum f) throws IOException; public List delUploadFile(Forum f, List fileNames) throws IOException; public void moveUploadFile(Forum forum, long tobid) throws IOException; public void delDetailFile(Forum forum) throws IOException; 我们看它的实现,由于实现它是通过spring注入的! 这个类也先使用了forumConfig及其getter/setter!(不过怎么没注入呢)我们看其: public void saveUploadFile(String toFileName, UploadFile uploadFile, SysConfig sysConfig) throws IOException { OutputStream bos = new FileOutputStream(toFileName); IOUtils.copy(uploadFile.getInputStream(), bos); if (sysConfig.isAttachImg(uploadFile.getFileName()) && sysConfig.getReduceAttachImg() == 1) { ImgUtil.reduceImg(toFileName, toFileName + Constant.IMG_SMALL_FILEPREFIX, sysConfig .getReduceAttachImgSize(), sysConfig.getReduceAttachImgSize(),1);//缩微图的生成,同目录内!public static String IMG_SMALL_FILEPREFIX = "_Small"; } ----------> public boolean isAttachImg(String fileName) { return FilenameUtils.isExtension(fileName, getAttachImgTypes()); } public String[] getAttachImgTypes() { String[] types = getAttachImgType().split(","); if (types == null || types.length == 0) { //提供默认值! types = new String[3]; types[0] = "gif"; types[1] = "jpg"; types[2] = "jpeg"; } return types; } public String getAttachImgType() { return this.getStringValue("AttachImgType"); } public int getReduceAttachImg() { return this.getIntValue("ReduceAttachImg", 1); } 是图片且系统允许生成! public int getReduceAttachImgSize() { return this.getIntValue("ReduceAttachImgSize", 200); }//长宽都用这个 注意我们将继续深入下去: FilenameUtils是org.apache.common.io下的!而ImgUtil.reduceImg则是com.laoer.bbscs.comm包里的工具类:(这个类就只有一个方法),我们摘入主要的一段: public static void reduceImg(String imgsrc, String imgdist, int widthdist, int heightdist, int benchmark) { // int benchmark说明:0,长宽哪个长,以哪个为标准;1,以宽为基准;2,以高为基准 try { File srcfile = new File(imgsrc); if (!srcfile.exists()) { return; } Image src = javax.imageio.ImageIO.read(srcfile); int width = src.getWidth(null); int height = src.getHeight(null); if (width <= widthdist && height <= heightdist) { // SysUtil.cpoyFile(imgsrc, imgdist); FileUtils.copyFile(new File(imgsrc), new File(imgdist)); return; } // 宽度除以高度的比例 float wh = (float) width / (float) height; if(benchmark==0) { ... } if (benchmark == 1) { float tmp_heigth = (float) widthdist / wh; BufferedImage tag = new BufferedImage(widthdist, (int) tmp_heigth, BufferedImage.TYPE_INT_RGB); tag.getGraphics().drawImage(src, 0, 0, widthdist, (int) tmp_heigth, null); FileOutputStream out = new FileOutputStream(imgdist); JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out); encoder.encode(tag); out.close(); } ...主要还是BufferedImage和JPEGCodec.createJPEGEncoder! 对于ForumUploadFileImp中的其它方法我们在用到的时候在来考虑之. 好,我们看看UserInfoFileIO的writeUserInfo(ui),对于这个文件的效果见:safe/user目录下!我们首先注入的是userConfig和sysConfig两个配置服务!下面是某用户文件中的内容: 402881e513bdc8550113bdf70a1b0019|1184303089000|1184303117000|0|0|0|0|100|0|0|0|0|-|本机地址| 用户ID|注册时间|登录时间|文章数|精华文章数|用户头衔|用户生命值(不一定)|积分|......|社区币|是否有相片|(有的话,图片名,无 为"-")|(有的话,用户来自)| 我们看其中的一段代码: if (StringUtils.isBlank(userInfo.getUserFrom())) { sb.append("-"); } else { sb.append(userInfo.getUserFrom()); } sb.append("|"); File usrfile = new File(this.getUserConfig().getUserFilePath(userInfo.getId()) + Constant.USER_PROFILE);//public static final String USER_PROFILE = "UserProFile.txt"; FileUtils.writeStringToFile(usrfile, sb.toString(), Constant.CHARSET); //关于userConfig其实与sysConfig和ForumConfig类似,提供的是简单的配置方法: 注入了safePath:(以前讲过,这里重复一次) public String getUserFilePath(String userID) { StringBuffer sb = new StringBuffer(); int num = Math.abs(userID.hashCode()); sb.append(this.getSafePath()); if (!this.getSafePath().endsWith("/")) { sb.append("/"); } sb.append("user/"); sb.append(num % 100); sb.append("/"); sb.append(userID); sb.append("/"); File ft = new File(sb.toString()); if (!ft.exists()) { ft.mkdirs(); } return sb.toString(); }
对天乙社区bbscs8实现的详细分析五
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.