手写springmvc框架
程序员文章站
2022-07-15 11:44:44
...
思路:
1.编写servlet用来接收前端所有请求
1.1 扫描contrller包 ,返回list 集合
1.2 遍历list集合 得出 所有 contrller 类 与 方法,分辨用两个集合装,key为 请求路径
下面是代码:
package com.springmvc.servlet;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.springmvc.annotation.ZPController;
import com.springmvc.annotation.ZPRequestMapping;
/**
* 2018年6月4日10:27:19
* @author
*
*/
public class DispatcherServlet extends HttpServlet{
private static final long serialVersionUID = 1L;
private List<String> packageNames = new ArrayList<String>(); //所有的类
private Map<String, Object> instanceMap = new HashMap<String, Object>(); //所有的contrller
private Map<String, Object> handerMap = new HashMap<String, Object>(); //与url关联的方法
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
doPost(req, resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
String url = req.getRequestURI();
String context = req.getContextPath();
String path = url.replace(context, "");
Method method = (Method) handerMap.get(path);
//如果url key没有匹配的方法,就提示404
if(method==null){
resp.getWriter().write("not find 404");
return;
}
//根据url key 获得 contrllor
Object obj = instanceMap.get(path);
try {
//根据url key 调用对应处理方法
Object rest = method.invoke(obj);
resp.getWriter().write(rest.toString());
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
@Override
public void init() throws ServletException {
//扫描contrller
scanPackage("com.springmvc.contrller");
try {
// filterAndInstance();
//url 关联 方法
handerMap();
} catch (Exception e) {
e.printStackTrace();
}
}
private String replaceTo(String path) {
return path.replaceAll("\\.", "/");
}
private void scanPackage(String Package) {
URL url = this.getClass().getClassLoader().getResource("/" + replaceTo(Package));
String pathFile = url.getFile();
File file = new File(pathFile);
String fileList[] = file.list();
for (String path : fileList) {
File eachFile = new File(pathFile + path);
if (eachFile.isDirectory()) {
scanPackage(Package + eachFile.getName());
} else {
packageNames.add(Package + "." + eachFile.getName());
}
}
}
private void filterAndInstance() throws Exception {
if (packageNames.size() <= 0) {
return;
}
for (String className : packageNames) {
Class<?> cName = Class.forName(className.replace(".class", "").trim());
if (cName.isAnnotationPresent(ZPController.class)) {
Object instance = cName.newInstance();
ZPController controller = (ZPController) cName.getAnnotation(ZPController.class);
String key = controller.value();
instanceMap.put(key, instance);
} else {
continue;
}
}
}
private void handerMap() throws ClassNotFoundException, InstantiationException, IllegalAccessException {
if (packageNames.size() <= 0) {
return;
}
//遍历所有contrller
for (String className : packageNames) {
Class<?> cName = Class.forName(className.replace(".class", "").trim());
//判断哪些类,有加 @contrller 注解
if (cName.isAnnotationPresent(ZPController.class)) {
//取出累上面的 @ZPRequestMapping 注解值
ZPRequestMapping requestMapping = (ZPRequestMapping) cName.getAnnotation(ZPRequestMapping.class);
String ctvalue = "";
if(requestMapping!=null){
ctvalue = requestMapping.value();
}
//取出类里面的 所有方法
Method[] methods = cName.getMethods();
for (Method method : methods) {
//判断哪些方法 有加 @ZPRequestMapping
if (method.isAnnotationPresent(ZPRequestMapping.class)) {
//取出注解值
ZPRequestMapping rm = (ZPRequestMapping) method.getAnnotation(ZPRequestMapping.class);
String rmvalue = rm.value();
//拼接 类的 @ZPRequestMapping 值与 方法上面的@ZPRequestMapping 当成key
//别人添加 类 与 方法,url路径当成key
handerMap.put(ctvalue + rmvalue, method);
instanceMap.put(ctvalue + rmvalue, cName.newInstance());
} else {
continue;
}
}
} else {
continue;
}
}
}
}
Contrller 注解:
package com.springmvc.annotation;
import java.lang.annotation.Documented;
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)
@Documented
public @interface ZPController {
String value() default "";
}
RequestMapping 注解:
package com.springmvc.annotation;
import java.lang.annotation.Documented;
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)
@Documented
public @interface ZPRequestMapping {
String value() default "";
}
例子 Contrller 类:
package com.springmvc.contrller;
import com.springmvc.annotation.ZPController;
import com.springmvc.annotation.ZPRequestMapping;
@ZPController
public class MyContrller {
@ZPRequestMapping("/test")
public String test(){
System.out.println("22222222222222222222");
return "1111111111111";
}
}
pom.xml :
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.test</groupId>
<artifactId>demo2</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/javax.servlet/javax.servlet-api -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
</dependencies>
</project>
上一篇: MVC分层思想
下一篇: 找工作的一些经验 工作面试