为什么80%的码农都做不了架构师?>>>
前言
在博客摘要里提到了,所有的基类的作用都是为了代码复用。java web程序,也不例外。
而java web程序,里面的基类代码复用,主要是复用什么呢?
答:主要是复用各种servlet对象。
除此之外,当前也会有一些共同的通用的业务方法需要复用,比如,web程序里,浏览器发出请求(数据),服务器要把所请求的数据发送到请求端的浏览器,所以可以复用这个响应数据的方法。
基类
package net.jforum;import java.io.IOException;import net.jforum.context.RequestContext;
import net.jforum.context.ResponseContext;
import net.jforum.exceptions.ForumException;
import net.jforum.exceptions.TemplateNotFoundException;
import net.jforum.repository.Tpl;
import net.jforum.util.preferences.ConfigKeys;
import net.jforum.util.preferences.SystemGlobals;
import net.jforum.util.preferences.TemplateKeys;
import freemarker.template.SimpleHash;
import freemarker.template.Template;/*** Action类的基类,所有的自定义Action类都要继承该基类<p>* * <code>Command</code> Pattern implementation.* All View Helper classes, which are intead to configure and processs* presentation actions must extend this class. * * @author Rafael Steil* @version $Id: Command.java,v 1.27 2007/07/28 14:17:11 rafaelsteil Exp $*/
public abstract class Command
{private static Class[] NO_ARGS_CLASS = new Class[0];private static Object[] NO_ARGS_OBJECT = new Object[0];private boolean ignoreAction;protected String templateName;protected RequestContext request;protected ResponseContext response;protected SimpleHash context;protected void setTemplateName(String templateName){this.templateName = Tpl.name(templateName);}protected void ignoreAction(){this.ignoreAction = true;}/*** Base method for listings. * May be used as general listing or as helper* to another specialized type of listing. Subclasses* must implement it to the cases where some invalid* action is called ( which means that the exception will* be caught and the general listing will be used )*/public abstract void list() ;/*** Process and manipulate a requisition.* @return <code>Template</code> reference* @param request WebContextRequest* @param response WebContextResponse*/public Template process(RequestContext request, ResponseContext response, SimpleHash context){this.request = request;this.response = response;this.context = context;String action = this.request.getAction(); //获取请求url中的方法名(例如,ForumAction.list()方法)if (!this.ignoreAction) {try {this.getClass().getMethod(action, NO_ARGS_CLASS).invoke(this, NO_ARGS_OBJECT);}catch (NoSuchMethodException e) { this.list(); }catch (Exception e){throw new ForumException(e);}}if (JForumExecutionContext.getRedirectTo() != null) {this.setTemplateName(TemplateKeys.EMPTY);}else if (request.getAttribute("template") != null) {this.setTemplateName((String)request.getAttribute("template"));}if (JForumExecutionContext.isCustomContent()) {return null;}if (this.templateName == null) {throw new TemplateNotFoundException("Template for action " + action + " is not defined");}// try {
// return JForumExecutionContext.templateConfig().getTemplate(
// new StringBuffer(SystemGlobals.getValue(ConfigKeys.TEMPLATE_DIR)).
// append('/').append(this.templateName).toString());
// }try {String sb = new StringBuffer(SystemGlobals.getValue(ConfigKeys.TEMPLATE_DIR)).append('/').append(this.templateName).toString();return JForumExecutionContext.templateConfig().getTemplate(sb);}catch (IOException e) {throw new ForumException( e);}}
}
总结:不知道为什么很多地方要提到命令模式,jforum里面的这个基类的原始注释也是这么介绍的,说使用了命令模式啊什么的。
其实,本质上,就是自定义Action类与基类的关系。
子类
/*** 论坛Action*/
package net.jforum.view.forum;import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.HashMap;
import java.util.List;
import java.util.Map;import net.jforum.Command;
import net.jforum.JForumExecutionContext;
import net.jforum.SessionFacade;
import net.jforum.dao.DataAccessDriver;
import net.jforum.dao.ForumDAO;
import net.jforum.dao.ModerationDAO;
import net.jforum.entities.Forum;
import net.jforum.entities.MostUsersEverOnline;
import net.jforum.entities.UserSession;
import net.jforum.repository.ForumRepository;
import net.jforum.repository.SecurityRepository;
import net.jforum.security.SecurityConstants;
import net.jforum.util.I18n;
import net.jforum.util.preferences.ConfigKeys;
import net.jforum.util.preferences.SystemGlobals;
import net.jforum.util.preferences.TemplateKeys;
import net.jforum.view.admin.ModerationAction;
import net.jforum.view.forum.common.ForumCommon;
import net.jforum.view.forum.common.PostCommon;
import net.jforum.view.forum.common.TopicsCommon;
import net.jforum.view.forum.common.ViewCommon;/*** 版块Action(例如,小说版)<p>* --------------------------------<p>* 如果一个请求url(例如,document.location = "forums/list.page";)中的模块是forums,那么就由该类来处理!<p>* * 注:一个请求url,要注意两点,<br>* 1.是哪个模块,即由哪个XXXAction类来处理;<br>* 2.是哪个方法,即由该XXXAction类的这个方法来处理* @author Rafael Steil* @version $Id: ForumAction.java,v 1.76 2007/09/03 12:24:32 rafaelsteil Exp $*/
public class ForumAction extends Command
{/*** 进入版块页面(即论坛首页):列出所有的版块* List all the forums (first page of forum index)?*/public void list(){this.setTemplateName(TemplateKeys.FORUMS_LIST); //"forums.list"this.context.put("allCategories", ForumCommon.getAllCategoriesAndForums(true));this.context.put("topicsPerPage", new Integer(SystemGlobals.getIntValue(ConfigKeys.TOPICS_PER_PAGE)));this.context.put("rssEnabled", SystemGlobals.getBoolValue(ConfigKeys.RSS_ENABLED));this.context.put("totalMessages", new Integer(ForumRepository.getTotalMessages()));this.context.put("totalRegisteredUsers", ForumRepository .totalUsers());this.context.put("lastUser", ForumRepository.lastRegisteredUser());SimpleDateFormat df = new SimpleDateFormat(SystemGlobals.getValue(ConfigKeys.DATE_TIME_FORMAT));GregorianCalendar gc = new GregorianCalendar();this.context.put("now", df.format(gc.getTime()));this.context.put("lastVisit", df.format(SessionFacade.getUserSession().getLastVisit()));this.context.put("forumRepository", new ForumRepository());// Online Usersthis.context.put("totalOnlineUsers", new Integer(SessionFacade.size()));int aid = SystemGlobals.getIntValue(ConfigKeys.ANONYMOUS_USER_ID);List onlineUsersList = SessionFacade.getLoggedSessions();// Check for an optional language parameterUserSession currentUser = SessionFacade.getUserSession();if (currentUser.getUserId() == aid) {String lang = this.request.getParameter("lang");if (lang != null && I18n.languageExists(lang)) {currentUser.setLang(lang);}}// If there are only guest users, then just register// a single one. In any other situation, we do not// show the "guest" usernameif (onlineUsersList.size() == 0) {UserSession us = new UserSession();us.setUserId(aid);us.setUsername(I18n.getMessage("Guest"));onlineUsersList.add(us);}int registeredSize = SessionFacade.registeredSize();int anonymousSize = SessionFacade.anonymousSize();int totalOnlineUsers = registeredSize + anonymousSize;this.context.put("userSessions", onlineUsersList);this.context.put("totalOnlineUsers", new Integer(totalOnlineUsers));this.context.put("totalRegisteredOnlineUsers", new Integer(registeredSize));this.context.put("totalAnonymousUsers", new Integer(anonymousSize));// Most users ever onlineMostUsersEverOnline mostUsersEverOnline = ForumRepository.getMostUsersEverOnline();if (totalOnlineUsers > mostUsersEverOnline.getTotal()) {mostUsersEverOnline.setTotal(totalOnlineUsers);mostUsersEverOnline.setTimeInMillis(System.currentTimeMillis());ForumRepository.updateMostUsersEverOnline(mostUsersEverOnline);}this.context.put("mostUsersEverOnline", mostUsersEverOnline);}public void moderation(){this.context.put("openModeration", true);this.show();}/*** 获取子版块的所有帖子<p>* Display all topics in a forum*/public void show(){int forumId = this.request.getIntParameter("forum_id");ForumDAO fm = DataAccessDriver.getInstance().newForumDAO();// The user can access this forum?Forum forum = ForumRepository.getForum(forumId);if (forum == null || !ForumRepository.isCategoryAccessible(forum.getCategoryId())) {new ModerationHelper().denied(I18n.getMessage("ForumListing.denied"));return;}int start = ViewCommon.getStartPage();List tmpTopics = TopicsCommon.topicsByForum(forumId, start);this.setTemplateName(TemplateKeys.FORUMS_SHOW);// ModerationUserSession userSession = SessionFacade.getUserSession();boolean isLogged = SessionFacade.isLogged();boolean isModerator = userSession.isModerator(forumId);boolean canApproveMessages = (isLogged && isModerator && SecurityRepository.canAccess(SecurityConstants.PERM_MODERATION_APPROVE_MESSAGES));Map topicsToApprove = new HashMap();if (canApproveMessages) {ModerationDAO mdao = DataAccessDriver.getInstance().newModerationDAO();topicsToApprove = mdao.topicsByForum(forumId);this.context.put("postFormatter", new PostCommon());}this.context.put("topicsToApprove", topicsToApprove);this.context.put("attachmentsEnabled", SecurityRepository.canAccess(SecurityConstants.PERM_ATTACHMENTS_ENABLED,Integer.toString(forumId))|| SecurityRepository.canAccess(SecurityConstants.PERM_ATTACHMENTS_DOWNLOAD));this.context.put("topics", TopicsCommon.prepareTopics(tmpTopics));this.context.put("allCategories", ForumCommon.getAllCategoriesAndForums(false));this.context.put("forum", forum);this.context.put("rssEnabled", SystemGlobals.getBoolValue(ConfigKeys.RSS_ENABLED));this.context.put("pageTitle", forum.getName());this.context.put("canApproveMessages", canApproveMessages);this.context.put("replyOnly", !SecurityRepository.canAccess(SecurityConstants.PERM_REPLY_ONLY, Integer.toString(forum.getId())));this.context.put("readonly", !SecurityRepository.canAccess(SecurityConstants.PERM_READ_ONLY_FORUMS, Integer.toString(forumId)));this.context.put("watching", fm.isUserSubscribed(forumId, userSession.getUserId()));// Paginationint topicsPerPage = SystemGlobals.getIntValue(ConfigKeys.TOPICS_PER_PAGE);int postsPerPage = SystemGlobals.getIntValue(ConfigKeys.POSTS_PER_PAGE);int totalTopics = forum.getTotalTopics();ViewCommon.contextToPagination(start, totalTopics, topicsPerPage);this.context.put("postsPerPage", new Integer(postsPerPage));TopicsCommon.topicListingBase();this.context.put("moderator", isLogged && isModerator);}// Make an URL to some actionprivate String makeRedirect(String action){String path = this.request.getContextPath() + "/forums/" + action + "/";String thisPage = this.request.getParameter("start");if (thisPage != null && !thisPage.equals("0")) {path += thisPage + "/";}String forumId = this.request.getParameter("forum_id");if (forumId == null) {forumId = this.request.getParameter("persistData");}path += forumId + SystemGlobals.getValue(ConfigKeys.SERVLET_EXTENSION);return path;}// Mark all topics as readpublic void readAll(){String forumId = this.request.getParameter("forum_id");if (forumId != null) {Map tracking = SessionFacade.getTopicsReadTimeByForum();if (tracking == null) {tracking = new HashMap();}tracking.put(new Integer(forumId), new Long(System.currentTimeMillis()));SessionFacade.setAttribute(ConfigKeys.TOPICS_READ_TIME_BY_FORUM, tracking);}if (forumId != null) {JForumExecutionContext.setRedirect(this.makeRedirect("show"));}else {JForumExecutionContext.setRedirect(this.request.getContextPath() + "/forums/list"+ SystemGlobals.getValue(ConfigKeys.SERVLET_EXTENSION));}}// Messages since last visitpublic void newMessages(){this.request.addParameter("from_date", SessionFacade.getUserSession().getLastVisit());this.request.addParameter("to_date", new Date());SearchAction searchAction = new SearchAction(this.request, this.response, this.context);searchAction.newMessages();this.setTemplateName(TemplateKeys.SEARCH_NEW_MESSAGES);}public void approveMessages(){if (SessionFacade.getUserSession().isModerator(this.request.getIntParameter("forum_id"))) {new ModerationAction(this.context, this.request).doSave();}JForumExecutionContext.setRedirect(this.request.getContextPath() + "/forums/show/"+ this.request.getParameter("forum_id") + SystemGlobals.getValue(ConfigKeys.SERVLET_EXTENSION));}/*** Action when users click on "watch this forum"* It gets teh forum_id and userId, and put them into a watch_forum table in the database;*/public void watchForum(){int forumId = this.request.getIntParameter("forum_id");int userId = SessionFacade.getUserSession().getUserId();this.watchForum(DataAccessDriver.getInstance().newForumDAO(), forumId, userId);JForumExecutionContext.setRedirect(this.redirectLinkToShowAction(forumId));}public void banned(){this.setTemplateName(TemplateKeys.FORUMS_BANNED);this.context.put("message", I18n.getMessage("ForumBanned.banned"));}private String redirectLinkToShowAction(int forumId){int start = ViewCommon.getStartPage();return this.request.getContextPath() + "/forums/show/" + (start > 0 ? start + "/" : "") + forumId+ SystemGlobals.getValue(ConfigKeys.SERVLET_EXTENSION);}/*** * @param dao ForumDAO* @param forumId int* @param userId int*/private void watchForum(ForumDAO dao, int forumId, int userId){if (SessionFacade.isLogged() && !dao.isUserSubscribed(forumId, userId)) {dao.subscribeUser(forumId, userId);}}/*** Unwatch the forum watched.*/public void unwatchForum(){if (SessionFacade.isLogged()) {int forumId = this.request.getIntParameter("forum_id");int userId = SessionFacade.getUserSession().getUserId();DataAccessDriver.getInstance().newForumDAO().removeSubscription(forumId, userId);String returnPath = this.redirectLinkToShowAction(forumId);this.setTemplateName(TemplateKeys.POSTS_UNWATCH);this.context.put("message", I18n.getMessage("ForumBase.forumUnwatched", new String[] { returnPath }));}else {this.setTemplateName(ViewCommon.contextToLogin());}}
}