内容简介:注解如下自己定义的controller如下由于是个Web项目,我们在Web.xml里面配置好自己的DispatcherServlet的映射
- 创建DispatcherServlet拦截所有的请求
- 初始化,重写Servlet的init方法
@Controller @RequestMapping
- 处理请求 重写GET和POST方法
- 获取请求URL,去URLBean里获取实例,再去URLMethod里获取方法实例,使用反射执行方法
Maven依赖
<dependencies> <!--servlet依赖--> <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>3.1.0</version> <scope>provided</scope> </dependency> <!--各种工具--> <dependency> <groupId>commons-lang</groupId> <artifactId>commons-lang</artifactId> <version>2.5</version> </dependency> </dependencies> 复制代码
定义自己的注解 @ExtController
和 @ExtRequestMapping
,定义一个自己的Controller
注解如下
@Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) public @interface ExtController { } 复制代码
@Target({ElementType.METHOD,ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) public @interface ExtRequestMapping { String value() default ""; } 复制代码
自己定义的controller如下
@ExtController @ExtRequestMapping("/") public class IndexController { @ExtRequestMapping public String getIndex() { System.out.println("自定义的MVC框架"); return "index"; } } 复制代码
重点!构建DispatcherServlet
由于是个Web项目,我们在Web.xml里面配置好自己的DispatcherServlet的映射
<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"> <servlet> <servlet-name>disaptcher</servlet-name> <servlet-class>com.libi.mvc.servlet.ExtDispatcherServlet</servlet-class> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>disaptcher</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping> </web-app> 复制代码
第一步、在init方法里扫包,判断是否有Controller注解,再把URL和映射经行关联
- 在DispatcherServlet里定义三个Bean容器
/**mvc的Bean容器,存入Controller对象*/ private ConcurrentHashMap<String, Object> controllerBeans = new ConcurrentHashMap<String, Object>(); /**mvc的请求地址,把Url和Controller建立映射*/ private ConcurrentHashMap<String, Object> urlBeans = new ConcurrentHashMap<String, Object>(); /**mvc的请求方法名称,把Url和方法名建立映射*/ private ConcurrentHashMap<String, Object> urlMethods = new ConcurrentHashMap<String, Object>(); 复制代码
- 在重写了Servlet的init方法里扫描指定包下面所有带有
@ExtController
注解的类,实例化后放在mvc的bean容器里
public void init() throws ServletException { //扫描Controller包下面的类,并且找到所有带@Controller的注解倒到Bean容器里 List<Class<?>> classes = ClassUtils.getClasses("com.controller"); try { findClassMvcAnnoation(classes); } catch (Exception e) { e.printStackTrace(); } } /**找到带有Controller注解的类然后初始化放入bean容器里*/ private void findClassMvcAnnoation(List<Class<?>> classes) throws IllegalAccessException, InstantiationException { for (Class<?> classInfo : classes) { ExtController extController = classInfo.getAnnotation(ExtController.class); if (extController != null) { String beanId = ClassUtils.toLowerCaseFirstOne(classInfo.getSimpleName()); mvcBeans.put(beanId, classInfo.newInstance()); } } } 复制代码
第二步 把method和url进行映射
- 利用反射机制获取有@RequestMapping的类和方法,把URL和方法经行关联,放在Map里
/**将URL映射和方法关联起来*/ private void handleMapping() { //遍历Controller,判断类上是否有RequestMapping注解 for (Map.Entry<String, Object> entry : controllerBeans.entrySet()) { Object controller = entry.getValue(); //判断类是否加上了@RequestMapping注解 Class<?> classInfo = controller.getClass(); ExtRequestMapping classRequestMapping = classInfo.getDeclaredAnnotation(ExtRequestMapping.class); String baseUrl = ""; if (classRequestMapping != null) { //获取Url映射的地址 baseUrl = classRequestMapping.value(); } //判断方法上是否加上了RequestMapping Method[] methods = classInfo.getDeclaredMethods(); for (Method method : methods) { //获取方法上的映射 ExtRequestMapping methodRequestMapping = method.getDeclaredAnnotation(ExtRequestMapping.class); if (methodRequestMapping != null) { String methodUrl = baseUrl + methodRequestMapping.value(); //装入映射表 System.out.println("put url:"+methodUrl); urlBeans.put(methodUrl, controller); urlMethods.put(methodUrl, method); } } } } 复制代码
上面这一步在init()方法里,创建完controller实例之后执行
第三步 重写doPost方法
- 利用反射机制获取到需要的方法,利用反射机制执行存在Map里的方法
/**处理请求*/ @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { //获取请求url地址 String url = req.getRequestURI(); System.out.println("url:"+url); //从map集合中获取controller Object controller = urlBeans.get(url); if (controller == null) { //到这里说明页面不存在 resp.getWriter().println("404 not find url"); return; } //从map中获取方法,调用并且获取返回结果 Method method = urlMethods.get(url); if (method == null) { //到这里说明页面不存在 resp.getWriter().println("404 not find method"); return; } String result = (String) methodInvoke(method, controller); resp.getWriter().println(result); } @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doPost(req,resp); } private Object methodInvoke(Method method, Object controller) { Object result = null; try { result = method.invoke(controller); } catch (IllegalAccessException | InvocationTargetException e) { e.printStackTrace(); } return result; } 复制代码
写到这里的效果如下
第四步 配置视图解析器
/**视图解析器*/ private void extResourceViewResolver(String pageName, HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException { String prefix = "/WEB-INF/view/"; String suffix = ".jsp"; request.getRequestDispatcher(prefix+pageName+suffix).forward(request,response); } 复制代码
以上代码在doGet里执行
/**处理请求*/ @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { //获取请求url地址 String url = req.getRequestURI(); System.out.println("url:"+url); //从map集合中获取controller Object controller = urlBeans.get(url); if (controller == null) { //到这里说明页面不存在 resp.getWriter().println("404 not find url"); return; } //从map中获取方法,调用并且获取返回结果 Method method = urlMethods.get(url); if (method == null) { //到这里说明页面不存在 resp.getWriter().println("404 not find method"); return; } String result = (String) methodInvoke(method, controller); //-----------------使用视图转换器渲染页面 extResourceViewResolver(result,req,resp); //------------------ } @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doPost(req,resp); } 复制代码
/WEB-INF/view/index.jsp内容如下
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>index</title> </head> <body> <h1>自己手写mvc——index.jsp</h1> </body> </html> 复制代码
执行后效果如下
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:- 手写源码(四):自己实现Mybatis
- 手写源码(二):自己实现SpringIOC
- 手写源码(一):自己实现Spring事务
- EventBus 源码详细分析:手写 EventBus 核心代码
- 阿里架构师手写Tomcat——Session源码解析
- node进阶——之事无巨细手写koa源码
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
深度学习
[美] 伊恩·古德费洛、[加] 约书亚·本吉奥、[加] 亚伦·库维尔 / 赵申剑、黎彧君、符天凡、李凯 / 人民邮电出版社 / 2017-7-1 / 168
《深度学习》由全球知名的三位专家Ian Goodfellow、Yoshua Bengio 和Aaron Courville撰写,是深度学习领域奠基性的经典教材。全书的内容包括3个部分:第1部分介绍基本的数学工具和机器学习的概念,它们是深度学习的预备知识;第2部分系统深入地讲解现今已成熟的深度学习方法和技术;第3部分讨论某些具有前瞻性的方向和想法,它们被公认为是深度学习未来的研究重点。 《深度......一起来看看 《深度学习》 这本书的介绍吧!