二. 手写SpringMVC框架

1 新建DispatcherServlet

1.2 在src目录下,新建applicationContext.xml

1.3 在 Dispatcher S ervlet 的构造方法中解析a pplicationContext.xml 配置文件

import java.io.IOException;

import java.io.InputStream;

import java.util.Map;

import java.util.concurrent.ConcurrentHashMap;

import javax.servlet.ServletException;

import javax.servlet.annotation.WebServlet;

import javax.servlet.http.HttpServlet;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

import javax.xml.parsers.DocumentBuilder;

import javax.xml.parsers.DocumentBuilderFactory;

import javax.xml.parsers.ParserConfigurationException;

import org.w3c.dom.Document;

import org.w3c.dom.Element;

import org.w3c.dom.Node;

import org.w3c.dom.NodeList;

import org.xml.sax.SAXException;

@WebServlet(“*.do”)

public class DispatcherServlet extends HttpServlet {

private Map

public DispatcherServlet() {

try {

InputStream inputStream = this.getClass().getClassLoader().getResourceAsStream(“applicationContext.xml”);

// 1,通过工厂模式,创建documentBuilderFactory 工厂对象

DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory. newInstance();

// 2,创建DocumentBuilder 对象

DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();

// 3,得到Document 对象(注意导入org.w3c.dom 包中的)

Document document = documentBuilder.parse(inputStream);

// 4,获得所有的bean 标签

NodeList nodeList = document.getElementsByTagName(“bean”);

for (int i = 0; i < nodeList.getLength(); i++) {

Node node = nodeList.item(i);

if(node.getNodeType() == Node. ELEMENT_NODE) {

//(注意导入org.w3c.dom 包中的)

//强转成Element 类的对象,里面有比Node 类更方便的方法

Element element = (Element)node;

String id = element.getAttribute(“id”);

String className = element.getAttribute(“class”);

boolean flag = map.containsKey(id);

if(flag == true)

return;

Object o = Class. forName(className).newInstance();

map.put(id, o);

} catch (ParserConfigurationException | SAXException | IOException | ClassNotFoundException | InstantiationException | IllegalAccessException e) {

e.printStackTrace();

@Override

protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

//设置编码

request.setCharacterEncoding(“UTF-8”);

response.setCharacterEncoding(“UTF-8”);

response.setContentType(“text/html;charset=UTF-8”);

//假设url 是:http://localhost:8080/mymvc2/hello.do

// ServletPath 是Servlet 的访问路径: /hello.do

// 思路是:

// 第1 步:/hello.do -> hello 或者/book.do -> book

// 第2 步:hello -> HelloController 或者book -> BookController

String servletPath = request.getServletPath(); // /hello.do

int lastDotIndex = servletPath.lastIndexOf(“.do”);

servletPath = servletPath.substring(1, lastDotIndex); // hello

1.4 在DispatcherServlet的service方法中,通过ServletPath获取对应的Controller对象,优化反射的代码

@Override

protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

//设置编码

request.setCharacterEncoding(“UTF-8”);

response.setCharacterEncoding(“UTF-8”);

response.setContentType(“text/html;charset=UTF-8”);

//假设url 是:http://localhost:8080/mymvc2/hello.do

// ServletPath 是Servlet 的访问路径: /hello.do

// 思路是:

// 第1 步:/hello.do -> hello 或者/book.do -> book

// 第2 步:hello -> HelloController 或者book -> BookController

String servletPath = request.getServletPath(); // /hello.do

int lastDotIndex = servletPath.lastIndexOf(“.do”);

servletPath = servletPath.substring(1, lastDotIndex); // hello

//通过ServletPath 获取对应的Controller 对象

Object xxxController = map.get(servletPath);

String ac = request.getParameter(“ac”);

System. out.println(“=======” + ac + “======”);

if (StringUtil. isEmpty(ac))

ac = “index”;

try {

//这里只能try…catch 异常,因为在重写的方法里,不能抛出比父类更大的异常

Method method = xxxController.getClass().getDeclaredMethod(ac, HttpServletRequest. class,HttpServletResponse. class);

if (method != null) {

method.invoke(xxxController, request, response);

} else {

throw new RuntimeException(“ac 值违法”);

} catch (NoSuchMethodException | SecurityException | IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {

e.printStackTrace();

1.5 写一个简单的EmpController

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

public class EmpController {

public void index(HttpServletRequest request,HttpServletResponse response) {

System. out.println(“EmpController…index”);

(代码格式问题各位大佬别吐槽,复制过来的有时间改)

Original: https://www.cnblogs.com/lijili/p/16102947.html
Author: 雾里看瓜
Title: 二. 手写SpringMVC框架

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/622022/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • IK-Analyzer(5.3.1)动态配置自定义词典

    参考文献:http://blog.csdn.net/fatpanda/article/details/37911079 jar包: IK-Analyzer-extra-5.3.1….

    Java 2023年6月7日
    076
  • IO流

    404. 抱歉,您访问的资源不存在。 可能是网址有误,或者对应的内容被删除,或者处于私有状态。 代码改变世界,联系邮箱 contact@cnblogs.com 园子的商业化努力-困…

    Java 2023年6月7日
    087
  • SpringBoot映射虚拟图片路径

    各位看官可以关注博主个人博客,了解更多信息。作者:Surpasser链接地址:https://surpass.org.cn 前言 ​ 我的毕设项目中涉及到了多媒体表单提交,以我本来…

    Java 2023年6月7日
    092
  • 在工作中学习看问题的角度

    向架构师学习 修改 A 导致 B 出了问题。 我们: 这里是个坑,下次要小心点 也许我应该写文档记录下这件事 也许我应该告诉下其他同事 …… 架构师:从框架…

    Java 2023年6月16日
    090
  • 并发编程之:AQS源码解析

    大家好,我是小黑,一个在互联网苟且偷生的农民工。 在Java并发编程中,经常会用到锁,除了Synchronized这个JDK关键字以外,还有Lock接口下面的各种锁实现,如重入锁R…

    Java 2023年6月7日
    099
  • ch04 Java流程控制

    Java 流程控制 Scanner对象 通过Scanner类的next()与nextLine()方法获取输入的字符串,在读取前一般使用hasNext()与hasNextLine()…

    Java 2023年6月9日
    067
  • 带你领略下iOS中OC的“alloc”源代码,让你在工作中不在迷惑

    前言前面我们使用官方开源的objc源码进行了编译调试 objc4-818.2源码编译调试笔记 前言为什么会想要调试源码? 苹果开源了部分源码, 但相似内容太多, 基本找不到代码见的…

    Java 2023年6月16日
    075
  • SpringBoot事件监听器源码分析

    本文涉及到Spring的监听器,如果不太了解请先阅读之前的Spring监听器的文章。 SpringBoot事件监听器初始化 SpringBoot中默认定义了11个事件监听器对象,全…

    Java 2023年6月13日
    081
  • SpringCloudAlibaba项目之Seata分布式事务

    SpringCloudAlibaba随笔目录 一、SpringCloudAlibaba项目之父工程搭建 二、 SpringCloudAlibaba项目之Nacos搭建及服务注册 三…

    Java 2023年6月5日
    0105
  • Centos7: 防火墙相关

    防火墙 开放端口 firewall-cmd –zone=public –add-port=5672/tcp –permanent # &#x5F00;&#x6…

    Java 2023年6月7日
    088
  • 【源码】按照自己的思路研究Spring AOP源码 ②

    问题的提出 哪一步导致了顺序的改变 AbstractAdvisorAutoProxyCreator.sortAdvisors()方法 总结 问题的提出 按照自己的思路研究Sprin…

    Java 2023年6月8日
    0170
  • 20220722-Java构造器

    Java构造器知识总结 来源:B站韩顺平老师Java入门教学 代码示例 class Person { int age; String name; public Person(int…

    Java 2023年6月15日
    086
  • 代码优化记录

    代码优化记录 神龟虽寿,犹有竟时。 神龟虽寿 犹有竟时 Original: https://www.cnblogs.com/taojietaoge/p/15853508.htmlA…

    Java 2023年6月5日
    084
  • Markown的语法

    1.下载一个文本编辑器 Markdown ,界面非常干净。 1)使用一级标题(一个 “#” 号表示一级标题,依次类推!) 二级标题 字体 (在文字的两边加 …

    Java 2023年6月8日
    0113
  • JavaWeb-Servlet(1)

    Web-Servlet(1) 获取参数 大致流程 在WEB-INF同级下新建一个html文件,写一个表单 hello 名称 价格 库存 备注 在src下新建一个类(AddSevle…

    Java 2023年6月5日
    084
  • Java 可变参数

    Java 可变参数 可变参数即:成员方法支持最少 0个或多个同类型的参数 在我们不确定形参的数量时就可以使用可变参数 可变参数的语法 class VarParameter { pu…

    Java 2023年6月5日
    076
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球