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