从0开始写JavaWeb框架系列(7)从0开始写SamrtFrameWork:核心控制器的编写

这一生的挚爱 提交于 2019-12-02 04:03:53

一、编写前端核心请求转发器( 基于Servlet3.0以上版本 )
    1.1、从HttpServletRequest对象中获取请求方法和请求路径,通过ControllerHelper#getHandler方法来获取Handler对象。
    1.2、当拿到Handler对象之后,我们可以方便的获取Controller的Class类,进而通过BeanHelper.getBean方法来获取Controller实例对象( 为了后续通过传入实例对象来调用响应的方法 )。
    1.3、接下来可以从HttpServletRequest对象中获取所有请求参数,并将其初始化到一个Param.java的对象中。

package org.smart4j.framework.bean;

import java.util.Map;

import org.smart4j.framework.util.CastUtil;

/**
 * 请求参数对象
 * @author Admin
 *
 */
public class Param {

	/**
	 * 所有请求参数的key,Value
	 */
	private Map<String,Object> paramMap;

	public Param(Map<String, Object> paramMap) {
		this.paramMap = paramMap;
	}
	
	/**
	 * 根据参数名获取long类型参数值
	 * @param name
	 * @return
	 */
	public long getLong(String name){
		return CastUtil.castLong(paramMap.get(name));
	}
	
	
	public Map<String,Object> getMap(){
		return paramMap;
	}

	
	
}


    1.4、在Param类中,会有一系列get方法,可以通过参数名获取指定类型的参数值,也可以获取所有参数的Map结构。


    1.5、.可以从Handler对象中获取Action方法的返回值,该返回值可能有两种情况:
        1.5.1、若返回值是View类型的视图对象,则返回一个jsp页面。
        1.5.2、若返回值是一个Data类型的对象,则返回一个json数据。
        1.5.3、我们需要根据以上两种情况来判断Action的返回值,并做不同处理。
        1.5.4、编写View类(添加模型数据)
        1.5.5、编写Data类(Data类封装了一个Object类型数据模型,框架会将改对象写入HttpServletResponse对象中,直接输出到浏览器)

package org.smart4j.framework.bean;

import java.util.HashMap;
import java.util.Map;

/**
 * 返回视图的对象
 * @author TS
 *
 */
public class View {
	
	/**
	 * 返回视图路径
	 */
	private String path;
	
	
	/**
	 * model数据 
	 */
	public Map<String,Object> model;
	
	
	public View(String path){
		this.path = path;
		model = new HashMap<String,Object>();
	}
	
	/**
	 * 添加模型数据
	 * @param key
	 * @param value
	 * @return
	 */
	public View addModel(String key,Object value){
		model.put(key, value);
		return this;
	}
	
	public String getPath(){
		return path;
	}
	
	public Map<String,Object> getModel(){
		return model;
	}

}
package org.smart4j.framework.bean;
/**
 * 返回数据对象
 * @author TS
 *
 */
public class Data {
	

	/**
	 * 模型数据
	 */
	private Object model;
	
	public Data(Object model){
		this.model = model;
	}

	public Object getModel() {
		return model;
	}

	
}


    6.编写MVC中最核心的DispatcherServlet(控制器)类。

package org.smart4j.framework;

import java.io.IOException;
import java.io.PrintWriter;
import java.lang.reflect.Method;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;

import javax.servlet.ServletConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRegistration;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.smart4j.framework.bean.Data;
import org.smart4j.framework.bean.Handler;
import org.smart4j.framework.bean.Param;
import org.smart4j.framework.bean.View;
import org.smart4j.framework.helper.BeanHelper;
import org.smart4j.framework.helper.ConfigHelper;
import org.smart4j.framework.helper.ControllerHelper;
import org.smart4j.framework.helper.HelperLoader;
import org.smart4j.framework.util.ArrayUtil;
import org.smart4j.framework.util.CodecUtil;
import org.smart4j.framework.util.JsonUtil;
import org.smart4j.framework.util.ReflectionUtil;
import org.smart4j.framework.util.StreamUtil;
import org.smart4j.framework.util.StringUtil;


/**
 * 请求转发总控制器
 * @author TS
 *
 */
@WebServlet(urlPatterns="/*",loadOnStartup = 0)
public class DispatcherServlet extends HttpServlet {

	private static final long serialVersionUID = 1L;

	public DispatcherServlet() {}


	/**
	 * 初始化
	 */
	@Override
	public void init(ServletConfig servletConfig) throws ServletException {
		//初始化Helper类:加载一系列初始化配置
		HelperLoader.init();
		//获取ServletContext上下文对象(用于注册Servlet)
		ServletContext servletContext = servletConfig.getServletContext();
		//TODO:注册处理jsp的Servlet(这个暂时还不太理解)
		ServletRegistration jspServlet = servletContext.getServletRegistration("jsp");
		jspServlet.addMapping(ConfigHelper.getAppJspPath() + "*");
		//TODO:注册处理静态资源的默认Servlet
		ServletRegistration defaultServlet = servletContext.getServletRegistration("default");
		defaultServlet.addMapping(ConfigHelper.getAppAssetPath() + "*");

	}

	@Override
	protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		//1.获取请求方法和路径
		String requestMethod = request.getMethod().toLowerCase();
		String requestPath = request.getPathInfo();
		//2.获取Action处理器Handler
		Handler handler = ControllerHelper.getHandler(requestMethod, requestPath);
		if(handler != null){
			//3.通过handler对象获取对应的Controller类和Controller实例
			Class<?> controllerClass = handler.getControllerClass();
			Object controllerBean = BeanHelper.getBean(controllerClass);
			//创建请求参数对象
			Map<String,Object> paramMap = new HashMap<String,Object>();
			//获取request请求的所有数据的key
			Enumeration<String> paramsNames = request.getParameterNames();
			while ( paramsNames.hasMoreElements() ) {
				String paramName = paramsNames.nextElement();	//请求的key
				String paramValue = request.getParameter(paramName);	//请求的Value
				//放入paramMap
				paramMap.put(paramName, paramValue);
			}
			String body = CodecUtil.decodeURL(StreamUtil.getString(request.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) && array.length == 2){
							String paramName = array[0];
							String paramValue = array[1];
							paramMap.put(paramName, paramValue);
						}
					}
				}
			}

			Param param = new Param(paramMap);

			//调用Action方法
			Method actionMethod = handler.getActionMethod();
			Object result = ReflectionUtil.invokeMethod(controllerBean,actionMethod,param);
			//处理Action方法返回值
			if(result instanceof View){
				//返回jsp页面
				View view = (View) result;
				String path = view.getPath();		//获取返回的路径
				if(StringUtil.isNotEmpty(path)){
					if(path.startsWith("/")){
						response.sendRedirect(request.getContextPath() + path);
					}else{
						Map<String,Object> model = view.getModel();
						for (Map.Entry<String, Object> entry : model.entrySet()) {		//遍历model
							request.setAttribute(entry.getKey(), entry.getValue());
						}
						request.getRequestDispatcher(ConfigHelper.getAppBasePackage() + path).forward(request, response);
					}
				}
			}else if(result instanceof Data){
				Data data = (Data) result;
				Object model = data.getModel();
				if( model!=null ){
					response.setContentType("application/json");
					response.setCharacterEncoding("UTF-8");
					PrintWriter write = response.getWriter();
					String json = JsonUtil.toJson(model);
					write.write(json);
					write.flush();
					write.close();
				}
			}
		}
	}
}


---------------------------------------summarize(总结):至此,一个简单的MVC框架开发完毕了,通过DispatcherServlet来处理所有的请求---------------------------------------

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!