内容简介:注解如下自己定义的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源码
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Text Processing in Python
David Mertz / Addison-Wesley Professional / 2003-6-12 / USD 54.99
Text Processing in Python describes techniques for manipulation of text using the Python programming language. At the broadest level, text processing is simply taking textual information and doing som......一起来看看 《Text Processing in Python》 这本书的介绍吧!