接上一个文档
配置信息注解部分:
根据web.xml配置的包路径(com.controller)获得对应文件夹的相对路径(com/controller),通过方法获取文件夹绝对路径后,创建File对象,获取文件夹所有子内容名字,对后缀名为.class的子内容进行处理,获得类名(去掉后缀名.class)。重新包装成完整的类路径(com.controller.TestController)。反射获得类注解—》反射获得类方法—》反射获得方法注解;获得请求映射信息:①@RequestMapping(“/test”)—>path ②反射创建controller对象 ③Method
类中配置文件部分的代码详见上一文档,此处删去**
package web;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import web.annotation.Controller;
import web.annotation.RequestMapping;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class DispatcherServlet extends HttpServlet {
/*
缓存请求映射信息
key="/test1"
*/
Map<String, MappingInfo> infoMap = new HashMap<>();
/*
单实例存储controller对象
key="com.controller.TestController"
value=new Object
*/
Map<String, Object> controllerMap = new HashMap<>();
/**
* 读取各种配置信息
* (目前只有请求映射信息)
*
* @throws ServletException
*/
@Override
public void init() throws ServletException {
//目前配置信息来自于两个部分,而且两个部分都可能存在
String xmlPath = super.getInitParameter("classpath");
if (xmlPath != null && !"".equals(xmlPath)) {
//指定了配置文件,需要读取配置文件
readXml(xmlPath);
}
String packagePath = super.getInitParameter("controller-scan");
if (packagePath != null && !"".equals(packagePath)) {
//指定了包路径,需要读取包下类中的注解信息
try {
readAnnotation(packagePath);
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
}
}
}
public Object getSingleController(String className) throws ClassNotFoundException, IllegalAccessException, InstantiationException {
Object obj = controllerMap.get(getClass());
if (obj == null) {
obj = Class.forName(className).newInstance();
controllerMap.put(className, obj);
}
return obj;
}
//读取注解
public void readAnnotation(String packagePath) throws ClassNotFoundException, IllegalAccessException, InstantiationException {
//需要框架从指定的包(可能有多个)中找到请求映射的直接
String[] packagePathArray = packagePath.split(",");
for (String p : packagePathArray) {
/*
* 如果想要用过反射获得类,光有包路径还不够,还需要类名com.controller+TestController
* 想要获得类名,反射行不通,可以通过File操作获得文件夹中的文件名(去掉后缀就是类名)
*/
String path1 = p.replace(".", "/");
String realPath="";
try {
realPath = Thread.currentThread().getContextClassLoader().getResource(path1).getPath();
} catch (NullPointerException e) {
//指定的包路径有错误
System.out.println("logging : package path not found [" + realPath + "]");
//当前包不存在就不检索了
continue;
//throw new FileNotFoundException(realPath);
}
File dir = new File(realPath);
String className = "";
//获得文件夹中所有子内容名字(子文件夹,子文件)
String[] fnames = dir.list();
for (String fname : fnames) {
if (fname.endsWith(".class")) {
className = fname.replace(".class", "");
className = p + "." + className;
Class clazz = Class.forName(className);
Controller c = (Controller) clazz.getAnnotation(Controller.class);
if (c == null) {
//该类没找到@Controller注解,不需要扫描
continue;
}
//遍历类中所有方法,找到@RequestMapping
Method[] methods = clazz.getMethods();
for (Method method : methods) {
RequestMapping rm = method.getAnnotation(RequestMapping.class);
if (rm == null) {
continue;
}
String path = rm.value();
Object obj = getSingleController(className);
MappingInfo info = new MappingInfo(path, obj, method);
Object obj1=infoMap.get(path);
if(obj1!=null){
//当前映射关系已经存在
//去重 continue
//覆盖 map.put
//抛出异常 throw new Exception
}
infoMap.put(path, info);
}
}
}
}
}
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//请求映射,根据请求调用controller的具体方法
//获得请求 /test1
//根据请求找到对应的mappinginfo 映射信息
//获得参数--》处理参数--》调用mappinginfo中的对象的方法,传递参数
}
}
**