接上一个文档
    配置信息注解部分:
    根据web.xml配置的包路径(com.controller)获得对应文件夹的相对路径(com/controller),通过方法获取文件夹绝对路径后,创建File对象,获取文件夹所有子内容名字,对后缀名为.class的子内容进行处理,获得类名(去掉后缀名.class)。重新包装成完整的类路径(com.controller.TestController)。反射获得类注解—》反射获得类方法—》反射获得方法注解;获得请求映射信息:①@RequestMapping(“/test”)—>path ②反射创建controller对象 ③Method

    类中配置文件部分的代码详见上一文档,此处删去**

    1. package web;
    2. import org.dom4j.Document;
    3. import org.dom4j.Element;
    4. import org.dom4j.io.SAXReader;
    5. import web.annotation.Controller;
    6. import web.annotation.RequestMapping;
    7. import javax.servlet.ServletException;
    8. import javax.servlet.http.HttpServlet;
    9. import javax.servlet.http.HttpServletRequest;
    10. import javax.servlet.http.HttpServletResponse;
    11. import java.io.File;
    12. import java.io.FileInputStream;
    13. import java.io.IOException;
    14. import java.io.InputStream;
    15. import java.lang.reflect.Method;
    16. import java.util.HashMap;
    17. import java.util.List;
    18. import java.util.Map;
    19. public class DispatcherServlet extends HttpServlet {
    20. /*
    21. 缓存请求映射信息
    22. key="/test1"
    23. */
    24. Map<String, MappingInfo> infoMap = new HashMap<>();
    25. /*
    26. 单实例存储controller对象
    27. key="com.controller.TestController"
    28. value=new Object
    29. */
    30. Map<String, Object> controllerMap = new HashMap<>();
    31. /**
    32. * 读取各种配置信息
    33. * (目前只有请求映射信息)
    34. *
    35. * @throws ServletException
    36. */
    37. @Override
    38. public void init() throws ServletException {
    39. //目前配置信息来自于两个部分,而且两个部分都可能存在
    40. String xmlPath = super.getInitParameter("classpath");
    41. if (xmlPath != null && !"".equals(xmlPath)) {
    42. //指定了配置文件,需要读取配置文件
    43. readXml(xmlPath);
    44. }
    45. String packagePath = super.getInitParameter("controller-scan");
    46. if (packagePath != null && !"".equals(packagePath)) {
    47. //指定了包路径,需要读取包下类中的注解信息
    48. try {
    49. readAnnotation(packagePath);
    50. } catch (ClassNotFoundException e) {
    51. e.printStackTrace();
    52. } catch (IllegalAccessException e) {
    53. e.printStackTrace();
    54. } catch (InstantiationException e) {
    55. e.printStackTrace();
    56. }
    57. }
    58. }
    59. public Object getSingleController(String className) throws ClassNotFoundException, IllegalAccessException, InstantiationException {
    60. Object obj = controllerMap.get(getClass());
    61. if (obj == null) {
    62. obj = Class.forName(className).newInstance();
    63. controllerMap.put(className, obj);
    64. }
    65. return obj;
    66. }
    67. //读取注解
    68. public void readAnnotation(String packagePath) throws ClassNotFoundException, IllegalAccessException, InstantiationException {
    69. //需要框架从指定的包(可能有多个)中找到请求映射的直接
    70. String[] packagePathArray = packagePath.split(",");
    71. for (String p : packagePathArray) {
    72. /*
    73. * 如果想要用过反射获得类,光有包路径还不够,还需要类名com.controller+TestController
    74. * 想要获得类名,反射行不通,可以通过File操作获得文件夹中的文件名(去掉后缀就是类名)
    75. */
    76. String path1 = p.replace(".", "/");
    77. String realPath="";
    78. try {
    79. realPath = Thread.currentThread().getContextClassLoader().getResource(path1).getPath();
    80. } catch (NullPointerException e) {
    81. //指定的包路径有错误
    82. System.out.println("logging : package path not found [" + realPath + "]");
    83. //当前包不存在就不检索了
    84. continue;
    85. //throw new FileNotFoundException(realPath);
    86. }
    87. File dir = new File(realPath);
    88. String className = "";
    89. //获得文件夹中所有子内容名字(子文件夹,子文件)
    90. String[] fnames = dir.list();
    91. for (String fname : fnames) {
    92. if (fname.endsWith(".class")) {
    93. className = fname.replace(".class", "");
    94. className = p + "." + className;
    95. Class clazz = Class.forName(className);
    96. Controller c = (Controller) clazz.getAnnotation(Controller.class);
    97. if (c == null) {
    98. //该类没找到@Controller注解,不需要扫描
    99. continue;
    100. }
    101. //遍历类中所有方法,找到@RequestMapping
    102. Method[] methods = clazz.getMethods();
    103. for (Method method : methods) {
    104. RequestMapping rm = method.getAnnotation(RequestMapping.class);
    105. if (rm == null) {
    106. continue;
    107. }
    108. String path = rm.value();
    109. Object obj = getSingleController(className);
    110. MappingInfo info = new MappingInfo(path, obj, method);
    111. Object obj1=infoMap.get(path);
    112. if(obj1!=null){
    113. //当前映射关系已经存在
    114. //去重 continue
    115. //覆盖 map.put
    116. //抛出异常 throw new Exception
    117. }
    118. infoMap.put(path, info);
    119. }
    120. }
    121. }
    122. }
    123. }
    124. @Override
    125. protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    126. //请求映射,根据请求调用controller的具体方法
    127. //获得请求 /test1
    128. //根据请求找到对应的mappinginfo 映射信息
    129. //获得参数--》处理参数--》调用mappinginfo中的对象的方法,传递参数
    130. }
    131. }

    **