`
sarin
  • 浏览: 1753859 次
  • 性别: Icon_minigender_1
  • 来自: 大连
博客专栏
E3b14d1f-4cc5-37dd-b820-b6af951740bc
Spring数据库访问系列...
浏览量:173354
C2083dc5-6474-39e2-993e-263652d27795
Android学习笔记
浏览量:367646
5f40a095-b33c-3e8e-8891-606fcf3b8d27
iBatis开发详解
浏览量:188923
B272a31d-e7bd-3eff-8cc4-c0624ee75fee
Objective-C学习...
浏览量:99551
社区版块
存档分类
最新评论

Java反射模拟Webwork的URL解析

阅读更多
    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中配置上一个核心控制器和字符过滤器,很简单,如下进行即可。
	<filter>
		<filter-name>characterEncoding</filter-name>
	<filter-class>mvc.filters.CharacterEncodingFilter</filter-class>
		<init-param>
			<param-name>encoding</param-name>
			<param-value>UTF-8</param-value>
		</init-param>
	</filter>
	<filter-mapping>
		<filter-name>characterEncoding</filter-name>
		<servlet-name>FrontController</servlet-name>
	</filter-mapping>
	<servlet>
		<servlet-name>FrontController</servlet-name>
		<servlet-class>mvc.ctl.FrontController</servlet-class>
	</servlet>
	<servlet-mapping>
		<servlet-name>FrontController</servlet-name>
		<url-pattern>*.action</url-pattern>
	</servlet-mapping>

    这样所有已action为服务请求名的请求都被核心控制器FrontController处理了,那么只要设计好这个核心控制器就行了,那么我们就用这个核心控制器来实现MVC模式。
package mvc.ctl;
import java.io.*;
import java.util.*;
import java.lang.reflect.*;
import javax.servlet.*;
import javax.servlet.http.*;
public class FrontController extends HttpServlet {
	private Map actions = new HashMap();// 装资源文件中配置的action
	public Map urls = new HashMap();// 装资源文件配置的url
	@Override
	public void init() throws ServletException {
		// 读取action配置文件
		ResourceBundle rb = ResourceBundle.getBundle("actions");
		Enumeration keys = rb.getKeys();
		while (keys.hasMoreElements()) {
			String key = (String) keys.nextElement();
			String value = rb.getString(key);
			try {
				// 根据资源文件的value反射获取action对象并装入HashMap
				Object o = Class.forName(value).newInstance();
				actions.put(key, o);
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		// 读取目的地址配置文件
		ResourceBundle url = ResourceBundle.getBundle("urls");
		keys = url.getKeys();
		while (keys.hasMoreElements()) {
			String key = (String) keys.nextElement();
			String value = url.getString(key);
			urls.put(key, value);
		}
	}
	public void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		processRequest(request, response);
	}
	public void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		processRequest(request, response);
	}
	public void processRequest(HttpServletRequest request,
			HttpServletResponse response) throws ServletException, IOException {
		// 从请求中获取URI
		String requestUri = request.getRequestURI();
		// 根据最后一个/截取请求地址(包含.action)
		String actionurl = requestUri.substring(
				requestUri.lastIndexOf('/') + 1, requestUri.length());
		// 截取.action前的有效数据
		actionurl = actionurl.substring(0, actionurl.indexOf(".action"));
		// 创建保存处理类和方法的变量
		String action = "";
		String method = "";
		if (actionurl.indexOf("!") >= 0) {// 有!号的请求这样处理
			action = actionurl.substring(0, actionurl.indexOf("!"));
			method = actionurl.substring(actionurl.indexOf("!") + 1);
		} else {// 没有!号时则默认执行execute()方法
			action = actionurl;
			method = "execute";
		}
		// 根据截取的action名获得存放在HashMap中的action对象
		Object handler = null;
		handler = actions.get(action);
		if (handler == null) {// 没有找到时默认执行default配置的action
			handler = actions.get("default");
			method = "execute";
		}
		// 存在时,获取Class实例
		Class handlerClass = handler.getClass();
		Method executor = null;
		// 设置请求处理结束的派发地址
		String toJump = "index";
		try {
			// 反射获取执行方法,由于是Servlet,所以参数是HttpServletRequest和HttpServletResponse
			executor = handlerClass.getMethod(method, new Class[] {
					HttpServletRequest.class, HttpServletResponse.class });
		} catch (Exception e) {
			e.printStackTrace();
			toJump = "frameerror";
		}
		try {
			// 利用反射机制执行方法,方法调用结束,返回值都是String类型的
			toJump = (String) executor.invoke(handler, new Object[] { request,
					response });
		} catch (Exception e) {
			e.printStackTrace();
			toJump = "frameerror";
		}
		// 转发处理结束以后的地址
		request.getRequestDispatcher(getURL(toJump)).forward(request, response);
	}
	/**
	 * 从HashMap中获取URL的方法
	 */
	public final String getURL(String url) {
		return (String) urls.get(url);
	}
}

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

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

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

	public String execute(HttpServletRequest request,
			HttpServletResponse response) {
		request.setAttribute("msg", "未定义操作");
		return "error";
	}
}

    是不是和WebWork的Action类很相似,这里还可以操作原始的request,response对象,执行效率也很高。
    其实,这也是一个小框架的简单实现,功能简单但是原理清晰,对于理解MVC模式非常有帮助。
    一家之言,仅供参考,欢迎交流。
  • 大小: 21.2 KB
4
2
分享到:
评论
4 楼 sarin 2010-10-14  
kongzhizhen 写道
RESTFUL style的呢?怎么模拟?

不太明白什么意思
3 楼 kongzhizhen 2010-10-14  
RESTFUL style的呢?怎么模拟?
2 楼 sarin 2010-06-16  
mercyblitz 写道
思路不错,但是这个程序有问题。

# private Map actions = new HashMap();// 装资源文件中配置的action 
#     public Map urls = new HashMap();// 装资源文件配置的url 

在processRequest实现方法调用它们的,注意线程安全。

恩,就是说明问题用的,如果真要扩展框架,那是要考虑很多问题的。
1 楼 mercyblitz 2010-06-15  
思路不错,但是这个程序有问题。

# private Map actions = new HashMap();// 装资源文件中配置的action 
#     public Map urls = new HashMap();// 装资源文件配置的url 

在processRequest实现方法调用它们的,注意线程安全。

相关推荐

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

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

    WebWork教程

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

    webwork源码底层实现

    2. **Action Mapping**:WebWork的核心是Action Mapping,它定义了URL与特定Action类之间的映射关系。`webwork-default.xml`是配置文件,其中包含了这些映射信息,允许开发者自定义请求路径和处理方法。 3. **请求...

    WebWork教程开发资料

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

    webwork的jar包

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

    WEBWORK

    在提供的示例中,`&lt;filter&gt;` 和 `&lt;filter-mapping&gt;` 元素定义了名为 `webwork` 的过滤器,它将所有以 `/` 开头的 URL 映射到 `FilterDispatcher` 类。这使得 WebWork 能够处理所有传入的请求。 2. **Taglib** 配置...

    webwork_框架文档

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

    webwork2开发指南

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

    spring与webwork框架集成

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

    WebWork2.0讲解说明

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

    webwork

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

    jvc.rar_java jvc_jvc_spring webwork_webwork

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

    webwork.pdf

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

    webwork,tomcat源码

    WebWork和Tomcat是两个在Java Web开发中非常重要的组件。WebWork是一个基于Action的MVC(模型-视图-控制器)框架,它为开发者提供了强大的动态Web应用程序开发能力,而Tomcat则是一个流行的开源Java Servlet容器,它...

    webwork2.1.7

    1. **Action映射**:WebWork通过XML配置文件定义了Action的映射,使得URL可以直接对应到业务逻辑的方法,增强了路由的灵活性。 2. **类型安全的参数绑定**:WebWork支持将HTTP请求参数自动绑定到Action类的属性上,...

    webwork中文帮助文档

    WebWork是一个开源的Java Web应用程序框架,它提供了一种基于MVC(Model-View-Controller)模式的开发方式,使得开发者能够更有效地构建动态、交互式的Web应用。本中文帮助文档旨在为使用WebWork框架的开发者提供...

    webwork 入门学习

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

    Webwork2开发指南

    Webwork2 是一个基于Java的开源MVC(Model-View-Controller)框架,专门用于构建动态、交互式的Web应用程序。它提供了强大的数据绑定、动作控制、异常处理以及国际化等功能,使得开发者能够更高效地进行Web应用的...

    webwork中文参考手册

    2. **动作映射(Action Mapping)**:WebWork通过配置文件定义了URL到具体动作类的映射,这样可以根据不同的URL调用不同的业务处理方法。 3. **拦截器(Interceptor)**:类似于AOP(面向切面编程),WebWork允许...

Global site tag (gtag.js) - Google Analytics