实现SpringMVC底层机制(一)

news2025/1/4 19:59:27

文章目录

    • 1.环境配置
        • 1.创建maven项目
        • 2.创建文件目录
        • 3.导入jar包
    • 2.开发核心控制器
        • 文件目录
        • 1.流程图
        • 2.编写核心控制器SunDispatcherServlet.java
        • 3.类路径下编写spring配置文件sunspringmvc.xml
        • 4.配置中央控制器web.xml
        • 5.配置tomcat,完成测试
          • 1.配置发布方式
          • 2.配置热加载
          • 3.修改SunDispatcherServlet.java
          • 4.完成测试
    • 3.完成客户端/浏览器可以请求控制层
        • 文件目录
        • 1.思路分析
        • 2.编写MonsterController.java
        • 3.自定义注解
          • 1.Controller.java
          • 2.RequestMapping.java
        • 4.自定义容器(1),在tomcat启动时读取配置文件,获取要扫描的包的工作路径
          • 1.SunWebApplicationContext.java
          • 2.修改SunDispatcherServlet.java
          • 3.单元测试,启动tomcat
        • 5.自定义容器(2),在tomcat启动的时候完成对指定包的扫描
          • 1.修改SunWebApplicationContext.java
          • 2.debug测试
        • 6.将自定义容器(3),符合要求的类反射创建对象,放到单例池
          • 1.修改SunWebApplicationContext.java增加方法,添加属性
          • 2.debug查看单例池
        • 7.完成url和控制器方法映射
          • 1.创建映射bean,SunHandler.java
          • 2.修改中央控制器SunWebApplicationContext.java添加方法和属性
          • 3.debug查看映射对象列表
        • 8.完成请求分发到目标方法
          • 1.修改SunDispatcherServlet.java,添加两个方法并在dopost中请求分发
          • 2.单元测试
    • 4.当前阶段完成的功能
        • 1.初始化阶段
        • 2.完成请求分发

1.环境配置

1.创建maven项目

image-20240227084815460

2.创建文件目录

image-20240227085226577

3.导入jar包
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>org.example</groupId>
  <artifactId>sun-springmvc</artifactId>
  <packaging>war</packaging>
  <version>1.0-SNAPSHOT</version>
  <name>sun-springmvc Maven Webapp</name>
  <url>http://maven.apache.org</url>
  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>3.8.1</version>
      <scope>test</scope>
    </dependency>
    <!--servlet原生api-->
    <dependency>
      <groupId>javax.servlet</groupId>
      <artifactId>javax.servlet-api</artifactId>
      <version>3.1.0</version>
      <!--在项目打包时不会带上这个jar-->
      <scope>provided</scope>
    </dependency>
    <!--解析xml-->
    <dependency>
      <groupId>dom4j</groupId>
      <artifactId>dom4j</artifactId>
      <version>1.6.1</version>
    </dependency>
    <!--常用工具类-->
    <dependency>
      <groupId>org.apache.commons</groupId>
      <artifactId>commons-lang3</artifactId>
      <version>3.5</version>
    </dependency>
  </dependencies>
  <build>
    <finalName>sun-springmvc</finalName>
  </build>
</project>

2.开发核心控制器

文件目录

image-20240227095105084

1.流程图

image-20240227093109208

2.编写核心控制器SunDispatcherServlet.java
package com.Sun.sunspringmvc.servlet;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * 充当中央控制器
 *
 * @author 孙显圣
 * @version 1.0
 */
public class SunDispatcherServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        super.doGet(req, resp);
    }

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

3.类路径下编写spring配置文件sunspringmvc.xml
4.配置中央控制器web.xml
<!DOCTYPE web-app PUBLIC
 "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
 "http://java.sun.com/dtd/web-app_2_3.dtd" >

<web-app>
  <display-name>Archetype Created Web Application</display-name>

  <!--配置中央控制器-->
  <servlet>
    <servlet-name>SunDispatcherServlet</servlet-name>
    <servlet-class>com.Sun.sunspringmvc.servlet.SunDispatcherServlet</servlet-class>
    <!--init—param设置spring配置文件的位置-->
    <init-param>
      <param-name>contextConfigLocation</param-name>
      <param-value>classpath:sunspringmvc.xml</param-value>
    </init-param>
    <!--服务器启动时实例化servlet,将其放到容器中,并且调用init方法-->
    <load-on-startup>1</load-on-startup>
  </servlet>
  <servlet-mapping>
    <servlet-name>SunDispatcherServlet</servlet-name>
    <!--拦截所有请求-->
    <url-pattern>/</url-pattern>
  </servlet-mapping>


</web-app>

5.配置tomcat,完成测试
1.配置发布方式

image-20240227092658306

2.配置热加载

image-20240227092725037

3.修改SunDispatcherServlet.java

image-20240227092846449

4.完成测试

image-20240227092956993

image-20240227093009005

3.完成客户端/浏览器可以请求控制层

文件目录

image-20240227165505347

1.思路分析

image-20240227143426184

2.编写MonsterController.java
package com.Sun.controller;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;

/**
 * @author 孙显圣
 * @version 1.0
 */
public class MonsterController {
    public void listMonster(HttpServletRequest request, HttpServletResponse response) {
        //设置mine类型
        response.setContentType("text/html;charset=utf-8");
        try {
            PrintWriter writer = response.getWriter();
            writer.write("<h1>妖怪列表信息</h1>");
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
}

3.自定义注解
1.Controller.java
package com.Sun.sunspringmvc.annotation;

import java.lang.annotation.*;

/**
 * 用于标识一个Controller
 *
 * @author 孙显圣
 * @version 1.0
 */
@Target(ElementType.TYPE) //作用于类型
@Retention(RetentionPolicy.RUNTIME) //作用范围
@Documented
public @interface Controller {
}

2.RequestMapping.java
package com.Sun.sunspringmvc.annotation;

import java.lang.annotation.*;

/**
 * 用于指定映射路径
 *
 * @author 孙显圣
 * @version 1.0
 */
@Target(ElementType.METHOD) //作用于方法
@Retention(RetentionPolicy.RUNTIME) //作用范围
@Documented
public @interface RequestMapping {
}

4.自定义容器(1),在tomcat启动时读取配置文件,获取要扫描的包的工作路径
1.SunWebApplicationContext.java
package com.Sun.sunspringmvc.context;

import com.Sun.sunspringmvc.xml.XmlParser;

import java.net.URL;
import java.util.ArrayList;
import java.util.List;

/**
 * @author 孙显圣
 * @version 1.0
 */
public class SunWebApplicationContext {
    //存放所有要扫描的包下的class文件的全路径
    private List<String> classFullPathList = new ArrayList<String>();

    //初始化容器
    public void init() {
        //读取spring配置文件,获取要扫描的包的信息
        String basePage = XmlParser.getBasePage("sunspringmvc.xml");
        //完成对指定包的扫描
        scanPage(basePage);
    }

    //创建方法,完成对指定包的扫描,获取所有class文件的全路径
    public void scanPage(String packFullName) {
        //将包的全类名中的点替换为斜杠
        String packPath = packFullName.replaceAll("\\.", "/");

        //通过类加载器来获取这个包的工作路径,就是获取工作路径下的类路径下的文件路径
        URL resource = SunWebApplicationContext.class.getClassLoader().getResource(packPath);
        System.out.println(resource);
    }
}

2.修改SunDispatcherServlet.java
package com.Sun.sunspringmvc.servlet;

import com.Sun.sunspringmvc.context.SunWebApplicationContext;

import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * 充当中央控制器
 *
 * @author 孙显圣
 * @version 1.0
 */
public class SunDispatcherServlet extends HttpServlet {
    @Override
    public void init(ServletConfig config) throws ServletException {
        //初始化容器
        SunWebApplicationContext sunWebApplicationContext = new SunWebApplicationContext();
        sunWebApplicationContext.init();

    }

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("doGet");
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("doPost");
    }
}

3.单元测试,启动tomcat

image-20240227133426603

5.自定义容器(2),在tomcat启动的时候完成对指定包的扫描
1.修改SunWebApplicationContext.java
package com.Sun.sunspringmvc.context;

import com.Sun.sunspringmvc.xml.XmlParser;

import java.io.File;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;

/**
 * @author 孙显圣
 * @version 1.0
 */
public class SunWebApplicationContext {
    //存放所有要扫描的包下的class文件的全路径
    private List<String> classFullPathList = new ArrayList<String>();

    //初始化容器
    public void init() {
        //读取spring配置文件,获取要扫描的包的信息
        String basePage = XmlParser.getBasePage("sunspringmvc.xml");
        //初始化容器
        //根据逗号进行分割,得到多个要扫描的包的全路径,遍历将里面的class文件全路径放到列表中
        String[] split = basePage.split(",");
        for (String packPath : split) {
            scanPage(packPath);
        }
    }

    //创建方法,完成对指定包的扫描,获取所有class文件的全路径
    public void scanPage(String packFullName) {
        //将包的全类名中的点替换为斜杠
        String packPath = packFullName.replaceAll("\\.", "/");

        //通过类加载器来获取这个包的工作路径,就是获取工作路径下的类路径下的文件路径
        URL url = SunWebApplicationContext.class.getClassLoader().getResource(packPath);
        //得到路径
        String file = url.getFile();
        //根据这个文件夹来创建一个file对象,从而遍历里面所有的class文件得到所有class文件的全路径
        File packDirectory = new File(file);
        if (packDirectory.isDirectory()) {
            //如果是文件夹则列出里面的所有文件对象
            File[] files = packDirectory.listFiles();
            //遍历这些文件对象,实际上就那个包下的所有class文件对象
            for (File classFile : files) {
                //如果这里的文件对象还是文件夹,则进行递归扫描
                if (classFile.isDirectory()) {
                    scanPage(packFullName + "." + classFile.getName());
                } else {
                    //如果这里的文件对象指的都是文件,则将其放到classFullPathList中
                    //得到当前文件的全类名 = 包的全路径 + class文件的名字去掉.class
                    String classFullPath = packFullName + "." + classFile.getName().replaceAll(".class", "");
                    //放到列表中
                    classFullPathList.add(classFullPath);
                }
            }
        }
    }

}

2.debug测试

image-20240227143135578

6.将自定义容器(3),符合要求的类反射创建对象,放到单例池
1.修改SunWebApplicationContext.java增加方法,添加属性

image-20240227145800640

    //编写方法,将符合要求的类反射创建对象,并封装到单例池中
    public void executeInstance(){
        //遍历所有全类名
        for (String classPath : classFullPathList) {
            try {
                //反射
                Class<?> aClass = Class.forName(classPath);
                //判断是否有Controller注解
                if (aClass.isAnnotationPresent(Controller.class)) {
                    //有注解,当他是单例的,反射创建bean对象,放到单例池中,默认首字母小写
                    //获取类名首字母小写
                    String name = aClass.getSimpleName().substring(0, 1).toLowerCase() + aClass.getSimpleName().substring(1);
                    //放到单例池中
                    singleObjects.put(name, aClass.newInstance());
                }
            } catch (ClassNotFoundException e) {
                throw new RuntimeException(e);
            } catch (InstantiationException e) {
                throw new RuntimeException(e);
            } catch (IllegalAccessException e) {
                throw new RuntimeException(e);
            }
        }
    }

2.debug查看单例池

image-20240227145600884

7.完成url和控制器方法映射
1.创建映射bean,SunHandler.java
package com.Sun.sunspringmvc.handler;

import java.lang.reflect.Method;

/**
 * 用于存放有注解的类的映射信息
 *
 * @author 孙显圣
 * @version 1.0
 */
public class SunHandler {
    private String url; //映射的url
    private Object controller; //controller对象
    private Method method; //方法对象,用于反射调用方法

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

    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 "SunHandler{" +
                "url='" + url + '\'' +
                ", controller=" + controller +
                ", method=" + method +
                '}';
    }
}

2.修改中央控制器SunWebApplicationContext.java添加方法和属性

image-20240227155457879

    //初始化映射对象列表,获取映射对象并且将其放到映射列表中
    private void initHandlerMapping() {
        //判断单例池是否为空
        if (sunWebApplicationContext.singleObjects.isEmpty()) {
            return;
        }
        //取出单例池里的所有对象
        for (Map.Entry<String, Object> entry : sunWebApplicationContext.singleObjects.entrySet()) {
            //反射
            Class<?> aClass = entry.getValue().getClass();
            //判断是否有colltroller注解
            if (aClass.isAnnotationPresent(Controller.class)) {
                //反射获取所有方法对象
                Method[] declaredMethods = aClass.getDeclaredMethods();
                //判断方法里是否有requestmapping注解
                for (Method declaredMethod : declaredMethods) {
                    if (declaredMethod.isAnnotationPresent(RequestMapping.class)) {
                        //获取这个方法的注解信息
                        String url = declaredMethod.getAnnotation(RequestMapping.class).value();
                        //将信息封装到映射bean对象中
                        SunHandler sunHandler = new SunHandler(url, entry.getValue(), declaredMethod);
                        //添加到列表中
                        handlers.add(sunHandler);
                    }
                }
            }
        }
    }
3.debug查看映射对象列表

8.完成请求分发到目标方法
1.修改SunDispatcherServlet.java,添加两个方法并在dopost中请求分发
package com.Sun.sunspringmvc.servlet;

import com.Sun.sunspringmvc.annotation.Controller;
import com.Sun.sunspringmvc.annotation.RequestMapping;
import com.Sun.sunspringmvc.context.SunWebApplicationContext;
import com.Sun.sunspringmvc.handler.SunHandler;

import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * 充当中央控制器
 *
 * @author 孙显圣
 * @version 1.0
 */
public class SunDispatcherServlet extends HttpServlet {
    //存放所有的映射关系
    private List<SunHandler> handlers = new ArrayList<SunHandler>();
    private SunWebApplicationContext sunWebApplicationContext = null;

    @Override
    public void init(ServletConfig config) throws ServletException {
        //初始化容器
        sunWebApplicationContext = new SunWebApplicationContext();
        sunWebApplicationContext.init();
        //初始化映射列表
        initHandlerMapping();
        System.out.println("ss");
    }

    @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 {
        //请求分发
        executeDispatch(req, resp);
    }

    //初始化映射对象列表,获取映射对象并且将其放到映射列表中
    private void initHandlerMapping() {
        //判断单例池是否为空
        if (sunWebApplicationContext.singleObjects.isEmpty()) {
            return;
        }
        //取出单例池里的所有对象
        for (Map.Entry<String, Object> entry : sunWebApplicationContext.singleObjects.entrySet()) {
            //反射
            Class<?> aClass = entry.getValue().getClass();
            //判断是否有colltroller注解
            if (aClass.isAnnotationPresent(Controller.class)) {
                //反射获取所有方法对象
                Method[] declaredMethods = aClass.getDeclaredMethods();
                //判断方法里是否有requestmapping注解
                for (Method declaredMethod : declaredMethods) {
                    if (declaredMethod.isAnnotationPresent(RequestMapping.class)) {
                        //获取这个方法的注解信息
                        String url = declaredMethod.getAnnotation(RequestMapping.class).value();
                        //将信息封装到映射bean对象中
                        SunHandler sunHandler = new SunHandler(url, entry.getValue(), declaredMethod);
                        //添加到列表中
                        handlers.add(sunHandler);
                    }
                }
            }
        }
    }

    //根据请求对象得到映射对象
    private SunHandler getSunHandler(HttpServletRequest request) {
        //获取uri: /sun-springmvc/list/monster
        String requestURI = request.getRequestURI();
        String contextPath = request.getServletContext().getContextPath();
        //遍历映射对象列表,查看列表中是否有这个uri
        for (SunHandler handler : handlers) {
            //这里拼接一个上下文路径
            if ((contextPath + "/" + handler.getUrl()).equals(requestURI)) {
                //返回这个映射对象
                return handler;
            }
        }
        return null;
    }

    //请求分发
    private void executeDispatch(HttpServletRequest request, HttpServletResponse response) {
        //获取映射对象
        SunHandler sunHandler = getSunHandler(request);
        //映射对象不等于空则反射调用controller的方法
        if (sunHandler != null) {
            try {
                sunHandler.getMethod().invoke(sunHandler.getController(), request, response);
            } catch (IllegalAccessException e) {
                throw new RuntimeException(e);
            } catch (InvocationTargetException e) {
                throw new RuntimeException(e);
            }
        } else {
            //当映射对象是空的时候,返回404
            try {
                response.getWriter().write("<h1>404 not found!</h1>");
            } catch (IOException e) {
                throw new RuntimeException(e);
            }

        }
    }
}

2.单元测试

image-20240227164234686

image-20240227164244515

image-20240227164254432

4.当前阶段完成的功能

1.初始化阶段
  • tomcat服务器启动,自动装载中央控制器(servlet),调用init方法
  • 初始化spring容器
    • 创建spring容器实例,调用init方法
    • 读取spring配置文件,得到要扫描的包的工作路径
    • 扫描指定的包,获取所有class文件的全路径
    • 扫描所有class文件,将包含Controller注解的类反射创建对象放到单例池中(这里假设都是单例的)
  • 初始化映射对象列表
    • 扫描所有单例池中的对象
    • 反射获取这个对象对应类的所有方法,如果方法包含RequestMapping注解,则将这个对象,url,Method对象封装到映射对象中,并且添加到映射对象列表
2.完成请求分发
  • 根据请求对象得到映射对象
    • 获取请求的uri
    • 遍历对象映射列表查看是否有匹配的映射对象,如果有则返回映射对象
  • 请求分发
    • 首先根据请求对象得到映射对象
    • 如果得到了就反射调用方法
    • 没有得到则返回404

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

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

相关文章

Vue入门篇:生命周期,钩子函数,工程化开发Vue(脚手架安装),组件化开发(全局注册,局部注册)

目录 1.Vue生命周期和生命周期的四个阶段2.Vue生命周期函数&#xff08;钩子函数)3.工程化开发&脚手架Vue CLI1.在powershell管理员权限下打开命令行安装脚手架&#xff1a;2.查看vue版本&#xff1a;3.创建项目架子4.运行项目 4.组件化开发&根组件1.App.vue文件&#…

JavaSE字节缓冲流

欢迎来到 请回答1024 的博客 &#x1f353;&#x1f353;&#x1f353;欢迎来到 请回答1024的博客 关于博主&#xff1a; 我是 请回答1024&#xff0c;一个追求数学与计算的边界、时间与空间的平衡&#xff0c;0与1的延伸的后端开发者。 博客特色&#xff1a; 在我的博客中&a…

解决minIO 文件上传回显报 403 问题

一、问题描述&#xff1a; minIO 上传文件回显时 提示 403 Forbidden 二、问题原因&#xff1a; minIO 中文件相对应的 buckets 权限问题造成 三、解决办法&#xff1a; 进入 minIO 控制台&#xff0c;将 buckets 中 access Policy 改为 public

监听器模式(三)

一、介绍 监听器模式是一种软件设计模式&#xff0c;在对象的状态发生改变时&#xff0c;允许依赖它的其他对象获得通知。在Java中&#xff0c;可以使用接口和回调机制来实现监听器模式。 二、代码实例 1、事件Event类 package com.xu.demo.listener;// 事件类 public class…

go设计模式之抽象工厂模式

抽象工厂模式 提供一个创建一系列相关或相互依赖对象的接口&#xff0c;而无需指定它们具体的类。 工厂方法模式通过引入工厂等级结构&#xff0c;解决了简单工厂模式中工厂类职责太重的问题&#xff0c;但由于工厂方法模式中的每个工厂只生产一类产品&#xff0c;可能会导致…

【禅道客户案例】同方智慧能源数智化转型新实践 禅道助力前行

同方智慧能源是同方股份有限公司的骨干企业。依托中核集团、清华大学的科技优势&#xff0c;坚持技术和资源双核驱动&#xff0c;基于30多年行业积淀&#xff0c;面向建筑、交通、工业、北方供热、数据中心等主要用能场景提供设计咨询、产品技术、投资建设、运营服务&#xff0…

每天一题crypto(8)---RSA(相邻素数)

题目&#xff1a; p getPrime(512) q gmpy2.next_prime(p) from Crypto.Util.number import * import gmpy2 flag bNSSCTF{******}p getPrime(512) q gmpy2.next_prime(p) n p*q e 65537 phi (p-1)*(q-1)m bytes_to_long(flag)c pow(m, e, n)print(fn {n}) print(f…

Linux网络编程---多进/线程并发服务器

一、多进程并发服务器 实现一个服务器可以连接多个客户端&#xff0c;每当accept函数等待到客户端进行连接时 就创建一个子进程 思路分析&#xff1a; 核心思路&#xff1a;让accept循环阻塞等待客户端&#xff0c;每当有客户端连接时就fork子进程&#xff0c;让子进程去和客户…

【调研分析】机器视觉及其系统

机器视觉 定义 机器视觉主要利用计算机模拟人的视觉功能&#xff0c;但不仅限于人眼的简单延伸&#xff0c;而是具备人脑的部分功能&#xff0c;即从客观事物的图像中提取信息、进行处理并加以理解&#xff0c;从而应用于实际的检测识别、测量和控制过程。 机器视觉系统组成 …

JavaEE >> Spring Boot(2)

Spring Boot 配置文件 前面的文章已经介绍了 Spring Boot 项目的创建&#xff0c;上文&#xff0c;本文介绍 Spring Boot 的简单进阶使用。 配置文件的作用 项目中的所有重要数据都是在配置文件中配置的&#xff0c;例如&#xff1a; 数据库的连接信息&#xff08;包括数据…

BossCMS RCE(下)

未授权漏洞 在登录后台的时候通过查看添加用户功能&#xff0c;看能不能挖掘sql注入漏洞&#xff0c;结果发现了个大问题&#xff0c;一个比较好玩的权限逻辑问题。这里添加用户的路由 我们跟进到manager.class.php里面的add()方法&#xff0c;这里先into::basc_class(admin)&…

DS进阶:并查集

一、并查集的原理 在一些应用问题中&#xff0c;需要将n个不同的元素划分成一些不相交的集合。开始时&#xff0c;每个元素自成一个单元素集合&#xff0c;然后按一定的规律将归于同一组元素的集合合并。在此过程中要反复用到查询某一个元素归属于那个集合的运算。适合于描述这…

局部多项式近似与 AMPM 算法

kappa3; %已在您的代码中定义% 定义窗口大小 windowSize (2*kappa1);% 初始化梯度估计值 [rows, cols] size(wrappedPhase); phi_y zeros(rows, cols); phi_x zeros(rows, cols);% 遍历每个窗口 for m 1kappa:rows-kappafor n 1kappa:cols-kappa% 提取局部窗口Z_mn wrap…

python 使用flask_httpauth和pyjwt实现登录权限控制

最近需要用到&#xff0c;学习了一下记录 首先安装依赖 pip install Flask-HTTPAuth pyjwt passlib Welcome to Flask-HTTPAuth’s documentation! — Flask-HTTPAuth documentation Welcome to PyJWT — PyJWT 2.8.0 documentation Passlib 1.7.4 documentation — Passl…

【代码随想录刷题记录】LeetCode27移除元素

题目地址 1. 思路 1.1 基本思路及代码的初步实现 基本思路大体上和卡尔老师的想法是一致的&#xff0c;详见代码随想录&#xff1a;数组&#xff1a;移除元素&#xff0c;暴力法大家都能想到&#xff0c;我这里写一下算法时间复杂度为 O ( n ) O(n) O(n)时候的思路&#xff…

短视频矩阵营销系统 poihuoqu 任意文件读取漏洞复现

0x01 产品简介 短视频矩阵营销系统是由北京华益云数据科技有限公司开发的一款产品,这家公司专注于抖音短视频矩阵营销系统的研发,致力于为企业提供全方位的短视频营销解决方案。华益云抖销短视频矩阵系统可以帮助企业快速搭建多个短视频账号,实现内容的批量制作和发布,提高…

ShardingSphere 5.x 系列【25】 数据分片原理之 SQL 解析

有道无术,术尚可求,有术无道,止于术。 本系列Spring Boot 版本 3.1.0 本系列ShardingSphere 版本 5.4.0 源码地址:https://gitee.com/pearl-organization/study-sharding-sphere-demo 文章目录 1. 分片执行流程1.1 Simple Push Down1.2 SQL Federation2. SQL 解析2.1 解析…

SystemUI KeyButtonView setDarkIntensity 解析

继承自 ImageView KeyButtonDrawable intensity为0时按键颜色为白色。 intensity为1时黑色为的调用堆栈&#xff1a; java.lang.NullPointerException: Attempt to invoke virtual method int java.lang.String.length() on a null object referenceat com.android.systemui.…

嵌入式学习Day18

一、输入两个数&#xff0c;实现排序 代码&#xff1a; #!/bin/bashread -p "please enter n m:" n m if [ $n -gt $m ] thentemp$nn$mm$temp fi echo $n $m运行结果 二、输入一个数判断是否水仙花数 代码&#xff1a; echo narcissistic number read -p "p…

店匠科技技术产品闪耀,引领新质生产力发展

在科技飞速发展的今天,新质生产力正成为推动社会进步和经济高质量发展的核心力量。店匠科技,作为一家致力于为全球B2C电商提供产品和技术解决方案的领先企业,其技术产品不仅体现了新质生产力的创新特质,更在推动电商行业转型升级中发挥了重要作用。 新质生产力,以创新为主导,摆…