- 浏览: 6934 次
- 性别:
- 来自: 南京
最新评论
请求的流程也是在类net.jforum.JForum.java中:
public class JForum extends JForumBaseServlet { public void service(HttpServletRequest req, HttpServletResponse res) throws IOException, ServletException { Writer out = null; JForumContext forumContext = null; RequestContext request = null; ResponseContext response = null; String encoding = SystemGlobals.getValue(ConfigKeys.ENCODING); try { // Initializes the execution context JForumExecutionContext ex = JForumExecutionContext.get(); request = new WebRequestContext(req); response = new WebResponseContext(res); this.checkDatabaseStatus(); forumContext = new JForumContext(request.getContextPath(), SystemGlobals.getValue(ConfigKeys.SERVLET_EXTENSION), request, response ); ex.setForumContext(forumContext); JForumExecutionContext.set(ex); // 准备freemarker数据模型 // Setup stuff SimpleHash context = JForumExecutionContext.getTemplateContext(); ControllerUtils utils = new ControllerUtils(); utils.refreshSession(); context.put("logged", SessionFacade.isLogged()); //加载当前用户的权限到cache中 // Process security data SecurityRepository.load(SessionFacade.getUserSession().getUserId()); utils.prepareTemplateContext(context, forumContext); //取得请求的模块 String module = request.getModule(); //取得模块对应的处理类 // Gets the module class name String moduleClass = module != null ? ModulesRepository.getModuleClass(module) : null; //请求中模块为空,向客户端返回找不到页面的错. if (moduleClass == null) { // Module not found, send 404 not found response response.sendError(HttpServletResponse.SC_NOT_FOUND); } else { //判断客户端地址是否是被禁止了 boolean shouldBan = this.shouldBan(request.getRemoteAddr()); if (!shouldBan) { //正常的请求 context.put("moduleName", module); context.put("action", request.getAction()); } else { //被禁止的请求,更改请求的模块为forums,action为banded,即请求路径为:/forums/banned moduleClass = ModulesRepository.getModuleClass("forums"); context.put("moduleName", "forums"); ((WebRequestContext)request).changeAction("banned"); } if (shouldBan && SystemGlobals.getBoolValue(ConfigKeys.BANLIST_SEND_403FORBIDDEN)) { //被禁止的请求,向客户端返回禁止访问页面 response.sendError(HttpServletResponse.SC_FORBIDDEN); } else { //正常的请求,将请求代理为具体的命令执行 context.put("language", I18n.getUserLanguage()); context.put("session", SessionFacade.getUserSession()); context.put("request", req); context.put("response", response); out = this.processCommand(out, request, response, encoding, context, moduleClass); } } } catch (Exception e) { //异常处理:设置允许事务回滚,向异常页面输出异常信息 this.handleException(out, response, encoding, e, request); } finally { this.handleFinally(out, forumContext, response); } } private void handleFinally(Writer out, JForumContext forumContext, ResponseContext response) throws IOException { //关闭输出流 try { if (out != null) { out.close(); } } catch (Exception e) { // catch close error } //获取重定向页面 String redirectTo = JForumExecutionContext.getRedirectTo(); //对数据库连接进行事务回滚或提交,并释放连接 JForumExecutionContext.finish(); if (redirectTo != null) { //将请求重定向到指定页 if (forumContext != null && forumContext.isEncodingDisabled()) { response.sendRedirect(redirectTo); } else { response.sendRedirect(response.encodeRedirectURL(redirectTo)); } } } private void handleException(Writer out, ResponseContext response, String encoding, Exception e, RequestContext request) throws IOException { //设置允许事务回滚 JForumExecutionContext.enableRollback(); //向异常页面输出异常信息 if (e.toString().indexOf("ClientAbortException") == -1) { response.setContentType("text/html; charset=" + encoding); if (out != null) { new ExceptionWriter().handleExceptionData(e, out, request); } else { new ExceptionWriter().handleExceptionData(e, new BufferedWriter(new OutputStreamWriter(response.getOutputStream())), request); } } } /** * 判断用户地址,或者用户账号被列入禁止列表 */ private boolean shouldBan(String ip) { Banlist b = new Banlist(); b.setUserId(SessionFacade.getUserSession().getUserId()); b.setIp(ip); return BanlistRepository.shouldBan(b); } private Writer processCommand(Writer out, RequestContext request, ResponseContext response, String encoding, SimpleHash context, String moduleClass) throws Exception { //根据模块的类名,实例化相应的命令,一个请求对应一个实例,利用反射生成类的实例 // Here we go, baby Command c = this.retrieveCommand(moduleClass); Template template = c.process(request, response, context); //不是重定向请求 if (JForumExecutionContext.getRedirectTo() == null) { String contentType = JForumExecutionContext.getContentType(); if (contentType == null) { contentType = "text/html; charset=" + encoding; } response.setContentType(contentType); //如果不是请求的二进程文件,向输出流中输出模板处理的结果,即返回请求的结果页面 // Binary content are expected to be fully // handled in the action, including outputstream // manipulation if (!JForumExecutionContext.isCustomContent()) { out = new BufferedWriter(new OutputStreamWriter(response.getOutputStream(), encoding)); template.process(JForumExecutionContext.getTemplateContext(), out); out.flush(); } } return out; } }
public class ControllerUtils { /** * 用户没有登录:如果配置了自动登录,则进行自动登录,否则则生成一个匿名用户登录 */ public void refreshSession() { UserSession userSession = SessionFacade.getUserSession(); RequestContext request = JForumExecutionContext.getRequest(); if (userSession == null) {// 如果用户还未登录 userSession = new UserSession(); userSession.registerBasicInfo(); userSession.setSessionId(request.getSessionContext().getId()); userSession.setIp(request.getRemoteAddr()); SessionFacade.makeUnlogged(); if (!JForumExecutionContext.getForumContext().isBot()) { // Non-SSO authentications can use auto login if (!ConfigKeys.TYPE_SSO.equals(SystemGlobals.getValue(ConfigKeys.AUTHENTICATION_TYPE))) {// 不是SSO认证 if (SystemGlobals.getBoolValue(ConfigKeys.AUTO_LOGIN_ENABLED)) {// 如果配置了自动登录 this.checkAutoLogin(userSession); } else {// 没有配置自动登录,生成一个匿名用户 userSession.makeAnonymous(); } } else {//转向SSO认证 this.checkSSO(userSession); } } SessionFacade.add(userSession); } else if (ConfigKeys.TYPE_SSO.equals(SystemGlobals.getValue(ConfigKeys.AUTHENTICATION_TYPE))) {//用户已经登录,且SSO认证 SSO sso; try { sso = (SSO) Class.forName(SystemGlobals.getValue(ConfigKeys.SSO_IMPLEMENTATION)).newInstance(); } catch (Exception e) { throw new ForumException(e); } // If SSO, then check if the session is valid if (!sso.isSessionValid(userSession, request)) {//session无效 SessionFacade.remove(userSession.getSessionId()); refreshSession(); } } else {// 更新用户在线时长 SessionFacade.getUserSession().updateSessionTime(); } } }
核心的处理请求的命令类
public abstract class Command { public Template process(RequestContext request, ResponseContext response, SimpleHash context) { this.request = request; this.response = response; this.context = context; //取得对模块的动作,对应为模块处理类的具体方法名 String action = this.request.getAction(); if (!this.ignoreAction) { try { //以无参形式执行请求对应的具体类的某个方法 this.getClass().getMethod(action, NO_ARGS_CLASS).invoke(this, NO_ARGS_OBJECT); } catch (NoSuchMethodException e) { //如果请求的方法不存在,默认执行list方法 this.list(); } catch (Exception e) { throw new ForumException(e); } } if (JForumExecutionContext.getRedirectTo() != null) { //是重定向请求 this.setTemplateName(TemplateKeys.EMPTY); } else if (request.getAttribute("template") != null) { //从请求中取得模板名,从缓存中取得模板名对应的具体页面,具体的对应关系在系统初始化时从templatesMapping.properties文件加载,并放到缓存中 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()); } catch (IOException e) { throw new ForumException( e); } } }
相关推荐
这个压缩包文件包含了关于Jforum的多个重要知识点,包括配置、初始化流程、处理请求的MVC架构、数据库访问实现、文件监控、缓存机制以及权限控制等内容。下面将对这些主题进行详细阐述。 首先,Jforum的配置是论坛...
Jforum的控制器基于Struts框架,提供了一种灵活的方式来组织和管理应用的流程。 **数据库和重要配置文件** Jforum的数据库设计是其核心部分,包含了用户信息、论坛板块、主题、帖子等数据表。配置文件如`database....
**JForum3源代码详解** JForum是一款广受欢迎的开源论坛软件,以其强大的功能、友好的用户界面和清晰的代码结构...无论是对Java框架的深入理解,还是对Web应用开发流程的整体把握,JForum3都是一份宝贵的教育资源。
5. **二次开发流程**:包括阅读源码,理解业务逻辑,使用版本控制系统(如Git)获取最新代码,编写单元测试,修改代码,构建新的jar包,部署并验证修改。这个过程涉及到软件开发的完整生命周期。 6. **数据库设计**...
2. 控制器(Controller):处理用户的请求,协调模型和视图之间的交互。 3. 视图(View):展示论坛内容,如帖子、板块、用户信息等,通常使用JSP页面实现。 4. 服务层(Service):封装业务逻辑,如用户注册、发帖...
1. **Struts框架**:JForum采用Struts作为MVC框架,处理HTTP请求并控制业务流程。 2. **Spring框架**:用于依赖注入,管理Bean,实现事务控制等。 3. **Hibernate**:作为ORM框架,负责数据持久化,与数据库进行交互...
总的来说,JForum开源论坛的2.1.9版本是一份宝贵的教育资源,对于Java Web开发者而言,它不仅提供了实践机会,还能帮助理解Web应用的架构设计和开发流程。通过研究源代码,我们可以提升自己的编程技巧,理解如何构建...
处理请求流程 - **前端处理器**:`JForum` 类作为前端处理器,负责接收客户端的请求,并根据请求内容执行相应的操作。 - **初始化流程**:`JForumBaseServlet` 类中定义了 `init` 方法,该方法在Servlet初始化时被...
本文将深入探讨Jforum3的核心特性、开发环境以及运行流程。 首先,Jforum3采用Java技术栈,这使得它具备跨平台的特性,可以在多种操作系统上运行。Java的面向对象特性也使得代码结构清晰,易于维护和扩展。同时,...
**JForum 2.5.0 安装详解** JForum 是一个开源的、基于Java的Web论坛系统,提供强大的讨论板功能...在实际操作过程中,可能还需要处理一些特定的错误或配置问题,但基本流程如上所述,希望能为你提供一个清晰的指导。
总之,开源论坛jforum-2.1.9源码提供了丰富的学习资源,无论是对JSP、Servlet、JavaBean技术的实践,还是对MySQL数据库管理的理解,或是对Web应用开发流程的掌握,都具有很高的学习价值。对于希望深入理解Java Web...
2. **配置驱动**:通过XML配置文件定义请求映射和业务流程,提高了代码的可维护性。 3. **拦截器**:利用拦截器机制,可以添加额外的功能,如日志、事务管理等,无需改动核心代码。 4. **插件体系**:Struts支持各种...
"jforum.gif"可能是JForum系统的整体工作流程图或者某一特定功能的简略表示。"jforum.htm"可能是一个介绍JForum的网页,包含了系统的基本信息和使用指南。"jforum_model.vsd"可能是一个Visio文档,用于绘制更复杂的...
【JForum开源论坛2.1.6】是一个基于Java技术和JSP(JavaServer Pages)的开源讨论论坛系统,适用于学生毕业设计和学习实践...同时,参与开源项目也可以让你接触到实际的开发流程,学习到团队合作和代码质量管理的经验。
在jforum的序列图中,我们可以看到各个组件如何协同工作来完成特定的业务流程,例如用户登录、发表帖子等。序列图通过时间轴展示了消息的传递顺序,有助于理解系统中各组件间的动态交互关系。 jforum的序列图可能...
JForum是一款基于Java技术开发的开源论坛系统,...通过分析和修改JForum的源代码,学生可以深入理解Web应用的开发流程,掌握用户认证、权限控制、数据持久化等核心概念,对提升编程技能和理解Web系统架构有极大的帮助。
**Java源码:Java论坛系统 JForum** JForum是一款基于Java技术开发的开源论坛系统,以其高效、稳定和可扩展性而闻名。...通过深入研究其源码,开发者可以提升自己的Java技术水平,了解Web应用的完整开发流程。
这个描述暗示了开发者需要对电子商务流程有深入理解,并能利用Java Web技术实现这些功能。 【标签】"java"表明该项目的核心编程语言是Java,这包括了Servlet、JSP、Spring MVC、Hibernate等Java Web开发框架。Java...
集中管理请求参数与参数映射 以运行时异常的方式来管理错误的响应 使用泛型来做强类型编程 多协议扩展支持(REST, RPC, SOAP, etc) Rails3消息队列系统 Sidekiq Sidekiq 为 Rails 3 应用程序提供一个高效的消息...
集中管理请求参数与参数映射 以运行时异常的方式来管理错误的响应 使用泛型来做强类型编程 多协议扩展支持(REST, RPC, SOAP, etc) Rails3消息队列系统 Sidekiq Sidekiq 为 Rails 3 应用程序提供一个高效的消息...