一个简单的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/...
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;
}
}
3、核心DispatcherServlet,在init的时候初始化actionMap,在doGet方法中根据servlet path解析出对应的actionName与methodName,再找到对应的Action Object,然后invoke method
public 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、示例Action
public 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,当然,也可以添加对参数检验,错误处理、国际化等的支持。
分享到:
相关推荐
总结来说,这个简单的MVC框架例子展示了如何使用JavaBean、Servlet和JSP来构建一个基本的Web应用。这种架构有助于分离关注点,使代码更易于维护和扩展。在实际项目中,更复杂的MVC框架,如Spring MVC,会提供更丰富...
**描述** "使用PHP开发自己的MVC框架,站点其实很简单,一个ToDo程序" 提示我们,这里将涉及如何用PHP构建一个简单的MVC框架,并通过一个Todo应用来演示其功能。Todo应用通常是一个基础的待办事项列表,用于展示基本...
在本项目中,我们探讨的是一个自己开发的简单MVC框架,它特别强调了注解的使用,而非传统的XML配置文件,同时集成了自动事务管理、AOP(面向切面编程)和IOC( inversion of control,控制反转)等关键功能。...
本项目是用C++实现的一个简单的MVC框架,名为MVCDemo,旨在帮助开发者理解MVC设计模式的基础概念。 首先,我们来详细解释MVC的三个组成部分: 1. Model(模型):模型层是应用的核心,它负责管理数据和业务逻辑。...
PHP简易MVC框架是由新浪的PHP程序员设计并实现的,旨在为初学者和开发者提供一个轻量级的学习平台,帮助他们理解和应用MVC(Model-View-Controller)设计模式。MVC模式是软件工程中的一种架构模式,广泛应用于Web...
本篇将详细介绍一个基于Servlet实现的MVC框架,并探讨其核心概念和工作原理。 **1. MVC设计模式** Model-View-Controller(MVC)是一种广泛应用于Web开发的设计模式。它将应用程序分为三个主要部分: - **Model...
C#的mvc框架,实现简单的web功能。可以应用在泛微oa等需要基础开发简单功能的网站。erp,crm等系统。
asp.net MVC框架示例,一个简单MVC框架演示,
总结来说,MVC框架是Web开发中的一个重要工具,通过它我们可以构建结构清晰、易于维护的应用程序。通过研究提供的资源,你可以深入了解MVC的工作原理,并将其应用于实际项目中,提升你的开发技能。
本课程“ASP.NET MVC框架开发系列课程2_一个简单的ASP.NET MVC应用程序WebCast20080425Video”旨在深入讲解如何使用该框架来构建实际的Web应用程序。 首先,我们要理解MVC模式的基本概念。模型(Model)负责处理...
此外,框架可能还包含了一些辅助工具,如自动加载类、错误处理和日志记录等功能,这些都是构建一个完整框架的重要组成部分。 5. **学习路径**: 对于初学者来说,首先理解MVC模式的基本概念是非常重要的。然后,你...
【标题】"mystruts简易MVC框架实现" 在软件开发中,Model-View-Controller(MVC)架构模式是一种广泛应用于创建用户界面的设计模式,它将应用程序的业务逻辑、数据处理和用户界面分离,提高了代码的可维护性和可...
在.NET MVC框架中,模型(Model)负责处理业务逻辑和数据管理,它是应用程序的核心部分。视图(View)则主要负责展示数据,它通常与控制器(Controller)交互,接收控制器传递的数据并渲染成用户界面。控制器负责...
Spring MVC 是 Spring 框架的一部分,它是一个用于构建 Web 应用程序的模型-视图-控制器(MVC)架构。在这个简易版框架中,我们将深入理解 Spring MVC 的核心概念和关键组件。 **1. MVC 架构模式** 在 MVC 模式中,...
ASP.NET MVC框架是微软开发的一款用于构建Web应用程序的开源框架,它基于模型-视图-控制器(MVC)设计模式,旨在提供更加灵活、可测试的Web开发方式。本课程将深入探讨MVC模式和ASP.NET MVC框架的基础知识,帮助...
简约版的MVC框架控制器可能会包含一些基础的路由设置和简单的动作方法,方便快速构建功能。 **ThinkphpMVC** `ThinkphpMVC`可能是这个简约版MVC框架的名称,它基于PHP开发,旨在提供一个轻量级的解决方案,用于理解...
一个小巧实用的MVC框架,供大家学习使用. 包含了单例模式,类反射,mvc分离,默认配置文件读取。 目录也比较简单,有兴趣的下去看看吧。 ########### 这个版本有一个地方有错误,请自行校正(^_^ 有错误提示的)
综上所述,这个“简单原生php MVC框架”提供了一个简洁而高效的开发环境,通过MVC架构帮助开发者更好地组织代码,提高开发效率。使用Composer进行依赖管理,保证了项目依赖的一致性,同时允许开发者轻松引入更多第三...
3. **创建第一个MVC应用**:通过一个简单的示例,展示如何创建一个新的MVC项目。 4. **控制器的使用**:讲解如何定义控制器类,处理HTTP请求,以及如何返回视图或JSON响应。 5. **模型绑定**:解释如何将HTTP请求...
7. **测试支持**:一个良好的MVC框架应提供方便的测试工具和API,使得单元测试和集成测试变得简单。 8. **安全性**:考虑到企业级应用的安全需求,框架需要考虑认证、授权和防止SQL注入等安全问题。开发者可能需要...