从零开始写javaweb框架 (2)

  在本节实现网页请求框架实现的整个过程,在本节中我们就能完美理解Spring到底为我们做了多少事情。
  首先来讲一下在JAVAWEB框架中最重要的类DispatcherServlet,即请求转发器。Spring框架是在Servlet基础上进行改进的,因此我们的请求转发类也同样要继承HttpServlet类,重新父类中的初始化方法,完成对上一节讲述的Helper类进行初始化、获取ServletContext对象、注册处理JSP的Servlet、jsp映射路径、注册处理静态资源的默认Servlet等

@Override
public void init(ServletConfig servletConfig) throws ServletException {
	//初始化相关Helper类
	HelperLoader.init();
	//获取ServletContext对象(用于注册Servlet)
	ServletContext servletContext = servletConfig.getServletContext();
	//注册处理JSP的Servlet
	ServletRegistration jspServlet = servletContext.getServletRegistration("jsp");
	//jsp映射路径
	jspServlet.addMapping(ConfigHelper.getAppJspPath()+"*");
	//注册处理静态资源的默认Servlet
	ServletRegistration defaultServlet = servletContext.getServletRegistration("default");
	defaultServlet.addMapping(ConfigHelper.getAppJspPath()+"*");
}

  第二步就是重写父类中service方法,这个就是我们框架中最重要的方法了。

  1. 获取请求方法与请求路径
String requestMethod = req.getMethod().toLowerCase();
String requestPath = req.getPathInfo();
  1. 获取Action处理器
Handler handler = ControllerHelper.getHandler(requestMethod, requestPath);
public static Handler getHandler(String requestMethod,String requestPath){
	Request request = new Request(requestMethod,requestPath);
	return ACTION_MAP.get(request);
}

从ControllerHelper中获取相对应的处理方法。在这里有个特别需要注意的点:
  在获取处理方法的过程中将请求方法和请求路径封装在Request请求中,因此我们不能直接从ACTION_MAP中获取,因为ACTION_MAP是hashMap结构,判断是否相等时对比的是地址,因此我们需要重写Request的hashcode和equals方法。

3.获取Controller类及其Bean实例

4.创建请求参数对象,参数对象分为两个部分post提交的参数、Url中携带的参数

//post提交的参数
Enumeration<String> parameterNames = req.getParameterNames();
while(parameterNames.hasMoreElements()){
	String paramName = parameterNames.nextElement();
	String paramValue = req.getParameter(paramName);
	paramMap.put(paramName, paramValue);
}
/从url中获取参数,&分割
String body = CodecUtil.decodeURL(StreamUtil.getString(req.getInputStream()));
    if(StringUtil.isNotEmpty(body)){
	String[] params = StringUtil.splitString(body, "&");
	if(ArrayUtil.isNotEmpty(params)){
		for(String param : params){
			String[] array = StringUtil.splitString(param, "=");
			if(ArrayUtil.isNotEmpty(array)){
				String paramName = array[0];
				String paramValue = array[1];
				paramMap.put(paramName, paramValue);
			}
		}
	}
}

5.调用Action方法
6.处理Action返回值,判断返回值是视图还是JSON数据

if(result instanceof View){
	//返回JSP
	View view = (View) result;
	String path = view.getPath();
	if(StringUtil.isNotEmpty(path)){
		if(path.startsWith("/")){
			res.sendRedirect(req.getContextPath()+path);
		}else{
			Map<String, Object> model = view.getModel();
			for(Map.Entry<String, Object>entry:model.entrySet()){
				req.setAttribute(entry.getKey(), entry.getValue());
			}
			req.getRequestDispatcher(ConfigHelper.getAppJspPath()+path).forward(req, res);
		}
	}
}else if(result instanceof Data){
	//返回JSON数据
	Data data = (Data) result;
	Object model = data.getModel();
	if(model != null){
		res.setContentType("application/json");
		res.setCharacterEncoding("UTF-8");
		PrintWriter writer = res.getWriter();
		String json = JsonUtil.toJson(model);
		writer.write(json);
		writer.flush();
		writer.close();
	}
}

如此我们就完成了最简单的JAVAWEB的框架了,目前该框架拥有依赖注入、方法层面的请求调用、注解配置等功能。下一节我们将来讲讲Spring中另一个最重要的特性--AOP。

posted @ 2017-06-10 10:13  青檬凝  阅读(756)  评论(0编辑  收藏  举报