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