MVC框架的实现原理,和一个简单demo的实现

相信从事web开发的java开发人员都用过mvc框架如struts、springMVC等。你是否好奇他们的实现原理呢?大家也许知道他们的原理,并也写过类似的mvc框架,如果你已经懂其原理可以直接pass掉这篇文章,如果你还未了解又有兴趣的话,不妨进来看看。接下来进入正文。

我的示例访问路径为:   http://localhost:8080/StrutsDemo/hello/sayHello.do

1.不管是struts还是springMVC他们最基本的实现原理都是抓取每一次请求的9大对象,将其赋值到自定义类中,再在自定义类中获取相应的参数和输出开发人员欲输出的信息。

以下是我的自定义类

/**
 * 自定义类,功能类似于servlet,用于抓取java web 9大对象,
 * 此处示例只抓取了request和response对象,然后通过request和response对象
 * 作相应的页面跳转、响应json、传递参数等操作。
 * 
 * !!!!!设置页面跳转参数等这些方法此处没有实现,实现方式和传统的serlvet一样。
 * @author gd_xbb
 *
 */
public abstract class Controller {
private HttpServletRequest request;
private HttpServletResponse response;


/**
* 响应json
* @param target
*/
public void responseJson(Object target){
try {
PrintWriter out = getResponse().getWriter();
out.print(JSON.toJSONString(target));
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}

/**
* 客户端跳转
* @param path
*/
public void redirect(String path){
try {
response.sendRedirect(request.getContextPath() + path);
} catch (IOException e) {
e.printStackTrace();
}
}

/**
* 获取request对象
* @return
*/
public HttpServletRequest getRequest() {
return request;
}


/**
* 设置request对象
* @param request
*/
public void setRequest(HttpServletRequest request) {
this.request = request;
}


/**
* 获取response对象
* @return
*/
public HttpServletResponse getResponse() {
return response;
}


/**
* 设置response对象
* @param response
*/
public void setResponse(HttpServletResponse response) {
this.response = response;
}

}

2.接下来我们要定义自己的路由信息以下是我的实现:

public class ControllerConfig {
public static Map<String, Class<? extends Controller>> router = new HashMap<String, Class<? extends Controller>>();

static {
router.put("hello", HelloController.class);
}
}

这路由的定义主要是为了一会儿反射生成Controller对象

3.实现我们自已的mvc框架的过滤器或者servlet作为框架的统一入口。我用的是过滤器。以下是我的代码:

/**
 * 仿struts过滤器,统一入口
 * @author gd_xbb
 *
 */
public class StrutsFilter implements Filter{


@Override
public void destroy() {

}


@Override
public void doFilter(ServletRequest svltReq, ServletResponse svltRes, FilterChain fltChain)
throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) svltReq;
HttpServletResponse response = (HttpServletResponse) svltRes;
String requestUrl = request.getRequestURI();
String[] reflectInfo = getReflectInfo(requestUrl, request.getContextPath());
String classKey = reflectInfo[0];
String methodName = reflectInfo[1];
executeTarget(classKey, methodName, request, response);
return;
}

/**
* 执行目标方法
* @param classKey路由中Controller对应的Key
* @param methodName对应请求的Controller的方法
* @param requestrequest对象
* @param responseresponse对象
*/
private void executeTarget(String classKey, String methodName, HttpServletRequest request, HttpServletResponse response){
try {
Controller controller= ControllerConfig.router.get(classKey).newInstance();
controller.setRequest(request); controller.setResponse(response);
Method method = controller.getClass().getMethod(methodName);
method.invoke(controller);
} catch (Exception e) {
e.printStackTrace();
}
}

/**
* 得到反射的信息
* @param requestUrl请求路径 
* @param contextPathweb项目的contextPath
* @return
*/
private String[] getReflectInfo(String requestUrl, String contextPath){
int contextPathLastIndex = requestUrl.indexOf(contextPath) + contextPath.length();
String reflectInfo = requestUrl.substring(contextPathLastIndex);
reflectInfo = reflectInfo.replaceFirst(".do", "").replaceFirst("/", "");
String methodName = reflectInfo.substring(reflectInfo.lastIndexOf("/") + 1);
String classKey = reflectInfo.substring(0, reflectInfo.lastIndexOf("/"));
String[] reflectArray = {classKey, methodName};
return reflectArray;
}


@Override
public void init(FilterConfig arg0) throws ServletException {

}


}

在web.xml中配置好我们的filter

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
id="WebApp_ID" version="3.0">
<display-name>StrutsDemo</display-name>
<filter>
<filter-name>struts</filter-name>
<filter-class>com.gzykdx.strutsDemo.interceptor.StrutsFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>struts</filter-name>
<url-pattern>*.do</url-pattern>
</filter-mapping>

</web-app>

以上代码的核心思想:通过路径中的hello查询路由反射生成HelloController对象,并调用HelloController中的sayHello方法

4.实现我们自己的Controller类。代码:

public class HelloController extends Controller {
public void sayHello() throws IOException{
responseJson("Hello world");
}
}

以上就是一个仿mvc框架的核心实现。  本人因为技术和时间原因写得不好,请各位大神留情。^*(- -)*^

以下是源代码下载地址:https://github.com/xbb0220/HowStrutsImplemented

demo的访问地址: http://localhost:8080/StrutsDemo/hello/sayHello.do

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值