热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

使用Java反射机制模拟WebworkURL解析

本文探讨如何利用Java反射技术来模拟Webwork框架中的URL解析过程。通过这一实践,读者可以更好地理解Webwork及其后续版本Struts2的工作原理,尤其是它们在MVC架构下的角色。
Webwork是一个高效且灵活的Web应用框架,Struts2基于此框架进一步发展,已成为许多开发者在构建MVC模式Web应用时的首选。熟悉Webwork的开发者可以轻松过渡到Struts2。

本文将通过Java反射技术来模拟Webwork的URL解析过程,尽管这种方法可能不如原生实现那样完善,但它有助于深入理解框架的核心机制。

### Webwork URL解析概述

Webwork默认处理以`.action`结尾的请求,这部分工作由Servlet容器完成,而非框架自身。在`web.xml`中配置``和``时指定``即可实现这一点。为了简化示例,我们将使用Servlet来模拟这一过程,并使用属性配置文件(.properties)进行配置。

当用户提交一个如`xx.action`的请求时,如果``配置中的``元素没有指定`method`属性,则会调用对应的类中的`execute()`方法;如果有`method`属性,则调用指定的方法。例如,对于`xx!yy.action`这样的请求,会在``元素中找到`class`属性指向的类,并在该类中执行`yy()`方法来响应请求。Webwork的Action可以是一个简单的POJO,方法的返回值通常为字符串,用于与``元素中的`name`属性匹配,从而决定跳转的目标地址。

### 示例项目配置

创建一个名为MVC的Web项目,其`web.xml`配置如下所示:

```xml

characterEncoding
mvc.filters.CharacterEncodingFilter

encoding
UTF-8



characterEncoding
FrontController


FrontController
mvc.ctl.FrontController


FrontController
*.action

```

上述配置确保所有以`.action`结尾的请求都将被`FrontController`处理。接下来,我们设计并实现这个核心控制器,以实现MVC模式。

### 核心控制器实现

以下是`FrontController`的实现代码:

```java
package mvc.ctl;

import java.io.IOException;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
import java.util.ResourceBundle;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class FrontController extends HttpServlet {
private Map actiOns= new HashMap<>();
private Map urls = new HashMap<>();

@Override
public void init() throws ServletException {
// 读取action配置文件
ResourceBundle rb = ResourceBundle.getBundle("actions");
for (String key : rb.keySet()) {
try {
Object o = Class.forName(rb.getString(key)).newInstance();
actions.put(key, o);
} catch (Exception e) {
e.printStackTrace();
}
}

// 读取目的地址配置文件
ResourceBundle url = ResourceBundle.getBundle("urls");
for (String key : url.keySet()) {
urls.put(key, url.getString(key));
}
}

protected void processRequest(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String requestUri = request.getRequestURI();
String actiOnUrl= requestUri.substring(requestUri.lastIndexOf('/') + 1, requestUri.length());
actiOnUrl= actionUrl.substring(0, actionUrl.indexOf(".action"));

String action = "";
String method = "";

if (actionUrl.contains("!")) {
action = actionUrl.split("!")[0];
method = actionUrl.split("!")[1];
} else {
action = actionUrl;
method = "execute";
}

Object handler = actions.get(action);
if (handler == null) {
handler = actions.get("default");
method = "execute";
}

try {
Method executor = handler.getClass().getMethod(method, HttpServletRequest.class, HttpServletResponse.class);
String toJump = (String) executor.invoke(handler, request, response);
request.getRequestDispatcher(getURL(toJump)).forward(request, response);
} catch (Exception e) {
e.printStackTrace();
request.getRequestDispatcher(getURL("frameerror")).forward(request, response);
}
}

private String getURL(String url) {
return urls.get(url);
}
}
```

### 配置文件

`actions.properties`文件配置了Action的名称和类的全限定名:

```properties
base=mvc.action.BaseAction
default=mvc.action.DefaultAction
```

`urls.properties`文件配置了跳转的地址:

```properties
index=index.jsp
frameerror=frameerror.jsp
```

### 默认Action实现

下面是一个默认Action的示例实现:

```java
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";
}
}
```

通过上述实现,我们可以看到,虽然这是一个简单的框架模拟,但其结构清晰,易于理解,对于学习MVC模式和Web框架的内部机制非常有帮助。
推荐阅读
author-avatar
小峰哥2502868817
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有