1、首先配置tomcat加载的web.xml文件
<servlet>
<servlet-name>mymvc</servlet-name>
<servlet-class>com.lwq.edu.mvcframework.servlet.MyDispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>springmvc.properties</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>mymvc</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
2、增加配置文件springmvc.properties,扫描包
scanPackage = com.lwq
3、自定自定义的扫描注解@MyAutowired,@MyRequestMapping,@MySelfController,@MySelfService
@Documented
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAutowired {
String value() default "";
}
@Documented
@Target({ElementType.TYPE,ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface MyRequestMapping {
String value() default "";
}
@Documented
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface MySelfController {
String value() default "";
}
@Documented
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface MySelfService {
String value() default "";
}
4、IOC容器进行bean的初始化和依赖注入,建立url和method之间的映射
@Override
public void init(ServletConfig config) throws ServletException {
//1、加载配置文件 springmvc.properties
String contextConfigLocation = config.getInitParameter("contextConfigLocation");
doLoadConfig(contextConfigLocation);
//2、扫描相关的类,扫描注解
doScan(properties.getProperty("scanPackage"));
//3、初始化bean对象(实现IOC容器,基于注解)
doInstance();
//4、实现依赖注入
doAutowired();
//5、构造一个HandlerMapping处理器映射器,将配置好的url和method建立映射关系
initHandlerMappping();
System.out.println("myMvc初始化完成");
//6、等待请求进入,处理请求
}
5、请求进入,进行方法处理
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//处理请求:根据url。找到对应的method方法,进行调用
//获取uri
//String requestURI = req.getRequestURI();
//Method method = handleMapping.get(requestURI);
//反射调用,需要传入对象,需要传入参数
//method.invoke()
//根据uri获取到当前请求的handle
Handle handle = getHandle(req);
if(handle == null){
resp.getWriter().write("404 not found");
return;
}
//验证是否有权限
Method method = handle.getMethod();
if(method.isAnnotationPresent(MySecurity.class)){
MySecurity mySecurity = method.getAnnotation(MySecurity.class);
String name = req.getParameter("name");
if(!Arrays.asList(mySecurity.value()).contains(name)){
req.setCharacterEncoding("UTF-8");
resp.setContentType("text/html;charset=utf-8");
resp.getWriter().write(name + "没有访问权限");
return;
}
}
//参数绑定
//获取所有参数类型数组,数组长度就是args数据长度
Class<?>[] parameterTypes = handle.getMethod().getParameterTypes();
//根据上述数组长度创建一个新的数组(传入反射调用的)
Object[] paraValues = new Object[parameterTypes.length];
//向参数数组中塞值,得保证参数的顺序和方法中形参顺序一致
Map<String, String[]> parameterMap = req.getParameterMap();
//遍历request中的参数(填充除request,response参数)
for (Map.Entry<String,String[]> param : parameterMap.entrySet()){
String value = StringUtils.join(param.getValue(), ",");
//参数与方法中的参数匹配,填充数据
if(!handle.getParamIndexMapping().containsKey(param.getKey())){
continue;
}
//方法形参中确实有该参数,找到他的索引位置,对应的把参数放入paramValues
Integer index = handle.getParamIndexMapping().get(param.getKey());
//把前台传过来的参数值填充到对应位置
paraValues[index] = value;
}
Integer requestIndex = handle.getParamIndexMapping().get(HttpServletRequest.class.getSimpleName());
paraValues[requestIndex] = req;
Integer responseIndex = handle.getParamIndexMapping().get(HttpServletResponse.class.getSimpleName());
paraValues[responseIndex] = resp;
//最终调用handle的method属性
try {
handle.getMethod().invoke(handle.getController(),paraValues);
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
6、权限的设置,自定义权限的注解@MySecurity
@Documented
@Target({ElementType.TYPE,ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface MySecurity {
String[] value() default {};
}
7、扫描注解,并对注解中的值进行处理
//验证是否有权限
Method method = handle.getMethod();
if(method.isAnnotationPresent(MySecurity.class)){
MySecurity mySecurity = method.getAnnotation(MySecurity.class);
String name = req.getParameter("name");
if(!Arrays.asList(mySecurity.value()).contains(name)){
req.setCharacterEncoding("UTF-8");
resp.setContentType("text/html;charset=utf-8");
resp.getWriter().write(name + "没有访问权限");
return;
}
}
源码下载地址:
https://download.csdn.net/download/qq_41267285/20433409