作者:小峰哥2502868817 | 来源:互联网 | 2024-12-18 10:06
本文探讨如何利用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框架的内部机制非常有帮助。