介绍
MVC:Model-View-Controller,包括三类对象,Model模型对象、View视图表示、Controller控制器。在应用MVC方式以前,通常将这三个对象的功能合到了一起,通过分离 模型、视图和控制器,可以更容易实现灵活性和可重用性。
view和model为观察者和被观察者关系。分离view和model对象,减少对象之间的藕和性,这样,当一个对象改变时,将不会影响到另外的对象,甚至不需要知道另外的对象的实现细节。
Controller定义了对用户输入的处理方式,指Web开发人员编写的处理不同URL。把用户输入的处理方式,封装为控制器。视图对象通过某一控制器对象的实例来实现特定的响应策略。为了实现不同的策略,可以简单的使用不同的控制器实例来替换当前的实例。甚至可以在运行时来改变视图的控制器,以改变视图对象对用户输入的响应。视图和控制器为策略模式关系。
IOC容器:依赖注入。由IOC容器来管理对象的生命周期、依赖关系等,从而使得应用程序的配置和依赖性规范与实际的应用程序代码分开。其中一个特点就是通过文本的配置文件进行应用程序组件间相互关系的配置,而不用重新修改并编译具体的代码。
拦截器:是AOP中的概念,它本身是一段代码,可以通过定义“织入点”,来指定拦截器的代码在“织入点”的前后执行,从而起到拦截的作用。
设计
前置控制器DispatcherServlet.java,他只干了2件事,1、负责初始化。2、接收所有的请求,给处理这。
初始化:DispatcherServlet初始化了系统编码等,控制器的初始化由持有者完成。看下DispatcherServlet.java代码:
package cn.eternal; import java.io.IOException; import javax.servlet.GenericServlet; import javax.servlet.ServletConfig; import javax.servlet.ServletContext; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import cn.eternal.config.Config; public class DispatcherServlet extends GenericServlet { private final Log log = LogFactory.getLog(getClass()); private Dispatcher dispatcher; @Override public void init(final ServletConfig config) throws ServletException{ super.init(config); log.info("Init Config..."); this.dispatcher = new Dispatcher(); this.dispatcher.init( new Config() { public String getInitParameter(String name) { return config.getInitParameter(name); } public ServletContext getServletContext() { return config.getServletContext(); } } ); } @Override public void service(ServletRequest req, ServletResponse resp) throws IOException{ HttpServletRequest httpReq = (HttpServletRequest) req; HttpServletResponse httpResp = (HttpServletResponse) resp; String method = httpReq.getMethod(); if ("GET".equals(method) || "POST".equals(method)) { dispatcher.service(httpReq, httpResp); }else{ httpResp.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED); } } @Override public void destroy() { this.dispatcher.destroy(); } }Dispatcher.java
package cn.eternal; import java.io.IOException; import javax.servlet.ServletContext; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.commons.digester.Digester; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.xml.sax.SAXException; import cn.eternal.config.CommonsConfig; import cn.eternal.config.Config; import cn.eternal.container.Container; import cn.eternal.handler.Handler; import cn.eternal.util.CommonUtil; class Dispatcher { private final Log log = LogFactory.getLog(getClass()); private ServletContext servletContext; public void init(Config config) throws ServletException { this.servletContext = config.getServletContext(); try { String maxFileSize = config.getInitParameter("max_file_size"); if (maxFileSize!=null) { try { long n = Long.parseLong(maxFileSize); if (n<=0) throw new NumberFormatException(); log.info("Init max_file_size "+n); CommonsConfig.setMaxFileSize(n); } catch (NumberFormatException e) { log.warn(" Init Invalid max_file_size value '" + maxFileSize + "', using default."); } } String encoding = config.getInitParameter("encoding"); if(encoding!=null){ log.info("Init encoding "+encoding); CommonsConfig.setEncoding(encoding); } String systemTitle = config.getInitParameter("system_title"); if(systemTitle!=null){ log.info("Init system_title "+systemTitle); CommonsConfig.setEncoding(systemTitle); } initDatabase(); Container.init(config); } catch (Exception e) { throw new ServletException("DispatcherServlet init failed.", e); } } private void initDatabase() { try { Digester digester = new Digester(); digester.setValidating(false); digester.addObjectCreate("database", "cn.eternal.config.CommonsConfig"); digester.addCallMethod("database/database", "setDatabase", 0); digester.addCallMethod("database/driver", "setDriver", 0); digester.addCallMethod("database/login", "setLogin", 0); digester.addCallMethod("database/password", "setPassword", 0); String contextRealPath = servletContext.getRealPath("/"); String prefix = CommonUtil.replaceAllOccurances(contextRealPath, "\\", "/"); if (prefix.endsWith("/")) { prefix = prefix.substring(0, prefix.length() - 1); } digester.parse(prefix+"/WEB-INF/db.xml"); log.info("Init Database Success"); } catch (IOException e) { log.error("Init Database 错误,没有找到/WEB-INF/db.xml文件。", e); } catch (SAXException e) { log.error("Init Database 文件db.xml中包含错误信息。"+e.getMessage(), e); } } public void service(HttpServletRequest req, HttpServletResponse resp){ String url = req.getRequestURI(); log.info("Handle Url "+url); String path = req.getContextPath(); if (path.length()>0){ url = url.substring(path.length()); } Handler handler = new Handler(); try { handler.handle(url,req, resp,servletContext); } catch (Exception e) { e.printStackTrace(); } } public void destroy() { log.info("Destroy Dispatcher..."); Container.destroy(); } }