從0開始寫JavaWeb框架系列(7)從0開始寫SamrtFrameWork:核心控制器的編寫

1、編寫前端核心請求轉發器( 基於Servlet3.0以上版本 )
    1.一、從HttpServletRequest對象中獲取請求方法和請求路徑,經過ControllerHelper#getHandler方法來獲取Handler對象。
    1.二、當拿到Handler對象以後,咱們能夠方便的獲取Controller的Class類,進而經過BeanHelper.getBean方法來獲取Controller實例對象( 爲了後續經過傳入實例對象來調用響應的方法 )。
    1.三、接下來能夠從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.四、在Param類中,會有一系列get方法,能夠經過參數名獲取指定類型的參數值,也能夠獲取全部參數的Map結構。java


    1.五、.能夠從Handler對象中獲取Action方法的返回值,該返回值可能有兩種狀況:
        1.5.一、若返回值是View類型的視圖對象,則返回一個jsp頁面。
        1.5.二、若返回值是一個Data類型的對象,則返回一個json數據。
        1.5.三、咱們須要根據以上兩種狀況來判斷Action的返回值,並作不一樣處理。
        1.5.四、編寫View類(添加模型數據)
        1.5.五、編寫Data類(Data類封裝了一個Object類型數據模型,框架會將改對象寫入HttpServletResponse對象中,直接輸出到瀏覽器)json

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來處理全部的請求---------------------------------------app

相關文章
相關標籤/搜索