自己实现 SpringMVC 底层机制 系列之--实现任务阶段 2- 完成客户端浏览器可以请求控制层

news2024/11/13 16:34:00

😀前言
本文是自己实现 SpringMVC 底层机制的第二篇之完成实现任务阶段 2- 完成客户端浏览器可以请求控制层

🏠个人主页:尘觉主页
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-TabAxc96-1692497234107)(https://picgoowyx.oss-cn-guangzhou.aliyuncs.com/imags/202308152043025.png)]

🧑个人简介:大家好,我是尘觉,希望我的文章可以帮助到大家,您的满意是我的动力😉😉

在csdn获奖荣誉: 🏆csdn城市之星2名
⁣⁣⁣⁣ ⁣⁣⁣⁣ ⁣⁣⁣⁣ ⁣⁣⁣⁣ ⁣⁣⁣⁣ ⁣⁣⁣⁣ ⁣⁣⁣⁣ ⁣⁣⁣⁣ 💓Java全栈群星计划top前5
⁣⁣⁣⁣ ⁣⁣⁣⁣ ⁣⁣⁣⁣ ⁣⁣⁣⁣ ⁣⁣⁣⁣ ⁣⁣⁣⁣ ⁣⁣⁣⁣ ⁣⁣⁣⁣ 🤗 端午大礼包获得者

💕欢迎大家:这里是CSDN,我总结知识的地方,欢迎来到我的博客,感谢大家的观看🥰
如果文章有什么需要改进的地方还请大佬不吝赐教 先在次感谢啦😊

文章目录

  • 🥰自己实现 SpringMVC 底层机制 系列之--实现任务阶段 2- 完成客户端浏览器可以请求控制层
    • 😀 创建 自己的 Controller 和自定义注解
      • ● 分析示意图
      • 代码实现
        • 创建MonsterController.java
        • 创建自定义注解Controller
        • 创建自定义注解RequestMapping
        • 配置 wyxspringmvc.xml
    • 😉编写 XMLParser 工具类,可以解析 wyxspringmvc.xml
      • 创建XMLPaser.java类
      • 创建WyxSpringMvcTest
    • 💖开发 WyxWebApplicationContext,充当 Spring 容器-得到扫描类的全路径列
      • 扫描后的
      • 创建WyxWebApplicationContext.java
      • 修改WyxDispatcherServlet.java类
      • 启动 Tomcat 完成测试,
    • 💝完善 WyxWebApplicationContext,充当 Spring 容器-实例化对象到容器中
      • 完成测试
    • 💞完成请求 URL 和控制器方法的映射关系
      • 示意图分析
      • 将配置的@RequestMapping 的 url 和 对应的 控制器-方法 映射关系保存到集合中
      • -如图
        • 创建WyxHandler 类
        • 修改WyxDispatcherServlet.java类
        • 完成测试
    • 💕完成 WyxDispatcherServlet 分发请求到对应控制器方法
      • 示意图
      • 修改WyxDispatcherServlet.java类
      • 完成测试(启动 Tomcat)
      • 增加方法和控制器再看看, 创建OrderController.java
    • 😄总结

🥰自己实现 SpringMVC 底层机制 系列之–实现任务阶段 2- 完成客户端浏览器可以请求控制层

😀 创建 自己的 Controller 和自定义注解

● 分析示意图

img

代码实现

创建MonsterController.java

public class MonsterController {
    public void listMonsters(HttpServletRequest request, HttpServletResponse
            response) {
        response.setContentType("text/html;charset=utf-8");
        try {
            PrintWriter printWriter = response.getWriter();
            printWriter.write("<h1>妖怪列表</h1>");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

创建自定义注解Controller

annotation\Controller.java

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Controller {
String value() default "";
}

创建自定义注解RequestMapping

annotation\RequestMapping

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface RequestMapping {
String value() default "";
}

配置 wyxspringmvc.xml

在该文件指定,我们的 springmvc 要扫描的包

<?xml version="1.0" encoding="UTF-8" ?>
    <beans>
        <component-scan base-package="com.wyxedu.controller"></component-scan>
    </beans>

😉编写 XMLParser 工具类,可以解析 wyxspringmvc.xml

完成功能说明: -编写 XMLParser 工具类, 可以解析 wyxringmvc.xml, 得到要扫描的包-如图

img

创建XMLPaser.java类

package com.wyxdu.wyxspringmvc.xml;

import org.dom4j.Attribute;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

import java.io.InputStream;

/**
 * XMLParser 用于解析spring配置文件
 */
public class XMLParser {

    public static String getBasePackage(String xmlFile) {

        //这个解析的过程,是前面讲过的
        SAXReader saxReader = new SAXReader();
        //通过得到类的加载路径-》获取到spring配置文件.[对应的资源流]
        InputStream inputStream =
                XMLParser.class.getClassLoader().getResourceAsStream(xmlFile);
        try {
            //得到xmlFile文档
            Document document = saxReader.read(inputStream);
            Element rootElement = document.getRootElement();
            Element componentScanElement =
                    rootElement.element("component-scan");
            Attribute attribute = componentScanElement.attribute("base-package");
            String basePackage = attribute.getText();
            return basePackage;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return "";
    }
}

创建WyxSpringMvcTest

public class HspSpringMvcTest {
    @Test
    public void readXML() {
        String basePackage = XMLPaser.getbasePackage("wyxspringmvc.xml");
        System.out.println("basePackage= " + basePackage);
    }
}

💖开发 WyxWebApplicationContext,充当 Spring 容器-得到扫描类的全路径列

完成的功能说明

img

- 把指定的目录包括子目录下的 java 类的全路径扫描到集合中,比如 ArrayList -如图[对 java 基础知识的使用

扫描后的

classFullPathList=[com.wyxdu.controller.MonsterController, com.wyxedu.service.impl.MonsterServiceImpl, com.wyxedu.service.MonsterService]

创建WyxWebApplicationContext.java

public class WyxWebApplicationContext {
private ArrayList<String> classFullPathList = new ArrayList

public void init() {
        //这里是写的固定的spring容器配置文件.?=>做活
        String basePackage = XMLParser.getBasePackage("wyxspringmvc.xml");

        //这时basePackage => com.wyxdu.controller,com.wyxdu.service
        String[] basePackages = basePackage.split(",");
        //遍历basePackages, 进行扫描
        if (basePackages.length > 0) {
            for (String pack : basePackages) {
                scanPackage(pack);//扫描
            }
        }
        System.out.println("扫描后的= classFullPathList=" + classFullPathList);
    }

 public void scanPackage(String pack) {

        //得到包所在的工作路径[绝对路径]
        //下面这句话的含义是 通过类的加载器,得到你指定的包对应的 工作路径[绝对路径]
        //比如 "com.hspedu.controller" => url 是 D:\hspedu_springmvc\hsp-springmvc\target\hsp-springmvc\WEB-INF\classes\com\hspedu\controller
        //细节说明: 1. 不要直接使用Junit测试, 否则 url null
        //             2. 启动tomcat来吃测试
        URL url =
                this.getClass().getClassLoader()
                        .getResource("/" + pack.replaceAll("\\.", "/"));

        System.out.println("urlss=" + url);
        //根据得到的路径, 对其进行扫描,把类的全路径,保存到classFullPathList

        String path = url.getFile();
        System.out.println("path= " + path);
        //在io中,把目录,视为一个文件
        File dir = new File(path);
        //遍历dir[文件/子目录]
        for (File f : dir.listFiles()) {
            if (f.isDirectory()) {//如果是一个目录,需要递归扫描
                scanPackage(pack + "." + f.getName());
            } else {
                //说明:这时,你扫描到的文件,可能是.class, 也可能是其它文件
                //就算是.class, 也存在是不是需要注入到容器
                //目前先把文件的全路径都保存到集合,后面在注入对象到容器时,再处理
                String classFullPath =
                        pack + "." + f.getName().replaceAll(".class", "");
                classFullPathList.add(classFullPath);
            }
        }

    }


}

修改WyxDispatcherServlet.java类

@Override
public void init(ServletConfig servletConfig) throws ServletException {
         //创建自己的spring容器
        wyxWebApplicationContext =
                new WyxWebApplicationContext(configLocation);

        wyxWebApplicationContext.init();
}

启动 Tomcat 完成测试,

看看扫描是否成功. 需要使用 Tomcat 启动方式完成测试,直接用 Junit 测试 URL 是null

15:03:30.297 信 息 [RMI TCP Connection(3)-127.0.0.1]
org.apache.jasper.servlet.TldScanner.scanJars At least one JAR was scanned for TLDs yet
contained no TLDs. Enable debug logging for this logger for a complete list of JARs that were
scanned but no TLDs were found in them. Skipping unneeded JARs during scanning can
improve startup time and JSP compilation time.

.扫描后

classFullPathList=[com.hspedu.controller.MonsterController, com.wyxdu.service.impl.MonsterServiceImpl, com.wyxdu.service.MonsterService]

💝完善 WyxWebApplicationContext,充当 Spring 容器-实例化对象到容器中

 public void init() {
        String basePackage = XMLParser.getBasePackage("wyxspringmvc.xml");

        //这时basePackage => com.wyxdu.controller,com.wyxdu.service
        String[] basePackages = basePackage.split(",");
        //遍历basePackages, 进行扫描
        if (basePackages.length > 0) {
            for (String pack : basePackages) {
                scanPackage(pack);//扫描
            }
        }
        System.out.println("扫描后的= classFullPathList=" + classFullPathList);
        //将扫描到的类, 反射到ico容器
        executeInstance();
        System.out.println("扫描后的 ioc容器= " + ioc);
}

public void executeInstance() {
        //判断是否扫描到类
        if (classFullPathList.size() == 0) {//说明没有扫描到类
            return;
        }
        try {
            //遍历classFullPathList,进行反射
            for (String classFullPath : classFullPathList) {
                Class<?> clazz = Class.forName(classFullPath);
                //说明当前这个类有@Controller
                if (clazz.isAnnotationPresent(Controller.class)) {
                    //得到类名首字母小写
                    String beanName = clazz.getSimpleName().substring(0, 1).toLowerCase() +
                            clazz.getSimpleName().substring(1);
                    ioc.put(beanName, clazz.newInstance());
                } //如果有其它的注解,可以扩展 , 来处理@Service
                else if()
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

完成测试

(提示: 启动 tomcat 来加载 WyxDispatcherServlet 的方式测试

扫描后的 ioc容器= {goodsController=com.wyxdu.controller.xx.GoodsController@29e91c96,

💞完成请求 URL 和控制器方法的映射关系

示意图分析

img

将配置的@RequestMapping 的 url 和 对应的 控制器-方法 映射关系保存到集合中

-如图

handlerList初始化的结果= [WyxHandler{url=‘/order/list’, controller=com.wyxdu.controller.OrderController@79b8c11d, method=public void com.wyxdu.controller.OrderController.listOrder(javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse)

创建WyxHandler 类

public class WyxHandler {
    private String url;
    private Object controller;
    private Method method;

    public WyxHandler(String url, Object controller, Method method) {
        this.url = url;
        this.controller = controller;
        this.method = method;
    }

    public WyxHandler() {
    }

    public String getUrl() {
        return url;
    }

    public void setUrl(String url) {
        this.url = url;
    }

    public Object getController() {
        return controller;
    }

    public void setController(Object controller) {
        this.controller = controller;
    }

    public Method getMethod() {
        return method;
    }

    public void setMethod(Method method) {
        this.method = method;
    }

    @Override
    public String toString() {
        return "WyxHandler{" +
                "url='" + url + '\'' +
                ", controller=" + controller +
                ", method=" + method +
                '}';
    }
}

修改WyxDispatcherServlet.java类

public class WyxDispatcherServlet extends HttpServlet {

    //定义属性 handlerList , 保存HspHandler[url和控制器方法的映射]
    private List<WyxHandler> handlerList =
            new ArrayList<>();
    //定义属性 wyxWebApplicationContext,自己的spring容器
    WyxWebApplicationContext wyxWebApplicationContext = null;

    @Override
    public void init(ServletConfig servletConfig) throws ServletException {

        //创建自己的spring容器
        wyxWebApplicationContext =
                new WyxWebApplicationContext();

        wyxWebApplicationContext.init();

        //调用 initHandlerMapping , 完成url和控制器方法的映射

        initHandlerMapping();
        //输出handlerList
        System.out.println("handlerList初始化的结果= " + handlerList);
    }

    private void initHandlerMapping() {
        if(wyxWebApplicationContext.ioc.isEmpty()) {
            throw new RuntimeException("spring ioc 容器为空");
        }
        for(Map.Entry<String,Object> entry:
                wyxWebApplicationContext.ioc.entrySet()) {
             //先取出注入的Object的clazz对象
            Class<?> clazz = entry.getValue().getClass();

            //如果注入的Bean是Controller
            if(clazz.isAnnotationPresent(Controller.class)) {

                //取出它的所有方法
                Method[] declaredMethods = clazz.getDeclaredMethods();
                //遍历方法
                for (Method declaredMethod : declaredMethods) {
                 //判断该方法是否有@RequestMapping
                    if(declaredMethod.isAnnotationPresent(RequestMapping.class)) {
                        //取出@RequestMapping值->就是映射路径
                        RequestMapping requestMappingAnnotation =
                                declaredMethod.getAnnotation(RequestMapping.class);
                        //这里小伙伴可以把工程路径+url
                        //getServletContext().getContextPath()
                        // /springmvc/monster/list

                        String url = requestMappingAnnotation.value();

                        handlerList.add(new
                                WyxHandler(url,entry.getValue(),declaredMethod));
                    }
                }
            }
        }
}

完成测试

(启动 Tomcat , 加载 HspDispatcherServlet 方式), 测试结果前面已经展示了

💕完成 WyxDispatcherServlet 分发请求到对应控制器方法

示意图

img

当用户发出请求,根据用户请求 url 找到对应的控制器-方法, 并反射调用

img

- 如果用户请求的路径不存在,返回 404

img

修改WyxDispatcherServlet.java类

  @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doPost(req, resp);
        }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //System.out.println("--WyxDispatcherServlet--doPost---");
        //调用方法,完成分发请求
        executeDispatch(req, resp);
    }

    private void executeDispatch(HttpServletRequest req,
                                 HttpServletResponse response) {
        WyxHandler wyxHandler = getWyxHandler(req);
        try {
            if (null == wyxHandler) {//没有匹配的 Handler
                response.getWriter().print("<h1>404 NOT FOUND</h1>");
            } else {//有匹配的 Handler, 就调用
                wyxHandler.getMethod().invoke(wyxHandler.getController(), req,
                        response);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

   private WyxHandler getWyxHandler(HttpServletRequest request) {
        //1.先获取的用户请求的uri 比如http://localhost:8080/springmvc/monster/list
        //  uri = /springmvc/monster/list
        //2. 这里要注意得到uri 和 保存url 是有一个工程路径的问题
        // 两个方案解决 =>第一个方案: 简单 tomcat 直接配置 application context =>/
        // 第二个方案 保存 hsphandler对象 url 拼接 getServletContext().getContextPath()
        String requestURI = request.getRequestURI();
        //遍历handlerList
        for (WyxHandler wyxHandler : handlerList) {
            if (requestURI.equals(wyxHandler.getUrl())) {//说明匹配成功
                return wyxHandler;
            }
        }
        return null;
    }

    private void initHandlerMapping() {
        if(wyxWebApplicationContext.ioc.isEmpty()) {
            throw new RuntimeException("spring ioc 容器为空");
        }
        for(Map.Entry<String,Object> entry:
                wyxWebApplicationContext.ioc.entrySet()) {
             //先取出注入的Object的clazz对象
            Class<?> clazz = entry.getValue().getClass();

            //如果注入的Bean是Controller
            if(clazz.isAnnotationPresent(Controller.class)) {

                //取出它的所有方法
                Method[] declaredMethods = clazz.getDeclaredMethods();
                //遍历方法
                for (Method declaredMethod : declaredMethods) {
                 //判断该方法是否有@RequestMapping
                    if(declaredMethod.isAnnotationPresent(RequestMapping.class)) {
                        //取出@RequestMapping值->就是映射路径
                        RequestMapping requestMappingAnnotation =
                                declaredMethod.getAnnotation(RequestMapping.class);
                        //这里小伙伴可以把工程路径+url
                        //getServletContext().getContextPath()
                        // /springmvc/monster/list

                        String url = requestMappingAnnotation.value();

                        handlerList.add(new
                                WyxHandler(url,entry.getValue(),declaredMethod));
                    }
                }
            }
        }
    }

完成测试(启动 Tomcat)

img

img

增加方法和控制器再看看, 创建OrderController.java

@Controller
public class OrderController {

    @RequestMapping(value = "/order/list")
    public void listOrder(HttpServletRequest request,
                          HttpServletResponse response)  {
        //设置编码和返回类型
        response.setContentType("text/html;charset=utf-8");
        //获取writer返回信息
        try {
            PrintWriter printWriter = response.getWriter();
            printWriter.write("<h1>订单列表信息</h1>");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @RequestMapping(value = "/order/add")
    public void addOrder(HttpServletRequest request,
                          HttpServletResponse response)  {
        //设置编码和返回类型
        response.setContentType("text/html;charset=utf-8");
        //获取writer返回信息
        try {
            PrintWriter printWriter = response.getWriter();
            printWriter.write("<h1>添加订单...</h1>");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

在这里插入图片描述

img

😄总结

本篇完成了任务阶段 2- 完成客户端浏览器可以请求控制层下一篇为实现任务阶段 3- 从 web.xml动态获取 wyxspringmvc.xml

😉 自己实现 SpringMVC 底层机制 核心分发 控制器+ Controller 和 Service 注入容器 + 对象自动装配 + 控制器 方法获取参数 + 视图解析 + 返回 JSON 格式数系列

第一篇->自己实现 SpringMVC 底层机制 系列之搭建 SpringMVC 底层机制开发环境和开发 WyxDispatcherServlet_springmvc分发器

😁热门专栏推荐
想学习vue的可以看看这个

java基础合集

数据库合集

redis合集

nginx合集

linux合集

等等等还有许多优秀的合集在主页等着大家的光顾感谢大家的支持

🤔欢迎大家加入我的社区 尘觉社区

文章到这里就结束了,如果有什么疑问的地方请指出,诸佬们一起来评论区一起讨论😁
希望能和诸佬们一起努力,今后我们一起观看感谢您的阅读🍻
如果帮助到您不妨3连支持一下,创造不易您们的支持是我的动力🤞

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/902243.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Spring MVC异常处理

Spring MVC异常处理 Spring MVC异常处理机制HandlerExceptionResolver的实现类DefaultHandlerExceptionResolver实现类DefaultHandlerExceptionResolver 在Controller的请求处理方法中手动使用try…catch块捕捉异常&#xff0c;当捕捉到指定的异常时&#xff0c;系统返回对应的…

ABBYY FineReader15最新专业的PDF OCR图片文字识别软件

ABBYY FineReader PDF15是专业的OCR图片文字识别软件&#xff0c;可以快速、准确、方便地将扫描纸质文件、PDF格式及数字或移动电话图像转换成可编辑格式——Microsoft Word、Excel、PowerPoint、可检索的PDF、HTML、DjVu等。99.8%的识别准确率即刻识别文本&#xff0c;复制和粘…

Stanley 轨迹跟踪算法研究

Stanley 轨迹跟踪算法研究 理论基础 首先还是阅读论文 《基于改进鲸鱼优化算法的Stanley算法研究》 《复杂环境下的移动机器人路径规划技术研究》 《Stanley:The Robot that Won the DARPA Grand Challenge》 《无人驾驶汽车轨迹跟随控制研究》 《基于混合算法的校园智能车路…

【kafka】-分区-消费端负载均衡

一.为什么kafka要做分区&#xff1f; 因为当一台机器有可能扛不住&#xff08;类比&#xff1a;就像redis集群中的redis-cluster一样&#xff0c;一个master抗不住写&#xff0c;那么就多个master去抗写&#xff09;&#xff0c;把一个队列的单一master变成多个master&#xf…

学习嵌入式

最近&#xff0c;打算了解一些关于嵌入式的知识。这里先了解嵌入式到底是什么。

[ MySQL ] — 常见函数的使用

目录 日期函数 current_date — 获取当前日期 current_time — 获取当前时间 current_timestamp — 获取当前时间戳 date — 获取参数的日期部分 ​编辑 date_add — 在日期或时间的基础上进行增加 date_sub — 在日期或时间的基础上进行减少 datediff — 计算两个日期相差…

快速上手Linux核心命令:Linux系统信息相关命令

前言 这期呢主要说一说Linux中与系统相关的命令&#xff0c;一共包含10个命令 uname 显示系统信息 1、简介 uname命令用于显示系统相关信息&#xff0c;比如内核版本号、硬件架构等 2、语法格式 uname [参数选项] 3、参数说明 参数参数说明-a显示系统所有相关信息-m显示计算…

通过重构来加深理解——DDD

要想成功地开发出实用的模型&#xff0c;需要注意以下三点&#xff1a; &#xff08;1&#xff09;复杂巧妙的领域模型是可以实现的&#xff0c;也是值得我们去花费力气实现的。 &#xff08;2&#xff09;这样的模型离开不断的重构是很难开发出来的&#xff0c;重构需要领域专…

2. Linux Server 20.04 Qt5.14.2配置Jetson Orin Nano Developer Kit 交叉编译环境

最近公司给了我一块Jetson Orin Nano的板子&#xff0c;先刷了系统&#xff08;1.Jetson Orin Nano Developer Kit系统刷机&#xff09;又让我搭建交叉编译环境&#xff0c;所以有了下面的文章 一 :Qt5.14.2交叉编译环境安装 1.准备 1.1设备环境 1.1.1 Server: Ubuntu20.0…

md文本学习

这里写自定义目录标题 欢迎使用Markdown编辑器新的改变功能快捷键合理的创建标题&#xff0c;有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、居左、居右SmartyPants 创建一个自定义列表如何创建一个…

腾讯云轻量应用服务器配置_网站上线全流程

腾讯云轻量应用服务器CPU内存带宽配置高&#xff0c;成本很低&#xff0c;腾讯云百科来详细说下腾讯云服务器从购买、配置到网站上线全流程&#xff0c;包括轻量服务器配置选择、应用镜像选择、重置密码、防火墙开放端口教程等详细教程&#xff1a; 目录 一&#xff1a;注册腾…

年薪100w的项目组合和项目集经理与项目经理的区别

项目经理未来的发展是什么&#xff1f;很多人经常问&#xff0c;专业的路可以是项目集&#xff0c;项目组合经理&#xff0c;也可以是PMO等等。为什么项目集经理&#xff0c;项目组合经理就挣得比较多呢&#xff1f;今天为大家一一揭秘&#xff01; 项目经理、项目集经理和项目…

【2023年11月第四版教材】《第5章-信息系统工程(合集篇)》

《第5章-信息系统工程&#xff08;合集篇&#xff09;》 章节说明1 软件工程1.1 架构设计1.2 需求分析1.3 软件设计1.4 软件实现&#xff3b;补充第三版教材内容&#xff3d; 1.5 部署交付 2 数据工程2.1 数据建模2.2 数据标准化2.3 数据运维2.4 数据开发利用2.5 数据库安全 3 …

攻防世界-backup

原题 解题思路 备份文件后缀大多是bak、git、svn、swp等&#xff0c;尝试index.php.bak就有文件下载了:

文件型数据库Derby操作示例

1.下载db-derby-10.14.2.0-bin.zip 2.启动数据库&#xff0c;两种方式 1) 可执行程序 Windows可以运行ij.bat, Linux可以运行ij Ij.bat, ij在bin目录里 2&#xff09;通过执行jar包形式启动 Derbyrun.jar在lib目录里 执行Java -jar derbyrun.jar ij 启动 2. 连接数据库 …

除了提升编码能力,养成这4个工作习惯,让你成为更优秀的前端开发者

如果你想成为一名优秀的前端开发者&#xff0c;你需要拥有不仅仅是技术知识。如今&#xff0c;由于谷歌和其他资源的存在&#xff0c;获取技术知识比以前更容易了。而真正能够产生差异的是习惯。就像心理强度对于个人成长很重要一样&#xff0c;有些习惯可以让你成为一个更有效…

七夕最强Python表白代码来了

点击上方Python小二&#xff0c;选择星标公众号 干货速达&#xff0c;不迷路 快到七夕了&#xff0c;大家都懂&#xff0c;这里不过多解释了&#xff0c;送大家几段节日专属Python代码。 玫瑰 毫无疑问&#xff0c;玫瑰一直都是七夕、520......这类节日的专属&#xff0c;带文字…

最长公共子序列——力扣1143

解法:动态规划 int longestCommonSubsequence(string text1, string text2){int m=text1.size(), n=text2.size

高等数学上册 第九章 多元函数微分法及其应用 知识点总结

多元函数微分法及其应用 &#xff08; 1 &#xff09;多元函数的极限&#xff1a; 用“ ε − δ ”语言描述&#xff0c;二元函数的极限叫二重极限 二重极限存在&#xff1a; { 1 、 P ( x , y ) 一定要以任何方式趋于 ( x 0 , y 0 ) 时&#xff0c; f ( x , y ) 无限趋近于 A…

flutter:webview_flutter和flutter_inappwebview的简单使用

前言 最近在研究如何在应用程序中嵌入Web视图&#xff0c;发现有两个库不错。 一个是官方维护、一个是第三方维护。因为没说特别的需求&#xff0c;就使用了官方库&#xff0c;实现一些简单功能是完全ok的 webview_flutter 不建议使用&#xff0c;因为效果不怎么样&#xf…