一、编写前端核心请求转发器( 基于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来处理所有的请求---------------------------------------
来源:oschina
链接:https://my.oschina.net/u/2453485/blog/682272