123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177 |
- package cn.nosum.framework.mvc.v1.servlet;
- import cn.nosum.framework.annotation.Autowired;
- import cn.nosum.framework.annotation.Controller;
- import cn.nosum.framework.annotation.RequestMapping;
- import cn.nosum.framework.annotation.Service;
- import javax.servlet.ServletConfig;
- 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.IOException;
- import java.io.InputStream;
- import java.lang.reflect.Field;
- import java.lang.reflect.Method;
- import java.net.URL;
- import java.util.*;
- public class DispatcherServlet extends HttpServlet {
- private Map<String, Object> mapping = new HashMap<String, Object>();
- @Override
- protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
- this.doPost(req, resp);
- }
- @Override
- protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
- try {
- doDispatch(req, resp);
- } catch (Exception e) {
- resp.getWriter().write("500 Exception " + Arrays.toString(e.getStackTrace()));
- }
- }
- /**
- * 进行URL的映射
- */
- private void doDispatch(HttpServletRequest req, HttpServletResponse resp) throws Exception {
- String url = req.getRequestURI();
- String contextPath = req.getContextPath();
- // 去除 URL 中的前缀并且将多个 / 替换为一个
- url = url.replace(contextPath, "").replaceAll("/+", "/");
- // 找不到页面
- if (!this.mapping.containsKey(url)) {
- resp.getWriter().write("404 Not Found!!");
- return;
- }
- // 根据 URL 取得对应的方法映射
- Method method = (Method) this.mapping.get(url);
- // 取得所有的参数
- Map<String, String[]> params = req.getParameterMap();
- // 调用方法
- method.invoke(this.mapping.get(method.getDeclaringClass().getName()), new Object[]{req, resp, params.get("name")[0]});
- }
- /**
- * 初始化所有的相关的类,IOC容器、servletBean
- */
- @Override
- public void init(ServletConfig config) throws ServletException {
- InputStream is = null;
- try {
- Properties configContext = new Properties();
- // 取得 application.properties
- is = this.getClass().getClassLoader().getResourceAsStream(config.getInitParameter("contextConfigLocation"));
- configContext.load(is);
- // 获取定义的扫描包路径
- String scanPackage = configContext.getProperty("scanPackage");
- // 将指定路径中的类名进行缓存
- doScanner(scanPackage);
- // 初始化 IOC 容器
- for (String className : mapping.keySet()) {
- if (!className.contains(".")) {
- continue;
- }
- Class<?> clazz = Class.forName(className);
- if (clazz.isAnnotationPresent(Controller.class)) {
- // 保存 Controller 实例
- mapping.put(className, clazz.getDeclaredConstructor().newInstance());
- String baseUrl = "";
- if (clazz.isAnnotationPresent(RequestMapping.class)) {
- RequestMapping requestMapping = clazz.getAnnotation(RequestMapping.class);
- baseUrl = requestMapping.value();
- }
- Method[] methods = clazz.getMethods();
- for (Method method : methods) {
- if (!method.isAnnotationPresent(RequestMapping.class)) {
- continue;
- }
- RequestMapping requestMapping = method.getAnnotation(RequestMapping.class);
- String url = (baseUrl + "/" + requestMapping.value()).replaceAll("/+", "/");
- // 保存 URL 对应的方法引用
- mapping.put(url, method);
- System.out.println("Mapped " + url + "," + method);
- }
- } else if (clazz.isAnnotationPresent(Service.class)) {
- Service service = clazz.getAnnotation(Service.class);
- String beanName = service.value();
- if ("".equals(beanName)) {
- beanName = clazz.getName();
- }
- Object instance = clazz.getDeclaredConstructor().newInstance();
- mapping.put(beanName, instance);
- // 如果当前实例具备有父接口,保存父接口包名
- for (Class<?> i : clazz.getInterfaces()) {
- mapping.put(i.getName(), instance);
- }
- } else {
- continue;
- }
- }
- // 依赖注入
- for (Object object : mapping.values()) {
- if (object == null) {
- continue;
- }
- Class clazz = object.getClass();
- if (clazz.isAnnotationPresent(Controller.class)) {
- // 取得所有的成员变量
- Field[] fields = clazz.getDeclaredFields();
- for (Field field : fields) {
- if (!field.isAnnotationPresent(Autowired.class)) { continue; }
- Autowired autowired = field.getAnnotation(Autowired.class);
- String beanName = autowired.value();
- if ("".equals(beanName)) {
- beanName = field.getType().getName();
- }
- field.setAccessible(true);
- try {
- // 从容器中,注入实例
- field.set(mapping.get(clazz.getName()), mapping.get(beanName));
- } catch (IllegalAccessException e) {
- e.printStackTrace();
- }
- }
- }
- }
- } catch (Exception ignored) {
- } finally {
- if (is != null) {
- try {
- is.close();
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- }
- System.out.print("MVC Framework is init");
- }
- /**
- * 将指定路径中的 class 名称保存
- */
- private void doScanner(String scanPackage) {
- // 将 . 替换为 /
- URL url = this.getClass().getClassLoader().getResource("/" + scanPackage.replaceAll("\\.", "/"));
- File classDir = new File(url.getFile());
- // 扫描包所有的 class 文件
- for (File file : classDir.listFiles()) {
- if (file.isDirectory()) {
- // 如果是文件夹,递归调用
- doScanner(scanPackage + "." + file.getName());
- } else {
- if (!file.getName().endsWith(".class")) {
- continue;
- }
- String clazzName = (scanPackage + "." + file.getName().replace(".class", ""));
- mapping.put(clazzName, null);
- }
- }
- }
- }
|