手写springMvc
commit
db04ed496a
|
@ -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
|
|
@ -0,0 +1,8 @@
|
||||||
|
# 默认忽略的文件
|
||||||
|
/shelf/
|
||||||
|
/workspace.xml
|
||||||
|
# 基于编辑器的 HTTP 客户端请求
|
||||||
|
/httpRequests/
|
||||||
|
# Datasource local storage ignored files
|
||||||
|
/dataSources/
|
||||||
|
/dataSources.local.xml
|
|
@ -0,0 +1,7 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="Encoding">
|
||||||
|
<file url="file://$PROJECT_DIR$/src/main/java" charset="UTF-8" />
|
||||||
|
<file url="file://$PROJECT_DIR$/src/main/resources" charset="UTF-8" />
|
||||||
|
</component>
|
||||||
|
</project>
|
|
@ -0,0 +1,14 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="ExternalStorageConfigurationManager" enabled="true" />
|
||||||
|
<component name="MavenProjectsManager">
|
||||||
|
<option name="originalFiles">
|
||||||
|
<list>
|
||||||
|
<option value="$PROJECT_DIR$/pom.xml" />
|
||||||
|
</list>
|
||||||
|
</option>
|
||||||
|
</component>
|
||||||
|
<component name="ProjectRootManager" version="2" languageLevel="JDK_17" default="true" project-jdk-name="17" project-jdk-type="JavaSDK">
|
||||||
|
<output url="file://$PROJECT_DIR$/out" />
|
||||||
|
</component>
|
||||||
|
</project>
|
|
@ -0,0 +1,6 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="VcsDirectoryMappings">
|
||||||
|
<mapping directory="$PROJECT_DIR$" vcs="Git" />
|
||||||
|
</component>
|
||||||
|
</project>
|
|
@ -0,0 +1,24 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<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.wtd</groupId>
|
||||||
|
<artifactId>wtd-mvc</artifactId>
|
||||||
|
<version>1.0-SNAPSHOT</version>
|
||||||
|
<packaging>war</packaging>
|
||||||
|
<properties>
|
||||||
|
<maven.compiler.source>17</maven.compiler.source>
|
||||||
|
<maven.compiler.target>17</maven.compiler.target>
|
||||||
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
|
</properties>
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>javax.servlet</groupId>
|
||||||
|
<artifactId>servlet-api</artifactId>
|
||||||
|
<version>2.3</version>
|
||||||
|
<scope>provided</scope>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
</project>
|
|
@ -0,0 +1,16 @@
|
||||||
|
package com.wtd.annotation;
|
||||||
|
|
||||||
|
import java.lang.annotation.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @program: wtd-mvc
|
||||||
|
* @description:
|
||||||
|
* @author: Mr.Wang
|
||||||
|
* @create: 2023-10-28 16:47
|
||||||
|
**/
|
||||||
|
@Target({ElementType.FIELD})
|
||||||
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
|
@Documented
|
||||||
|
public @interface WtdAutowiredAnnotation {
|
||||||
|
String value() default "";
|
||||||
|
}
|
|
@ -0,0 +1,16 @@
|
||||||
|
package com.wtd.annotation;
|
||||||
|
|
||||||
|
import java.lang.annotation.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @program: wtd-mvc
|
||||||
|
* @description:
|
||||||
|
* @author: Mr.Wang
|
||||||
|
* @create: 2023-10-28 16:47
|
||||||
|
**/
|
||||||
|
@Target({ElementType.TYPE})
|
||||||
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
|
@Documented
|
||||||
|
public @interface WtdControllerAnnotation {
|
||||||
|
String value() default "";
|
||||||
|
}
|
|
@ -0,0 +1,16 @@
|
||||||
|
package com.wtd.annotation;
|
||||||
|
|
||||||
|
import java.lang.annotation.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @program: wtd-mvc
|
||||||
|
* @description:
|
||||||
|
* @author: Mr.Wang
|
||||||
|
* @create: 2023-10-28 16:47
|
||||||
|
**/
|
||||||
|
@Target({ElementType.TYPE,ElementType.METHOD})
|
||||||
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
|
@Documented
|
||||||
|
public @interface WtdRequestMappingAnnotation {
|
||||||
|
String value() default "";
|
||||||
|
}
|
|
@ -0,0 +1,16 @@
|
||||||
|
package com.wtd.annotation;
|
||||||
|
|
||||||
|
import java.lang.annotation.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @program: wtd-mvc
|
||||||
|
* @description:
|
||||||
|
* @author: Mr.Wang
|
||||||
|
* @create: 2023-10-28 16:47
|
||||||
|
**/
|
||||||
|
@Target({ElementType.PARAMETER})
|
||||||
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
|
@Documented
|
||||||
|
public @interface WtdRequestParamAnnotation {
|
||||||
|
String value() default "";
|
||||||
|
}
|
|
@ -0,0 +1,16 @@
|
||||||
|
package com.wtd.annotation;
|
||||||
|
|
||||||
|
import java.lang.annotation.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @program: wtd-mvc
|
||||||
|
* @description:
|
||||||
|
* @author: Mr.Wang
|
||||||
|
* @create: 2023-10-28 16:47
|
||||||
|
**/
|
||||||
|
@Target({ElementType.TYPE})
|
||||||
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
|
@Documented
|
||||||
|
public @interface WtdServiceAnnotation {
|
||||||
|
String value() default "";
|
||||||
|
}
|
|
@ -0,0 +1,38 @@
|
||||||
|
package com.wtd.controller;
|
||||||
|
|
||||||
|
import com.wtd.annotation.WtdAutowiredAnnotation;
|
||||||
|
import com.wtd.annotation.WtdControllerAnnotation;
|
||||||
|
import com.wtd.annotation.WtdRequestMappingAnnotation;
|
||||||
|
import com.wtd.annotation.WtdRequestParamAnnotation;
|
||||||
|
import com.wtd.service.WtdService;
|
||||||
|
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.PrintWriter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @program: wtd-mvc
|
||||||
|
* @description:
|
||||||
|
* @author: Mr.Wang
|
||||||
|
* @create: 2023-10-28 16:53
|
||||||
|
**/
|
||||||
|
@WtdControllerAnnotation
|
||||||
|
@WtdRequestMappingAnnotation("/wtd")
|
||||||
|
public class WtdController {
|
||||||
|
@WtdAutowiredAnnotation("WtdServiceImpl")
|
||||||
|
private WtdService wtdService;
|
||||||
|
|
||||||
|
public void query(HttpServletRequest request, HttpServletResponse response,
|
||||||
|
@WtdRequestParamAnnotation("name")String name,
|
||||||
|
@WtdRequestParamAnnotation("age")String age){
|
||||||
|
try {
|
||||||
|
PrintWriter pw = response.getWriter();
|
||||||
|
String result = wtdService.query(name, age);
|
||||||
|
pw.write(result);
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,11 @@
|
||||||
|
package com.wtd.service;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @program: wtd-mvc
|
||||||
|
* @description:
|
||||||
|
* @author: Mr.Wang
|
||||||
|
* @create: 2023-10-28 16:53
|
||||||
|
**/
|
||||||
|
public interface WtdService {
|
||||||
|
String query(String name,String age);
|
||||||
|
}
|
|
@ -0,0 +1,18 @@
|
||||||
|
package com.wtd.service.impl;
|
||||||
|
|
||||||
|
import com.wtd.annotation.WtdServiceAnnotation;
|
||||||
|
import com.wtd.service.WtdService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @program: wtd-mvc
|
||||||
|
* @description:
|
||||||
|
* @author: Mr.Wang
|
||||||
|
* @create: 2023-10-28 16:53
|
||||||
|
**/
|
||||||
|
@WtdServiceAnnotation("WtdServiceImpl")
|
||||||
|
public class WtdServiceImpl implements WtdService {
|
||||||
|
@Override
|
||||||
|
public String query(String name, String age) {
|
||||||
|
return "name==="+name+"; age==="+age;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,198 @@
|
||||||
|
package com.wtd.servlet;
|
||||||
|
|
||||||
|
import com.wtd.annotation.*;
|
||||||
|
import com.wtd.controller.WtdController;
|
||||||
|
|
||||||
|
import javax.servlet.ServletConfig;
|
||||||
|
import javax.servlet.ServletException;
|
||||||
|
import javax.servlet.ServletRequest;
|
||||||
|
import javax.servlet.ServletResponse;
|
||||||
|
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.lang.reflect.Field;
|
||||||
|
import java.lang.reflect.InvocationTargetException;
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
import java.net.URL;
|
||||||
|
import java.text.Annotation;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @program: wtd-mvc
|
||||||
|
* @description:
|
||||||
|
* @author: Mr.Wang
|
||||||
|
* @create: 2023-10-28 17:02
|
||||||
|
**/
|
||||||
|
public class DispatcherServlet extends HttpServlet {
|
||||||
|
|
||||||
|
List<String> classNames=new ArrayList<>();
|
||||||
|
|
||||||
|
Map<String,Object> beans=new HashMap<String,Object>();
|
||||||
|
Map<String,Object> handlerMap=new HashMap<String,Object>();
|
||||||
|
|
||||||
|
|
||||||
|
public void init(ServletConfig config){
|
||||||
|
scanPackage("com.wtd");//写到properties
|
||||||
|
doInstance();//根据全类名创建bean
|
||||||
|
doIoc();//根据bean进行依赖注入
|
||||||
|
buildUrlMapping();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void scanPackage(String basePackage){
|
||||||
|
URL url=this.getClass().getClassLoader().getResource("/"+basePackage.replaceAll("\\.","/"));
|
||||||
|
String fileStr=url.getFile();
|
||||||
|
File file=new File(fileStr);
|
||||||
|
|
||||||
|
String[] filesStr = file.list();
|
||||||
|
|
||||||
|
for (String path : filesStr) {
|
||||||
|
File filePath=new File(fileStr+path);
|
||||||
|
if(filePath.isDirectory()){
|
||||||
|
scanPackage(basePackage+"."+path);
|
||||||
|
}else{
|
||||||
|
classNames.add(basePackage+"."+filePath.getName());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//根据扫描出来的全类名 进行实例化
|
||||||
|
private void doInstance(){
|
||||||
|
if(classNames.size()<0){
|
||||||
|
System.out.println("扫描失败");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
//遍历list里面所有的class类
|
||||||
|
for (String className : classNames) {
|
||||||
|
String cn = className.replace(".class", "");
|
||||||
|
try {
|
||||||
|
Class<?> clazz = Class.forName(cn);
|
||||||
|
if(clazz.isAnnotationPresent(WtdControllerAnnotation.class)){
|
||||||
|
Object instance = clazz.newInstance();
|
||||||
|
WtdRequestMappingAnnotation requestMappingAnnotation = clazz.getAnnotation(WtdRequestMappingAnnotation.class);
|
||||||
|
String rmValue=requestMappingAnnotation.value();
|
||||||
|
beans.put(rmValue,instance);
|
||||||
|
}else if(clazz.isAnnotationPresent(WtdServiceAnnotation.class)){
|
||||||
|
WtdServiceAnnotation service=clazz.getAnnotation(WtdServiceAnnotation.class);
|
||||||
|
Object instance=clazz.newInstance();
|
||||||
|
beans.put(service.value(),instance);
|
||||||
|
}else {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
} catch (ClassNotFoundException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}catch (InstantiationException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
} catch (IllegalAccessException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//把service注入到controller
|
||||||
|
public void doIoc(){
|
||||||
|
if(!(beans.entrySet().size() > 0)){
|
||||||
|
System.out.println("没有一个实例类");
|
||||||
|
}
|
||||||
|
for (Map.Entry<String,Object> entry:beans.entrySet()){
|
||||||
|
Object instance=entry.getValue();
|
||||||
|
Class<?> clazz = instance.getClass();
|
||||||
|
if(clazz.isAnnotationPresent(WtdControllerAnnotation.class)){
|
||||||
|
Field[] fields = clazz.getDeclaredFields();
|
||||||
|
for (Field field : fields) {
|
||||||
|
if(field.isAnnotationPresent(WtdAutowiredAnnotation.class)){
|
||||||
|
WtdAutowiredAnnotation auto=field.getAnnotation(WtdAutowiredAnnotation.class);
|
||||||
|
String key=auto.value();
|
||||||
|
field.setAccessible(true);
|
||||||
|
try {
|
||||||
|
field.set(instance,beans.get(key));
|
||||||
|
} catch (IllegalAccessException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}else {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}else {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private void buildUrlMapping(){
|
||||||
|
if(!(beans.entrySet().size() > 0)){
|
||||||
|
System.out.println("没有类的实例化");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
for (Map.Entry<String,Object> entry:beans.entrySet()){
|
||||||
|
Object instance=entry.getValue();
|
||||||
|
Class<?> clazz=instance.getClass();
|
||||||
|
if(clazz.isAnnotationPresent(WtdControllerAnnotation.class)){
|
||||||
|
WtdRequestMappingAnnotation requestMappingAnnotation=clazz.getAnnotation(WtdRequestMappingAnnotation.class);
|
||||||
|
String classPath = requestMappingAnnotation.value();
|
||||||
|
Method[] methods = clazz.getMethods();
|
||||||
|
for (Method method : methods) {
|
||||||
|
if(method.isAnnotationPresent(WtdRequestMappingAnnotation.class)){
|
||||||
|
WtdRequestMappingAnnotation methodMapping=method.getAnnotation(WtdRequestMappingAnnotation.class);
|
||||||
|
String methodPath=methodMapping.value();
|
||||||
|
handlerMap.put(classPath+methodPath,method);
|
||||||
|
}else {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}else {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@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 {
|
||||||
|
String uri=req.getRequestURI();
|
||||||
|
String context=req.getContextPath();
|
||||||
|
String path=uri.replace(context,"");
|
||||||
|
Method method=(Method) handlerMap.get(path);
|
||||||
|
//根据key=/wtd到map去拿
|
||||||
|
WtdController instance=(WtdController) beans.get("/"+path.split("/")[1]);
|
||||||
|
Object arg[]=hand(req,resp,method);
|
||||||
|
try {
|
||||||
|
method.invoke(instance,arg);
|
||||||
|
} catch (IllegalAccessException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
} catch (InvocationTargetException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private static Object[] hand(HttpServletRequest request,HttpServletResponse response,Method method){
|
||||||
|
Class<?>[] paramClazzs = method.getParameterTypes();
|
||||||
|
Object[] args=new Object[paramClazzs.length];
|
||||||
|
int args_i=0;
|
||||||
|
int index=0;
|
||||||
|
for (Class<?> paramClazz : paramClazzs) {
|
||||||
|
if(ServletRequest.class.isAssignableFrom(paramClazz)){
|
||||||
|
args[args_i++]=request;
|
||||||
|
}
|
||||||
|
if(ServletResponse.class.isAssignableFrom(paramClazz)){
|
||||||
|
args[args_i++]=response;
|
||||||
|
}
|
||||||
|
Annotation[] paramAns= (Annotation[]) method.getParameterAnnotations()[index];
|
||||||
|
if(paramAns.length>0){
|
||||||
|
for (Annotation paramAn : paramAns) {
|
||||||
|
if(WtdRequestParamAnnotation.class.isAssignableFrom(paramAn.getClass())){
|
||||||
|
WtdRequestParamAnnotation rp=(WtdRequestParamAnnotation) paramAn;
|
||||||
|
args[args_i++]=request.getParameter(rp.value());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
index++;
|
||||||
|
}
|
||||||
|
return args;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,16 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
|
||||||
|
version="4.0">
|
||||||
|
<display-name>wtd-mvc</display-name>
|
||||||
|
<servlet>
|
||||||
|
<servlet-name>DispatcherServlet</servlet-name>
|
||||||
|
<servlet-class>com.wtd.servlet.DispatcherServlet</servlet-class>
|
||||||
|
<load-on-startup>0</load-on-startup>
|
||||||
|
</servlet>
|
||||||
|
<servlet-mapping>
|
||||||
|
<servlet-name>DispatcherServlet</servlet-name>
|
||||||
|
<url-pattern></url-pattern>
|
||||||
|
</servlet-mapping>
|
||||||
|
</web-app>
|
Loading…
Reference in New Issue