一个简单的MVC框架
1、ActionMap,action name与action object之间的映射
public class ActionMap {
private Map<String, Object> actionMap = new HashMap<String, Object>();
public Object getAction(String actionName){
return actionMap.get(actionName);
}
public void initFromProperties(Configuration conf) throws InstantiationException, IllegalAccessException, ClassNotFoundException{
System.out.println("Init actionMap from Properties " + conf.getFileName() + " ...");
Set<Entry<Object, Object>> keyValues = conf.entrySet();
for(Entry<Object, Object> keyValue : keyValues){
this.actionMap.put(keyValue.getKey().toString(), Class.forName(keyValue.getValue().toString()).newInstance());
}
System.out.println("Init actionMap success, Total size " + this.actionMap.size());
}
}
2、NormalUrl是用来解析url中的Servlet path中的action name与method name的(本来还有一个RestfulUrl的,但又不想在这里实现),约定为 http://www.unclepeng.com:XXXX/appName/actionName/methodName/...
1、ActionMap,action name与action object之间的映射
public class ActionMap {
private Map<String, Object> actionMap = new HashMap<String, Object>();
public Object getAction(String actionName){
return actionMap.get(actionName);
}
public void initFromProperties(Configuration conf) throws InstantiationException, IllegalAccessException, ClassNotFoundException{
System.out.println("Init actionMap from Properties " + conf.getFileName() + " ...");
Set<Entry<Object, Object>> keyValues = conf.entrySet();
for(Entry<Object, Object> keyValue : keyValues){
this.actionMap.put(keyValue.getKey().toString(), Class.forName(keyValue.getValue().toString()).newInstance());
}
System.out.println("Init actionMap success, Total size " + this.actionMap.size());
}
}
2、NormalUrl是用来解析url中的Servlet path中的action name与method name的(本来还有一个RestfulUrl的,但又不想在这里实现),约定为 http://www.unclepeng.com:XXXX/appName/actionName/methodName/...
public class NormalUrl { public static final String DEFAULT_METHOD_NAME = "index"; private String actionName; private String methodName; private int level = 2; public String getActionName() { return actionName; } public String getMethodName() { return methodName; } public static NormalUrl fromServletPath(String str){ if(str.startsWith("/")){ str = str.substring(1); } String[] strs = StringUtils.split(str, '/', true); NormalUrl url = new NormalUrl(); if(strs == null || strs.length == 0){ throw new IllegalArgumentException(String.format("Illegal Servlet path %s", str)); } url.actionName = StringUtils.split(strs[0], '.', true)[0]; if(strs.length > 1){ url.methodName = StringUtils.split(strs[1], '.', true)[0]; }else{ url.methodName = DEFAULT_METHOD_NAME; url.level = 1; } return url; } public int getLevel() { return level; } public void setLevel(int level) { this.level = level; } } [、code] 3、核心DispatcherServlet,在init的时候初始化actionMap,在doGet方法中根据servlet path解析出对应的actionName与methodName,再找到对应的Action Object,然后invoke methodpublic class DispatcherServlet extends HttpServlet { private static final long serialVersionUID = - 8330920476525405610L; public static final String INCLUDE_PATH_INFO = "javax.servlet.include.path_info"; public DispatcherServlet() { super(); } private ActionMap actionMap = new ActionMap(); public static int FILE_NOT_FOUND = 404; public void destroy() { super.destroy(); this.actionMap = null; } public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //Split URL String path = request.getServletPath(); NormalUrl url = NormalUrl.fromServletPath(path); String actionName = url.getActionName(); String methodName = url.getMethodName(); //Get action by name, if not found, response 404 Object action = this.actionMap.getAction(actionName); if(action == null){//action not found System.err.println(String.format("Action named '%s' not found", actionName)); response.sendError(FILE_NOT_FOUND); } //Invoke action method, and forward if invoke result not returns null try{ Method method = action.getClass().getMethod(methodName, HttpServletRequest.class, HttpServletResponse.class); Object o = method.invoke(action, new Object[]{request, response}); if(o!= null){ if(url.getLevel() == 2){ request.getRequestDispatcher("../" + (String)o).forward(request, response); }else{ request.getRequestDispatcher((String)o).forward(request, response); } return; } }catch(Exception e){ e.printStackTrace(); response.sendError(FILE_NOT_FOUND); return; } } public void doPut(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } public void doDelete(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } public void init() throws ServletException { ServletConfig servletConfig = this.getServletConfig(); String mvcConfigFilePath = servletConfig.getInitParameter("mvc_config"); Configuration conf = null; if(mvcConfigFilePath != null){//case 1, use properites configuration try { conf = new PropertiesConfiguration(mvcConfigFilePath); actionMap.initFromProperties(conf); return; } catch (Exception e) { e.printStackTrace(); System.exit(1); } }else{//case 2, use packages setting String realPath = this.getServletContext().getRealPath("/"); String packagesPath = servletConfig.getInitParameter("action_packages"); String[] packagePathArray = StringUtils.split(packagesPath, ',', true); for(String packagePath : packagePathArray){ } } } }
4、web.xml配置<?xml version="1.0" encoding="UTF-8"?> <web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"> <servlet> <servlet-name>Dispatcher</servlet-name> <servlet-class>com.upeng.webcommons.mvc.DispatcherServlet</servlet-class> <init-param> <param-name>mvc_config</param-name> <param-value>mvc.properties</param-value> </init-param> </servlet> <servlet-mapping> <servlet-name>Dispatcher</servlet-name> <url-pattern>*.do</url-pattern> </servlet-mapping> </web-app>
5、示例Actionpublic class ProductAction { public String index(HttpServletRequest request, HttpServletResponse response){ return "product.jsp"; } }
6、mvc.properties配置product =com.upeng.webcommons.test.ProductAction
7、Test
http://localhost:222/webcommons/product/index.do 或者 http://localhost:222/webcommons/product.do,其中的product为action名,index为action中的方法名,当没指定方法时,默认选择action中的index方法
总结与选型过程:
1、本来想实现基于类的MVC,类似struts2,然后把对应的url parameter注入到action的field中,这样做好处是能跟servletAPI完全解耦,坏处是为每次请求以反射的方式生成一个临时的action object,效率上要打些折扣。
2、也想过实现类似mvc.net 1.0中的把action实现成sigton,然后实现基于方法的MVC把对应的url parameter注入到方法的参数里然后回调,这样做要求action中不能有重名的方法,另外在查找方法的时候要做一次遍历,稍微比直接指定method name跟parameterTypes式的查找慢了那么一点。
但是还需要把string型的url parameters转型为方法参数对应的类型效率上又打了一点点的折扣。综合考虑下便又打消了这个念头
3、这还只是一个MVC雏形,初步实现了url到action乃到action中的method之间的mapping,当然,也可以添加对参数检验,错误处理、国际化等的支持。
发表评论
-
MyEclipse6.5配置Tomcat7.0
2014-11-26 10:26 817window>>Preferences>&g ... -
JSP 转换 mht java 代码
2013-11-22 10:31 1036import java.io.BufferedInputS ... -
JAVA实现FTP上传下载
2013-09-06 10:31 876import java.io.DataIn ... -
java的KVM在arm上的应用
2013-03-21 09:26 933http://wenku.baidu.com/view/162 ... -
JAVA在ARM的应用
2013-03-21 09:18 5743J2ME CDC(Connected Device Confi ... -
JAVA桌面截图
2013-03-20 15:07 780Robot robot = new Robo ... -
引用他人代码去掉前面行数
2013-03-19 11:01 869import java.io.*; public clas ... -
JAVA调用DLL文件
2012-11-25 16:02 9761 创建 TestDll.java public cla ... -
用java的反射清空对象属性的值
2012-10-25 16:09 7993@SuppressWarnings("unche ... -
用反射清空对象属性的的值
2012-10-25 16:06 0@SuppressWarnings("unche ... -
JMS实例,包括点对点和主题订阅
2012-07-11 10:58 2997三个Java文件: JMSTest.java ... -
Jmail收发邮件
2012-07-11 09:32 1097Jmail 接收邮件: import javax.mai ... -
MyEclipse6.0反编译插件jadclipse安装
2012-05-16 11:54 1034插件下载 反编译工具jad,地址:http://www.var ... -
MyEclipse6.0反编译插件jadclipse安装
2012-05-16 11:51 0插件下载 反编译工具ja ... -
把第一个对象中不为空的数据复制到第二个对象中
2012-04-09 10:31 1047/*** *实现两个实例对象之间的对拷, * ... -
velocity导出word模板
2012-02-29 13:11 1504public class VelocityExample { ... -
Jacob操作word
2012-02-29 13:02 1351package test; import com.jacob ... -
EJB3学习资料
2011-03-31 17:28 856http://wenku.baidu.com/view/6e2 ... -
Java和C#相互调用
2011-03-31 17:23 885http://developer.51cto.com/art/ ... -
java操作注册表方法
2011-02-23 16:57 849http://www.iteye.com/topic/8229 ...
相关推荐
然而,为了理解MVC框架的基本工作原理,我们可以使用Servlet来模拟Struts的行为。 首先,我们要知道MVC的三个核心组件: 1. **Model(模型)**:负责业务逻辑处理和数据操作。在实际项目中,这通常由JavaBean或EJB...
本教程将引导你如何创建自己的MVC框架。 **一、模型(Model)** 模型是MVC框架的核心部分,负责处理业务逻辑和数据操作。在自定义MVC框架中,你需要设计一个抽象的`Model`类或接口,作为所有业务模型的基础。模型...
### ASP.NET 3.5 MVC框架知识点解析 #### 一、概述 ASP.NET MVC 是一种用于构建动态网站的开源框架,它遵循模型-视图-控制器(Model-View-Controller, MVC)架构模式。该模式将业务逻辑与表示层分离,从而提高开发...
ASP.NET MVC 5框架是微软推出的用于构建动态、数据驱动的Web应用程序的开源框架,它基于Model-View-Controller(MVC)设计模式。在这个框架中,开发人员可以清晰地分离业务逻辑、用户界面和数据处理,从而实现更加...
这个简单的模拟项目旨在帮助开发者深入理解Spring MVC的工作原理,通过使用Java注解来实现核心功能。以下是对Spring MVC核心概念及模拟实现的详细解释。 1. **模型(Model)**:在Spring MVC中,模型通常由Java对象...
这个框架结合了ASP.NET的强大力量和MVC(Model-View-Controller)设计模式的优势,为开发者提供了丰富的工具集,使得创建复杂的Web应用变得更为简单。本文将深入探讨ASP.NET MVC5的关键特性、工作原理以及如何利用C#...
1. **Struts**:作为MVC框架,Struts负责处理HTTP请求,调度控制器,以及视图渲染。在自定义框架中,你可以模仿Struts的动作调度和拦截器机制。 2. **Spring**:Spring提供依赖注入和AOP,是整个系统的核心。在我们...
ASP.NET MVC 2.0 是一个用于构建动态网站的开源框架,它基于Model-View-Controller(MVC)设计模式,由微软开发...通过这个“无数据库”的实例,你可以专注于MVC框架的基础概念,从而为后续的复杂项目打下坚实的基础。
总之,这个MVC3项目的增删改查示例涵盖了Web开发的基本流程,它帮助初学者理解MVC框架的工作原理,熟悉数据库操作,以及如何构建动态网页。通过实际动手操作,学习者可以迅速提升自己的技能,为进一步的Web开发奠定...
SpringBoot MVC简单Demo详解 SpringBoot是Spring框架的一个简化版,它旨在简化Spring应用程序的初始搭建...通过学习和实践这个简单的Demo,你可以进一步深入理解SpringBoot MVC的工作原理,从而更高效地开发Web应用。
此外,开发者还应关注Spring的安全更新,及时升级Spring MVC框架以修补已知的安全漏洞。通过结合代码审查、单元测试和安全扫描工具,可以在开发过程中尽早发现并修复潜在的参数绑定漏洞。 对于学习和排查此类问题,...
该在线测试系统是一个使用Spring-MVC框架构建的简单示例,旨在模拟实际的在线考试环境,尤其是处理客观题型。Spring-MVC是Spring框架的一部分,它提供了模型-视图-控制器(MVC)的设计模式,使得开发人员能够更有效...
总的来说,SSM框架的简易登录功能涵盖了前端请求处理、后端业务逻辑、数据库交互以及测试等多个方面,对新手来说,这是一个很好的实践项目,能够帮助他们理解JavaWeb开发的基本流程和SSM框架的协同工作原理。...
**MVC Contrib** 是一个针对ASP.NET MVC框架的开源扩展库,它提供了许多额外的功能和工具,以增强ASP.NET MVC的开发体验。这个压缩包包含了MVC Contrib项目的实例源码和相关组件,对于理解MVC Contrib的工作原理以及...
【标题】"Automa o Web realizada无站点Todo MVC utilizando o框架Cypress.zip" 提供了一个关于使用Cypress框架进行Web自动化测试的项目,重点在于实现一个无服务器(serverless)的Todo MVC应用。Todo MVC是一种...
然后,模拟Struts框架的目的是为了理解和学习其工作原理,或者在特定场景下替代它。Struts框架的关键组件包括: 1. **Action**:业务逻辑的入口点,负责处理用户的请求。 2. **ActionForm**:用于收集和验证表单...
总之,模拟Struts1的过程是一个很好的学习方式,它帮助开发者理解MVC模式和框架如何协调工作,同时也能提升对Servlet的理解。实际开发中,虽然Struts1已经被Struts2和其他现代框架取代,但了解其工作原理对理解和...
Spring 2.0 MVC框架是Java Web开发中的一个重要里程碑,它极大地简化了企业级应用程序的构建,特别是对于处理HTTP请求和响应的Web层。在这个"FirstSpringWebApp"项目中,我们将深入探讨Spring MVC的核心概念和它在...