`
宋双旺
  • 浏览: 157578 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

Java反射模拟Webwork的URL解析(转)

    博客分类:
  • web
阅读更多

Webwork是一款优秀的WEB应用框架,在其基础之上发展而来的Struts2已经开始替代Struts作为MVC模式下的WEB框架。熟悉 Webwork的程序员很容易过渡到Struts2。本文来模拟一下Webwork的URL解析,应用反射机制实现,只作为说明,当然没有webwork 本身实现的完美。
    Webwork默认解析的服务请求名是.action,这个过程是Servlet容器完成的,而不是框架本身,在web.xml配置<servlet-mapping>和<filer-mapping>时设置<url-pattern>即可实现,这里我们不做过多说明,仅用Servlet来模拟,配置文件使用属性配置文件properties。
    首先还是回顾一下Webwork解析服务请求的方式吧。我们提交的请求以xx.action发出时,在<xwork>中配置的<action>元素中若没有method属性时,则执行的是class类中的execute()方法,若有method属性时,则执行 method中规定的方法。当请求以xx!yy.action形式发出时,在<action>元素中找到class属性的指向类,在该类中执行yy()方法来响应请求。因为Webwork的Action可以是一个POJO,而且方法返回值都默认为String,则在<action>中的<result>元素中的name值和方法返回值匹配后,就转向到<result>标识的目的地址中了,这个地址当然可以是目标页面也可以是另外一个请求地址。
    创建一个WEB项目,起名就叫MVC,配置如下内容:

    在web.xml中配置上一个核心控制器和字符过滤器,很简单,如下进行即可。

Xml代码  收藏代码
  1. < filter >   
  2.     < filter-name > characterEncoding </ filter-name >   
  3. < filter-class > mvc.filters.CharacterEncodingFilter </ filter-class >   
  4.     < init-param >   
  5.         < param-name > encoding </ param-name >   
  6.         < param-value > UTF-8 </ param-value >   
  7.     </ init-param >   
  8. </ filter >   
  9. < filter-mapping >   
  10.     < filter-name > characterEncoding </ filter-name >   
  11.     < servlet-name > FrontController </ servlet-name >   
  12. </ filter-mapping >   
  13. < servlet >   
  14.     < servlet-name > FrontController </ servlet-name >   
  15.     < servlet-class > mvc.ctl.FrontController </ servlet-class >   
  16. </ servlet >   
  17. < servlet-mapping >   
  18.     < servlet-name > FrontController </ servlet-name >   
  19.     < url-pattern > *.action </ url-pattern >   
  20. </ servlet-mapping >   


    这样所有已action为服务请求名的请求都被核心控制器FrontController处理了,那么只要设计好这个核心控制器就行了,那么我们就用这个核心控制器来实现MVC模式。

Java代码  收藏代码
  1. package  mvc.ctl;  
  2. import  java.io.*;  
  3. import  java.util.*;  
  4. import  java.lang.reflect.*;  
  5. import  javax.servlet.*;  
  6. import  javax.servlet.http.*;  
  7. public   class  FrontController  extends  HttpServlet {  
  8.     private  Map actions =  new  HashMap(); // 装资源文件中配置的action   
  9.     public  Map urls =  new  HashMap(); // 装资源文件配置的url   
  10.     @Override   
  11.     public   void  init()  throws  ServletException {  
  12.         // 读取action配置文件   
  13.         ResourceBundle rb = ResourceBundle.getBundle("actions" );  
  14.         Enumeration keys = rb.getKeys();  
  15.         while  (keys.hasMoreElements()) {  
  16.             String key = (String) keys.nextElement();  
  17.             String value = rb.getString(key);  
  18.             try  {  
  19.                 // 根据资源文件的value反射获取action对象并装入HashMap   
  20.                 Object o = Class.forName(value).newInstance();  
  21.                 actions.put(key, o);  
  22.             } catch  (Exception e) {  
  23.                 e.printStackTrace();  
  24.             }  
  25.         }  
  26.         // 读取目的地址配置文件   
  27.         ResourceBundle url = ResourceBundle.getBundle("urls" );  
  28.         keys = url.getKeys();  
  29.         while  (keys.hasMoreElements()) {  
  30.             String key = (String) keys.nextElement();  
  31.             String value = url.getString(key);  
  32.             urls.put(key, value);  
  33.         }  
  34.     }  
  35.     public   void  doGet(HttpServletRequest request, HttpServletResponse response)  
  36.             throws  ServletException, IOException {  
  37.         processRequest(request, response);  
  38.     }  
  39.     public   void  doPost(HttpServletRequest request, HttpServletResponse response)  
  40.             throws  ServletException, IOException {  
  41.         processRequest(request, response);  
  42.     }  
  43.     public   void  processRequest(HttpServletRequest request,  
  44.             HttpServletResponse response) throws  ServletException, IOException {  
  45.         // 从请求中获取URI   
  46.         String requestUri = request.getRequestURI();  
  47.         // 根据最后一个/截取请求地址(包含.action)   
  48.         String actionurl = requestUri.substring(  
  49.                 requestUri.lastIndexOf('/' ) +  1 , requestUri.length());  
  50.         // 截取.action前的有效数据   
  51.         actionurl = actionurl.substring(0 , actionurl.indexOf( ".action" ));  
  52.         // 创建保存处理类和方法的变量   
  53.         String action = "" ;  
  54.         String method = "" ;  
  55.         if  (actionurl.indexOf( "!" ) >=  0 ) { // 有!号的请求这样处理   
  56.             action = actionurl.substring(0 , actionurl.indexOf( "!" ));  
  57.             method = actionurl.substring(actionurl.indexOf("!" ) +  1 );  
  58.         } else  { // 没有!号时则默认执行execute()方法   
  59.             action = actionurl;  
  60.             method = "execute" ;  
  61.         }  
  62.         // 根据截取的action名获得存放在HashMap中的action对象   
  63.         Object handler = null ;  
  64.         handler = actions.get(action);  
  65.         if  (handler ==  null ) { // 没有找到时默认执行default配置的action   
  66.             handler = actions.get("default" );  
  67.             method = "execute" ;  
  68.         }  
  69.         // 存在时,获取Class实例   
  70.         Class handlerClass = handler.getClass();  
  71.         Method executor = null ;  
  72.         // 设置请求处理结束的派发地址   
  73.         String toJump = "index" ;  
  74.         try  {  
  75.             // 反射获取执行方法,由于是Servlet,所以参数是HttpServletRequest和 HttpServletResponse   
  76.             executor = handlerClass.getMethod(method, new  Class[] {  
  77.                     HttpServletRequest.class , HttpServletResponse. class  });  
  78.         } catch  (Exception e) {  
  79.             e.printStackTrace();  
  80.             toJump = "frameerror" ;  
  81.         }  
  82.         try  {  
  83.             // 利用反射机制执行方法,方法调用结束,返回值都是String类型的   
  84.             toJump = (String) executor.invoke(handler, new  Object[] { request,  
  85.                     response });  
  86.         } catch  (Exception e) {  
  87.             e.printStackTrace();  
  88.             toJump = "frameerror" ;  
  89.         }  
  90.         // 转发处理结束以后的地址   
  91.         request.getRequestDispatcher(getURL(toJump)).forward(request, response);  
  92.     }  
  93.     /**  
  94.      * 从 HashMap中获取URL的方法  
  95.      */   
  96.     public   final  String getURL(String url) {  
  97.         return  (String) urls.get(url);  
  98.     }  
  99. }  


    代码中有详细的注释,我们说一下简单的思路。这是一个Servlet,那是肯定的,因为我们已经在web.xml中声明了。那么就要覆盖父类中的 doGet()和doPost()两个基本方法实现对Http请求的处理。但是这里我们也覆盖了init()方法用来初始化一些东西。可以看出是从 action.properties中加载配置信息,那么这个文件中有什么呢?很简单,就是action的名和类全名,如下:

Java代码  收藏代码
  1. base=mvc.action.BaseAction  
  2. default =mvc.action.DefaultAction  


    读取出这两个信息后,使用反射生成Action的实例并保存到一个HashMap中。这样就是以名/值对方式存在的了。下面就是获取 urls.properties中信息了,这里面记录了跳转的地址信息,是V层的实现。如下:

Java代码  收藏代码
  1. index=index.jsp  
  2. frameerror=frameerror.jsp  


    init()方法解释完后,我们看看具体的servlet处理方法processRequest()。首先获取到请求的URI,然后解析这个URI看看其具体格式。分为有!号的请求和没有!号的请求,这里就是模拟webwork的实现。创建两个String遍历存放handler和method,然后匹配 URI解析到的内容。进而使用反射机制获取具体的Action实例和方法。最后判断跳转到路径,然后使用 request.getRequestDispatcher().forward()方法进行跳转,那么流程处理就完成了。至此控制器C的原理就说完了。
    模型M就是配置的Action类,我们看一看默认Action的写法:

Java代码  收藏代码
  1. package  mvc.action;  
  2. import  javax.servlet.http.HttpServletRequest;  
  3. import  javax.servlet.http.HttpServletResponse;  
  4. public   class  DefaultAction {  
  5.   
  6.     public  String execute(HttpServletRequest request,  
  7.             HttpServletResponse response) {  
  8.         request.setAttribute("msg" "未定义操作" );  
  9.         return   "error" ;  
  10.     }  
  11. }  


    是不是和WebWork的Action类很相似,这里还可以操作原始的request,response对象,执行效率也很高。
    其实,这也是一个小框架的简单实现,功能简单但是原理清晰,对于理解MVC模式非常有帮助。
    一家之言,仅供参考,欢迎交流。

分享到:
评论

相关推荐

    java私塾][Spring讲解+webwork2整合+webwork2整合全套

    根据提供的文件信息,我们可以推断出这是一篇关于Java私塾中的Spring框架讲解与WebWork2整合教程的文章。下面将围绕这些关键词展开详细的讲解。 ### Spring框架基础 #### Spring简介 Spring是一个开源框架,最初由...

    WebWork类型转换

    因此,当需要将请求参数赋值给Java对象中的`String`类型的属性时,WebWork会自动将字符串数组的第一个元素转换为字符串类型。 ##### 2. **基础类型(Primitives)** - **描述**:对于Java的基础类型如`int`、`...

    webwork类型转换入门一

    WebWork是一个基于Java的开源MVC(模型-视图-控制器)框架,它在早期的Web开发中被广泛使用,特别是在Struts1之后,作为替代方案出现。本篇将介绍WebWork的基础知识,特别是它的类型转换机制,这对于理解Web应用程序...

    WebWork教程

    WebWork是一个由OpenSymphony组织开发的Java Web框架,它遵循MVC(Model-View-Controller)设计模式,并且特别注重组件化以及代码重用。WebWork2.x版本的发展前身是Rickard Öberg开发的WebWork,并且已经被拆分为...

    webwork_框架文档

    每个Action对应一个URL,当用户通过浏览器发送请求时,WebWork会根据URL找到相应的Action执行。Action的执行结果通常会传递给视图层进行渲染,展示给用户。`Interceptor`是WebWork中的另一个关键概念,它允许在...

    webwork源码底层实现

    WebWork是一个古老的Java Web开发框架,它在早期的MVC(模型-视图-控制器)架构中占有重要地位,为开发者提供了丰富的功能和强大的动作映射能力。在深入理解WebWork源码之前,我们首先需要了解一些基本概念。 1. **...

    WEBWORK

    WebWork 是一个基于 Java 的开源 MVC(Model-View-Controller)框架,它在早期的 Web 应用开发中非常流行,尤其是在 Struts 1 之前。WebWork 提供了强大的动作(Action)处理、类型转换、拦截器(Interceptor)机制...

    WebWork教程开发资料

    ServletDispatcher是WebWork的调度器,负责解析请求,调用相应的Action,并将结果转发给视图。它根据URL映射规则和Action的配置来决定哪个Action应该处理当前请求。 **Action的单元测试** WebWork提供了对Action...

    webwork-1.4-src.zip_webwork_webwork s_webwork.zip_webwork1.4.zip

    WebWork 是一个基于Java的开源MVC(Model-View-Controller)框架,它主要用于构建企业级的Web应用程序。WebWork1.4是该框架的一个较早版本,它为开发者提供了强大的功能,包括动作映射、数据绑定、异常处理、国际化...

    webwork的jar包

    WebWork 是一个基于Java的MVC(模型-视图-控制器)框架,它在Web应用程序开发中被广泛使用。WebWork 1 和 WebWork 2 都是该框架的不同版本,每个版本都有其特性和改进。 WebWork 1 是早期的版本,提供了基础的MVC...

    WebWork_开发指南

    - **WebWork**:WebWork 是一款用于构建企业级 Java Web 应用程序的框架,它以模型-视图-控制器(MVC)架构为基础,为开发者提供了一种更加灵活的方式来处理用户的请求。随着版本的演进,WebWork 框架逐渐成熟和完善...

    WebWork2.0讲解说明

    WebWork2.0是一款基于Java的企业级Web应用框架,它为开发者提供了强大的MVC(Model-View-Controller)架构支持,旨在简化Web应用程序的开发流程,提高代码的可维护性和可扩展性。本讲解将围绕WebWork2.0的核心概念、...

    webwork2开发指南

    WebWork2是一款基于Java的MVC(Model-View-Controller)框架,用于构建Web应用程序。在Web开发领域,它提供了一种结构化和模块化的开发方式,帮助开发者更高效地组织代码并实现业务逻辑。本指南将深入探讨WebWork2的...

    spring与webwork框架集成

    WebWork2.1 与 Spring 框架的集成是一个常见的技术实践,目的是利用 Spring 提供的依赖注入(DI)和面向切面编程(AOP)能力,以及 WebWork 的优秀动作层管理,来构建更加灵活和解耦的Java Web应用。在集成过程中,...

    webwork

    WebWork 是一个基于Java的开源MVC(Model-View-Controller)框架,它在早期的Web开发中被广泛使用,特别是在构建企业级应用时。WebWork 提供了一种灵活、可扩展的方式来组织和管理Web应用程序的逻辑,使得开发者能够...

    webwork详细讲解.doc

    1. **下载WebWork**:访问[WebWork官方网站](https://webwork.dev.java.net/servlets/ProjectDocumentList)下载最新的WebWork压缩包,并进行解压。 2. **解压文件**:解压后的目录包含必要的文件和目录,例如`...

    jvc.rar_java jvc_jvc_spring webwork_webwork

    Java JVC(Java Virtual Controller)框架是一个基于Java的控制层框架,设计灵感来源于Struts、Spring和WebWork等成熟的MVC(Model-View-Controller)架构。JVC旨在简化Web应用的开发流程,提供更好的可维护性和可...

    webwork2.1.7

    WebWork 2.1.7 是一个古老的Java Web框架,由Apache软件基金会开发,它在Struts的基础上进行了改进,提供了更强大的MVC(Model-View-Controller)架构支持。这个框架的主要目标是简化Web应用程序的开发,提高代码的...

    webwork 入门学习

    WebWork 是一款基于Java的轻量级Web应用框架,它为开发者提供了强大的MVC(Model-View-Controller)架构支持,使得开发Web应用程序变得更加高效和简单。本篇将围绕"WebWork入门学习"这一主题,深入讲解WebWork的核心...

    webwork.pdf

    WebWork 2.0与Spring框架的集成是另一个重要的方面,Spring作为Java领域最流行的依赖注入框架之一,其与WebWork的结合能够进一步增强应用的模块化和灵活性。通过Spring的依赖注入功能,可以更方便地管理和配置...

Global site tag (gtag.js) - Google Analytics