`
pengzhoushuo
  • 浏览: 12846 次
  • 性别: Icon_minigender_1
  • 来自: 广州
文章分类
社区版块
存档分类
最新评论

一个简单的MVC框架

阅读更多
一个简单的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框架例子

    总结来说,这个简单的MVC框架例子展示了如何使用JavaBean、Servlet和JSP来构建一个基本的Web应用。这种架构有助于分离关注点,使代码更易于维护和扩展。在实际项目中,更复杂的MVC框架,如Spring MVC,会提供更丰富...

    PHP mvc框架

    **描述** "使用PHP开发自己的MVC框架,站点其实很简单,一个ToDo程序" 提示我们,这里将涉及如何用PHP构建一个简单的MVC框架,并通过一个Todo应用来演示其功能。Todo应用通常是一个基础的待办事项列表,用于展示基本...

    简单mvc框架

    在本项目中,我们探讨的是一个自己开发的简单MVC框架,它特别强调了注解的使用,而非传统的XML配置文件,同时集成了自动事务管理、AOP(面向切面编程)和IOC( inversion of control,控制反转)等关键功能。...

    C++实现简单的MVC框架

    本项目是用C++实现的一个简单的MVC框架,名为MVCDemo,旨在帮助开发者理解MVC设计模式的基础概念。 首先,我们来详细解释MVC的三个组成部分: 1. Model(模型):模型层是应用的核心,它负责管理数据和业务逻辑。...

    php简易MVC框架

    PHP简易MVC框架是由新浪的PHP程序员设计并实现的,旨在为初学者和开发者提供一个轻量级的学习平台,帮助他们理解和应用MVC(Model-View-Controller)设计模式。MVC模式是软件工程中的一种架构模式,广泛应用于Web...

    servlet的一个mvc框架

    本篇将详细介绍一个基于Servlet实现的MVC框架,并探讨其核心概念和工作原理。 **1. MVC设计模式** Model-View-Controller(MVC)是一种广泛应用于Web开发的设计模式。它将应用程序分为三个主要部分: - **Model...

    C#的mvc框架,实现简单的web功能

    C#的mvc框架,实现简单的web功能。可以应用在泛微oa等需要基础开发简单功能的网站。erp,crm等系统。

    asp.net MVC框架示例代码

    asp.net MVC框架示例,一个简单MVC框架演示,

    MVC框架工程Myeclipse做的

    总结来说,MVC框架是Web开发中的一个重要工具,通过它我们可以构建结构清晰、易于维护的应用程序。通过研究提供的资源,你可以深入了解MVC的工作原理,并将其应用于实际项目中,提升你的开发技能。

    ASP.NETMVC框架开发系列课程2_一个简单的ASP.NETMVC应用程序WebCast20080425Video

    本课程“ASP.NET MVC框架开发系列课程2_一个简单的ASP.NET MVC应用程序WebCast20080425Video”旨在深入讲解如何使用该框架来构建实际的Web应用程序。 首先,我们要理解MVC模式的基本概念。模型(Model)负责处理...

    PHP 封装简单MVC框架

    此外,框架可能还包含了一些辅助工具,如自动加载类、错误处理和日志记录等功能,这些都是构建一个完整框架的重要组成部分。 5. **学习路径**: 对于初学者来说,首先理解MVC模式的基本概念是非常重要的。然后,你...

    mystruts简易MVC框架实现 .

    【标题】"mystruts简易MVC框架实现" 在软件开发中,Model-View-Controller(MVC)架构模式是一种广泛应用于创建用户界面的设计模式,它将应用程序的业务逻辑、数据处理和用户界面分离,提高了代码的可维护性和可...

    .netmvc框架

    在.NET MVC框架中,模型(Model)负责处理业务逻辑和数据管理,它是应用程序的核心部分。视图(View)则主要负责展示数据,它通常与控制器(Controller)交互,接收控制器传递的数据并渲染成用户界面。控制器负责...

    Spring-MVC框架简单实现

    Spring MVC 是 Spring 框架的一部分,它是一个用于构建 Web 应用程序的模型-视图-控制器(MVC)架构。在这个简易版框架中,我们将深入理解 Spring MVC 的核心概念和关键组件。 **1. MVC 架构模式** 在 MVC 模式中,...

    ASP.NET MVC框架开发系列课程(1):MVC模式与ASP.NET MVC框架概述

    ASP.NET MVC框架是微软开发的一款用于构建Web应用程序的开源框架,它基于模型-视图-控制器(MVC)设计模式,旨在提供更加灵活、可测试的Web开发方式。本课程将深入探讨MVC模式和ASP.NET MVC框架的基础知识,帮助...

    简约版本 MVC 框架模型

    简约版的MVC框架控制器可能会包含一些基础的路由设置和简单的动作方法,方便快速构建功能。 **ThinkphpMVC** `ThinkphpMVC`可能是这个简约版MVC框架的名称,它基于PHP开发,旨在提供一个轻量级的解决方案,用于理解...

    一个实用小巧的php MVC框架

    一个小巧实用的MVC框架,供大家学习使用. 包含了单例模式,类反射,mvc分离,默认配置文件读取。 目录也比较简单,有兴趣的下去看看吧。 ########### 这个版本有一个地方有错误,请自行校正(^_^ 有错误提示的)

    简单原生php MVC框架

    综上所述,这个“简单原生php MVC框架”提供了一个简洁而高效的开发环境,通过MVC架构帮助开发者更好地组织代码,提高开发效率。使用Composer进行依赖管理,保证了项目依赖的一致性,同时允许开发者轻松引入更多第三...

    微软MVC框架教程 案例

    3. **创建第一个MVC应用**:通过一个简单的示例,展示如何创建一个新的MVC项目。 4. **控制器的使用**:讲解如何定义控制器类,处理HTTP请求,以及如何返回视图或JSON响应。 5. **模型绑定**:解释如何将HTTP请求...

    山寨的一个MVC框架

    7. **测试支持**:一个良好的MVC框架应提供方便的测试工具和API,使得单元测试和集成测试变得简单。 8. **安全性**:考虑到企业级应用的安全需求,框架需要考虑认证、授权和防止SQL注入等安全问题。开发者可能需要...

Global site tag (gtag.js) - Google Analytics