您的位置:首页 > 编程语言 > Java开发

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

2016-05-27 00:00 369 查看
摘要: 本文章来自基于Java语言的SmartFramework开源作者黄勇的架构探险一书 ( 感谢勇哥 )。希望勇哥可以看到我的博文!

一、编写前端核心请求转发器( 基于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
7fe0
;
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来处理所有的请求---------------------------------------
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: