接上一个文档
配置信息注解部分:
根据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*/@Overridepublic 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;}//遍历类中所有方法,找到@RequestMappingMethod[] 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);}}}}}@Overrideprotected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {//请求映射,根据请求调用controller的具体方法//获得请求 /test1//根据请求找到对应的mappinginfo 映射信息//获得参数--》处理参数--》调用mappinginfo中的对象的方法,传递参数}}
**
