门户网站综合型门户,郑州经济技术开发区属于什么区,2345网址下载,海外网站建设公司目录
一.什么是MVC
1.1.三层架构和MVC的区别
二.自定义MVC工作原理图
三.自定义mvc实现
3.1 创建web工程 3.2 中央处理器
3.3 Action接口定义
3.4 实现子控制器
3.5 完善中央控制器
3.5.1 请求分发功能
3.5.2 使用配置文件配置action
3.5.3 请求参数处理
1. 定义接…目录
一.什么是MVC
1.1.三层架构和MVC的区别
二.自定义MVC工作原理图
三.自定义mvc实现
3.1 创建web工程 3.2 中央处理器
3.3 Action接口定义
3.4 实现子控制器
3.5 完善中央控制器
3.5.1 请求分发功能
3.5.2 使用配置文件配置action
3.5.3 请求参数处理
1. 定义接口
在中央处理器中加入请求参数的处理能力 2.处理请求参数中的null及空字符串转换问题
为了更方面的处理请求参数中的null及空字符串转换为数值型数据的问题加入一个监听器在应用启动时注册转换器。
3.6 完善Action
1.构建抽象类
2.自定义的Action子控制器示例
发送请求示例http://localhost:8080/mvc/studentAction.actionmethodNameaddStudentsid100age23addraabbcc
四.其他公用组件的集成
五.打jar包 一.什么是MVC
MVC全名是Model View Controller是模型(model)视图(view)控制器(controller)的缩写一种软件设计典范。用一种业务逻辑、数据、界面显示分离的方法将业务逻辑聚集到一个部件里面在改进和个性化定制界面及用户交互的同时不需要重新编写业务逻辑。
MVC结构 Model是应用程序中用于处理应用程序数据逻辑的部分通常模型对象负责在数据库中存取数据。 View是应用程序中处理数据显示的部分通常视图是依据模型数据创建的。 Controller是应用程序中处理用户交互的部分通常控制器负责从视图读取数据控制用户输入并向模型发送数据。
MVC是一个框架模式它强制性的使应用程序的输入、处理和输出分开。使用MVC应用程序被分成三个核心部件模型、视图、控制器。它们各自处理自己的任务。最典型的MVC就是JSP servlet javabean的模式 Model:常用javabean去实现通过各种类来对数据库的数据进行获取并封装在对象当中。 View:常用JSP来实现通过可直接观察的JSP页面来展示我们从数据库中获取的数据。 Controller:常用servlet来实现通过servlet来获取经过javabean包装过的对象已存入数据库中的数据然后再发送数据传输到JSP界面。 1不能跨层调用 2只能由上往下进行调用View - Controller - Model 1.1.三层架构和MVC的区别 三层架构是基于业务逻辑来分的而MVC是基于页面来分的 三层是种软件架构通过接口实现编程MVC模式是一种复合设计模式一种解决方案 三层架构模式是体系结构模式MVC是设计模式 三层架构模式又可归于部署模式MVC可归于表示模式。
二.自定义MVC工作原理图 核心组件说明
中央控制器ActionServlet 复杂接收所有的请求并分别给控制器具体处理。自控制器Action负责处理中央处理器分配的请求视图view jsp页面负责显示模型Model 负责业务处理逻辑
三.自定义mvc实现
3.1 创建web工程
创建一个web工程需要加入必要的依赖。 3.2 中央处理器
通过servlet来实现一个中央控制器负责所有请求的接收。后续中央控制器在再将请求转发给各个子控制器此处可以先把请求接进来转发功能后面再加
/*** 中央控制器负责接收所有的请求并分别给控制器具体处理* author Administrator*/
WebServlet(*.action)
public class ActionDispatchServlet extends HttpServlet {Overridepublic void doGet(HttpServletRequest request, HttpServletResponse response) {doPost(request, response);}Overridepublic void doPost(HttpServletRequest request, HttpServletResponse response) {System.out.println(dopost ..... );}}
3.3 Action接口定义
Action接口定义了每个子控制器需要遵循的行为使得所有的子控制器都有一个同一的抽象类型所以我们可以在中央控制器中使用Action接口类型来引用所有的子控制器。这样就为用户扩展自定义的子控制器提供了条件
/*** 每个子控制器必须实现该接口负责处理中央处理器分配的请求* author Administrator*/
public interface Action {/*** 处理请求* param request 请求* param response 响应* return String 返回转发或重定向的jsp页面名称*/String exeute(HttpServletRequest request, HttpServletResponse response);}
3.4 实现子控制器
为方便调试实现两个子控制器
public class BookAction implements Action {Overridepublic String exeute(HttpServletRequest request, HttpServletResponse response) {return bookList;}}
public class StudentAction implements Action {Overridepublic String exeute(HttpServletRequest request, HttpServletResponse response) {// TODO Auto-generated method stubreturn students;}}
3.5 完善中央控制器
为了便于理解我们可以分步骤的循序渐进的完善中央控制器
编写简单的请求分发实现功能实现通过配置文件来配置子控制器的功能完善请求参数处理功能
3.5.1 请求分发功能
为了在中央控制器中完成请求的分发需要在中央控制器中维护所有子控制器的实例并且能够依据请求路径将请求转发给与其关联的子控制器。
/*** 中央控制器负责接收所有的请求并分别给控制器具体处理* author Administrator*/
WebServlet(*.action)
public class ActionDispatchServlet extends HttpServlet {//用于保存path与action子控制器的映射public static MapString, Action actionMap new HashMap();static {actionMap.put(/studentAction, new StudentAction());actionMap.put(/bookAction, new BookAction());}Overridepublic void doGet(HttpServletRequest request, HttpServletResponse response) {doPost(request, response);}Overridepublic void doPost(HttpServletRequest request, HttpServletResponse response) {String servletPath request.getServletPath();String path servletPath.split(\\.)[0];Action action actionMap.get(path);String rpath action.exeute(request, response);System.out.println(rpath);}}
3.5.2 使用配置文件配置action
在上面的示例中在中央控制器中直接创建action子控制器如果新增一个子控制器需要在中央控制器中添加这样并不实用。 为了增加灵活性可以将action转移到配置文件中配置中央控制器通过配置来初始化action子控制器。
1 此时需要将config.xml文件的解析和建模项目的功能集成进来。 ConfigModelActionModelForwardModelConfigModelFactory
2 在项目的src目录下加入如下配置文件config.xml
?xml version1.0 encodingUTF-8?
!DOCTYPE config[!ELEMENT config (action*)!ELEMENT action (forward*)!ELEMENT forward EMPTY!ATTLIST actionpath CDATA #REQUIREDtype CDATA #REQUIRED!ATTLIST forwardname CDATA #REQUIREDpath CDATA #REQUIREDredirect (true|false) false
]
configaction path/studentAction typeorg.lisen.mvc.action.StudentActionforward namestudents path/students/studentList.jsp redirectfalse//action
/config 完善中央处理器通过配置文件来获取子控制器配置
WebServlet(*.action)
public class ActionDispatchServlet extends HttpServlet {//用于保存path与action子控制器的映射//public static MapString, Action actionMap new HashMap();private static ConfigModel configModel;static {//actionMap.put(/students, new StudentAction());//actionMap.put(/books, new BookAction());configModel ConfigModelFactory.getConfigModel();}Overridepublic void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {doPost(request, response);}Overridepublic void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {String servletPath request.getServletPath();String path servletPath.split(\\.)[0];Action action getActionByPath(path);String name action.exeute(request, response);ForwardModel forwardModel getForwardModel(path, name);if (forwardModel.isRedirect()) {response.sendRedirect(request.getContextPath() / forwardModel.getPath());} else {request.getRequestDispatcher(forwardModel.getPath()).forward(request, response);}}//通过请求路径获取对应的action实例private Action getActionByPath(final String path) {ActionModel action configModel.find(path);try {Class? clazz Class.forName(action.getType());return (Action)clazz.newInstance();} catch (Exception e) {throw new RuntimeException(创建Action实例异常e.getMessage(), e);}}public ForwardModel getForwardModel(String path, String name) {return configModel.find(path).find(name);}}
注 本例的实现中Action子控制器是多例模式的及每个请求对应一个Action实例
3.5.3 请求参数处理
1. 定义接口
/*** 对于需要处理请求参数的Action可以通过实现该接口获取请求参数的* 处理能力中央控制器将会使用该接口来获取Model对象并统一处理* 参数* author Administrator*/
public interface ModelDrive {Object getModel();}
在中央处理器中加入请求参数的处理能力
Override
public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {......Action action getActionByPath(path);//处理请求参数if(action instanceof ModelDrive) {Object model ((ModelDrive) action).getModel();if(model ! null) {try {BeanUtils.populate(model, request.getParameterMap());} catch (Exception e) {throw new RuntimeException(在中央处理器中处理请求参数时发生异常, e);}}}String name action.exeute(request, response);......
} 2.处理请求参数中的null及空字符串转换问题 为了更方面的处理请求参数中的null及空字符串转换为数值型数据的问题加入一个监听器在应用启动时注册转换器。
/*** ServletContextListener接口为Servlet API中的接口用于监听ServletContext对象的生命周期。* 当Servlet 容器启动或终止Web 应用时会触发ServletContextEvent事件该事件由* ServletContextListener来处理。* author Administrator*/
WebListener
public class BeanUtilsListener implements ServletContextListener {/*** 当Servlet 容器终止Web 应用时调用该方法。在调用该方法之前* 容器会先销毁所有的Servlet和Filter 过滤器。*/Overridepublic void contextDestroyed(ServletContextEvent arg0) {// TODO Auto-generated method stub}/*** 当Servlet 容器启动Web应用时调用该方法。* 在调用完该方法之后容器再对Filter 初始化* 并且对那些在Web应用启动时就需要被初始化的Servlet进行初始化。*/Overridepublic void contextInitialized(ServletContextEvent arg0) {ConvertUtils.register(new IntegerConverter(null), Integer.class);ConvertUtils.register(new FloatConverter(null), Float.class);ConvertUtils.register(new DoubleConverter(null), Double.class);ConvertUtils.register(new LongConverter(null), Long.class);ConvertUtils.register(new BigDecimalConverter(null), BigDecimal.class);}}
3.6 完善Action
每个Action只能有一个execute方法如果处理一个模块的增删改查则需要单独编写多个Action这样会比较麻烦。如果在一个Action实例中可以处理多个请求方法则框架会更加灵活。
规定请求参数中必须包含一个“methodName”参数用于指定处理请求的Action中的方法构建一个抽象类该类实现Action子控制器接口通过反射机制调用其子类中的方法方法名有请求参数“methodName”指定。需要开发的Action子控制器集成上一步构建的抽象类编写的用于处理请求的方法名要与请求参数“methodName”指定的方法名匹配同时需要HttpServletRequest和HttpServletResponse两个参数保留该参数主要为了方面对请求的处理
1.构建抽象类
public abstract class AbstractDispatchAction implements Action {Overridepublic String exeute(HttpServletRequest request, HttpServletResponse response) {String methodName request.getParameter(methodName);Class? extends AbstractDispatchAction clazz this.getClass();try {Method method clazz.getDeclaredMethod(methodName, HttpServletRequest.class,HttpServletResponse.class);return (String)method.invoke(this, request,response);} catch (Exception e) {throw new RuntimeException(在调用Action中的[methodName]方法是异常, e);} }}
2.自定义的Action子控制器示例
public class StudentAction extends AbstractDispatchAction implements ModelDrive {private Student student new Student();Overridepublic Object getModel() {return student;}/*Overridepublic String exeute(HttpServletRequest request, HttpServletResponse response) { System.out.println(StudentAction student); return students;}*/public String getStudents(HttpServletRequest request, HttpServletResponse response) { System.out.println(getStudents);System.out.println(StudentAction student);return students;}public String addStudent(HttpServletRequest request, HttpServletResponse response) {System.out.println(addStudent);System.out.println(add student student);return students;}}
发送请求示例 http://localhost:8080/mvc/studentAction.actionmethodNameaddStudentsid100age23addraabbcc
注意在请求中需要添加一个methodName的固定参数该参数指定了需要调用的Action中的方法的名称。
四.其他公用组件的集成
可以将通用分页字符编码过滤器等组件一集成到mvc框架中便于复用。
五.打jar包
将自定义mvc框架打成jar包以便于在其他项目中使用。
项目 --(右击)--Export