commit 528f61742a71755634ea61d5c7992609d8c41d2c Author: niuniuniu Date: Wed Nov 1 08:26:54 2023 +0800 初始化 diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..5ff6309 --- /dev/null +++ b/.gitignore @@ -0,0 +1,38 @@ +target/ +!.mvn/wrapper/maven-wrapper.jar +!**/src/main/**/target/ +!**/src/test/**/target/ + +### IntelliJ IDEA ### +.idea/modules.xml +.idea/jarRepositories.xml +.idea/compiler.xml +.idea/libraries/ +*.iws +*.iml +*.ipr + +### Eclipse ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ +build/ +!**/src/main/**/build/ +!**/src/test/**/build/ + +### VS Code ### +.vscode/ + +### Mac OS ### +.DS_Store \ No newline at end of file diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..35410ca --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,8 @@ +# 默认忽略的文件 +/shelf/ +/workspace.xml +# 基于编辑器的 HTTP 客户端请求 +/httpRequests/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml diff --git a/.idea/aws.xml b/.idea/aws.xml new file mode 100644 index 0000000..b63b642 --- /dev/null +++ b/.idea/aws.xml @@ -0,0 +1,11 @@ + + + + + + \ No newline at end of file diff --git a/.idea/encodings.xml b/.idea/encodings.xml new file mode 100644 index 0000000..aa00ffa --- /dev/null +++ b/.idea/encodings.xml @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..7e60d96 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..94a25f7 --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..40a4e30 --- /dev/null +++ b/pom.xml @@ -0,0 +1,65 @@ + + 4.0.0 + com.brave + untitled7 + war + 1.0-SNAPSHOT + untitled7 Maven Webapp + http://maven.apache.org + + + junit + junit + 3.8.1 + test + + + + javax.servlet + javax.servlet-api + 4.0.1 + provided + + + org.reflections + reflections + 0.9.11 + + + + org.springframework.boot + spring-boot-maven-plugin + 2.5.2 + + + + + + + + + + src/main/java + + **/*.* + + + + src/main/resources + + **/*.* + + + + + + org.springframework.boot + spring-boot-maven-plugin + 2.5.2 + + + + + + diff --git a/src/main/java/com/brave/annotation/MyController.java b/src/main/java/com/brave/annotation/MyController.java new file mode 100644 index 0000000..702f66a --- /dev/null +++ b/src/main/java/com/brave/annotation/MyController.java @@ -0,0 +1,15 @@ +package com.brave.annotation; + + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target(ElementType.TYPE) +@Retention(RetentionPolicy.RUNTIME) +public @interface MyController { + + + String value() default ""; +} diff --git a/src/main/java/com/brave/annotation/MyRequestMapping.java b/src/main/java/com/brave/annotation/MyRequestMapping.java new file mode 100644 index 0000000..de19fd4 --- /dev/null +++ b/src/main/java/com/brave/annotation/MyRequestMapping.java @@ -0,0 +1,14 @@ +package com.brave.annotation; + + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target({ElementType.TYPE,ElementType.METHOD}) +@Retention(RetentionPolicy.RUNTIME) +public @interface MyRequestMapping { + + String value() default ""; +} diff --git a/src/main/java/com/brave/controller/TestController.java b/src/main/java/com/brave/controller/TestController.java new file mode 100644 index 0000000..bdc67c6 --- /dev/null +++ b/src/main/java/com/brave/controller/TestController.java @@ -0,0 +1,24 @@ +package com.brave.controller; + +import com.brave.annotation.MyController; +import com.brave.annotation.MyRequestMapping; + +@MyRequestMapping(value = "/test") +@MyController +public class TestController { + + @MyRequestMapping(value = "/test1") + public void test1() { + System.out.println("test1被调用"); + } + + @MyRequestMapping(value = "/test2") + public void test2() { + System.out.println("test2被调用了"); + } + + @MyRequestMapping(value = "/test3") + public void test3(){ + System.out.println("test3被调用了"); + } +} diff --git a/src/main/java/com/brave/servlet/MyDispatcherServlet.java b/src/main/java/com/brave/servlet/MyDispatcherServlet.java new file mode 100644 index 0000000..cb2123c --- /dev/null +++ b/src/main/java/com/brave/servlet/MyDispatcherServlet.java @@ -0,0 +1,183 @@ +package com.brave.servlet; + +import com.brave.annotation.MyController; +import com.brave.annotation.MyRequestMapping; +import org.reflections.Reflections; + +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.IOException; +import java.io.InputStream; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.*; + +public class MyDispatcherServlet extends HttpServlet { + /** + * 配置扫描的包,放到一个.properties文件中,在初始化的时候读取 + */ + private Properties properties=new Properties(); + + /** + * 需要一个set,把所有能够相应controller的存起来 + */ + private Set> classSet=new HashSet<>(); + + /** + * SpringMVC容器 + */ + private Map springMVCContext=new HashMap<>(); + + + /** + * 映射处理器,存储所有的方法 + */ + private Map handlerMapping=new HashMap<>(); + + /** + * 后端处理器的映射关系,存储所有controller + */ + private Map controllerMap=new HashMap<>(); + + + @Override + public void init(ServletConfig config) throws ServletException { + //加载配置文件,在web.xml中配置的初始化参数contextfigLocation + String initParameter = config.getInitParameter("contextConfigLocation"); + try { + loadConfigFile(initParameter); + }catch (Exception e){ + e.printStackTrace(); + } + + //扫描controller + scanPackage(properties.getProperty("package")); + + //初始化controller包 + initController(); + //初始化处理器映射器 + initHandlerMapping(); + } + + @Override + protected void service(HttpServletRequest req, HttpServletResponse resp){ + //处理请求 + if (handlerMapping.isEmpty()){ + return; + } + + //获取url + String uri = req.getRequestURI(); + String contextPath = req.getContextPath(); + String url = uri.replace(contextPath, ""); + if (!handlerMapping.containsKey(url)){ + try { + resp.getWriter().println("404"); + } catch (IOException e) { + throw new RuntimeException(e); + } + }else { + Method method = handlerMapping.get(url); + Object controller = controllerMap.get(url); + try { + method.invoke(controller); + } catch (IllegalAccessException e) { + throw new RuntimeException(e); + } catch (InvocationTargetException e) { + throw new RuntimeException(e); + } + } + } + + private void initHandlerMapping() { + if (springMVCContext.isEmpty()){ + return; + } + + for (Map.Entry entry : springMVCContext.entrySet()) { + //获取class对象 + Class aClass = entry.getValue().getClass(); + if (!aClass.isAnnotationPresent(MyController.class)){ + continue; + }else { + String baseUrl=""; + if (aClass.isAnnotationPresent(MyRequestMapping.class)){ + //如果类包含注解MyRequestMapping,获取注解值 + MyRequestMapping annotation = aClass.getAnnotation(MyRequestMapping.class); + baseUrl=annotation.value(); + } + + //获取所有方法 + Method[] methods=aClass.getMethods(); + for (Method method : methods) { + //判断方法上含有MyRequestMapping注解 + if (method.isAnnotationPresent(MyRequestMapping.class)){ + MyRequestMapping annotation = method.getAnnotation(MyRequestMapping.class); + String url = annotation.value(); + url = baseUrl +url; + + //将该放入方法集 + handlerMapping.put(url,method); + + try { + //放入controllerMap中 + controllerMap.put(url,aClass.newInstance()); + } catch (InstantiationException e) { + throw new RuntimeException(e); + } catch (IllegalAccessException e) { + throw new RuntimeException(e); + } + } + } + } + } + } + + private void initController() { + if (classSet.isEmpty()){ + return; + } + for (Class controller : classSet) { + try { + springMVCContext.put(lowerFirstWord(controller.getSimpleName()), controller.newInstance()); + } catch (InstantiationException e) { + throw new RuntimeException(e); + } catch (IllegalAccessException e) { + throw new RuntimeException(e); + } + } + } + + private String lowerFirstWord(String simpleName) { + char[] array = simpleName.toCharArray(); + array[0] +=32; + return String.valueOf(array); + } + + private void scanPackage(String packageName) { + Reflections reflections = new Reflections(packageName); + classSet=reflections.getTypesAnnotatedWith(MyController.class); + } + + + private void loadConfigFile(String fileName) { + //以流的方式获取资源 + InputStream inputStream = this.getClass().getClassLoader().getResourceAsStream(fileName); + + try { + properties.load(inputStream); + } catch (IOException e) { + throw new RuntimeException(e); + }finally { + try { + inputStream.close(); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + } +} diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties new file mode 100644 index 0000000..e69de29 diff --git a/src/main/webapp/WEB-INF/web.xml b/src/main/webapp/WEB-INF/web.xml new file mode 100644 index 0000000..10d0960 --- /dev/null +++ b/src/main/webapp/WEB-INF/web.xml @@ -0,0 +1,22 @@ + + + + + + dispatcherServlet + com.brave.servlet.MyDispatcherServlet + + + contextConfigLocation + application.properties + + + + dispatcherServlet + + / + + diff --git a/src/main/webapp/index.jsp b/src/main/webapp/index.jsp new file mode 100644 index 0000000..c38169b --- /dev/null +++ b/src/main/webapp/index.jsp @@ -0,0 +1,5 @@ + + +

Hello World!

+ +