当前位置: 首页 > article >正文

SpringBoot 第二课(Ⅰ) 整合springmvc(详解)

目录

一、SpringBoot对静态资源的映射规则

1. WebJars 资源访问

2. 静态资源访问

3. 欢迎页配置

二、SpringBoot整合springmvc

概述

Spring MVC组件的自动配置

中央转发器(DispatcherServlet)

控制器(Controller)

视图解析器

实现springmvc的文件上传

upload.html

FileUploadController.java(/upload)

消息转换和格式化

1.消息转换器

概念

2.格式化

①实现WebMvcConfigurer接口

②配置文件编写

 三、Springboot扩展springmvc

1.在容器中注册视图控制器(请求转发)

2.拦截器设置

补充(配置类的加载顺序)


经过前面对SpringBoot第一课的学习,大致也总结出对springboot的使用流程:

①创建 Spring Boot 应用并选择模块(参见下面博客):SpringBoot(一)--搭建架构5种方法_springboot框架搭建-CSDN博客文章浏览阅读2.2k次,点赞19次,收藏39次。Spring Boot 是基于 Spring 框架,以约定优于配置、自动配置为核心,可快速构建独立运行的应用,为微服务等开发提供便利的开发框架。前面已经对SSM(Spring,SpringMVC,MyBatis)每个框架做了讲解,SpringBoot就是基于这个框架一个更简单、更有利于开发。_springboot框架搭建 https://blog.csdn.net/m0_74977981/article/details/146139845?spm=1001.2014.3001.5501

②少量配置即可运行:Spring Boot 具有自动配置的特性,默认将很多常见的开发场景(如 Web 开发的服务器配置、数据库连接的基础配置等)都配置好了。开发者不需要进行大量复杂的配置工作,只需要在配置文件(如 application.properties 或 application.yml)中指定少量必要的配置信息,就能够让应用程序运行起来。

③编写业务代码:当 Spring Boot 应用创建好并且基本配置完成后,开发者就可以专注于编写具体的业务逻辑代码了。例如,实现用户登录、数据处理、业务规则判断等功能,来满足实际项目的需求。

本文章就解读“少量配置”“编写业务代码”两方面进行讲解。

在开始讲解之前,先来说一说Spring Boot 框架中的两个核心概念:自动配置(AutoConfiguration)和属性配置(Properties)

  1. xxxxAutoConfiguration(给容器中自动配置组件):指的是自动配置类,这些类帮助我们在 Spring Boot 应用中自动配置各种组件。Spring Boot 通过这些自动配置类,根据类路径中的 jar 包依赖和配置文件中的设置,自动配置应用的各个部分,从而简化了配置过程。

  2. xxxxProperties(配置类来封装配置文件中的内容):指的是配置属性类,这些类用于封装外部配置文件(如 application.propertiesapplication.yml)中的内容。通过将配置文件中的属性映射到这些类中的字段,Spring Boot 能够将配置值注入到应用的各个组件中,实现配置的集中管理和使用。

所以向查看这两个方面的源码,可以参见类名带这两个后缀的类。

一、SpringBoot对静态资源的映射规则

在 Spring Boot 2.4 之前,静态资源的配置属性主要由 ResourceProperties 类来管理,它位于 org.springframework.boot.autoconfigure.web 包下,相关配置项以 spring.resources 作为前缀;

但是在从 Spring Boot 2.4 开始,静态资源的配置属性被整合到了 WebProperties 类中,该类位于 org.springframework.boot.autoconfigure.web 包下。其中,静态资源相关的配置被封装在 WebProperties.Resources 这个内部类里(WebProperties的前缀是spring.web,而ResourceProperties 作为内部封装类,它的前缀依旧是 spring.resources ,所以2.4后想在配置文件更改它的信息前缀就变成了spring.web.resources)。

可以在External Libraries里查看(由于我用的是2.7.0版本,所以在这里我就展示WebProperties类,代码功能都是一样的):

External Libraries目录下

就在这个包里面,顺着org.springframework.boot.autoconfigure.web查看: 

顺着路径向下找

可以点开查看这个封装类的源码: 

就是这一个(2.4后封装位置)

可以看见内部:

WebProperties源码

1. WebJars 资源访问

WebJars 是一种将前端库(如 jQuery、Bootstrap 等)打包成 Java 可识别的 JAR 文件的方式。这样做的好处是可以利用 Maven 或 Gradle 等构建工具来管理这些库的依赖,同时保持项目的依赖关系清晰。

在 Spring Boot 项目中,所有以 /webjars/** 开头的请求都会被映射到 classpath:/META-INF/resources/webjars/ 目录下寻找资源。这意味着,如果在项目中引入了 WebJars 资源,你可以通过 /webjars/ 路径前缀来访问这些资源。

【注:所有以 /webjars/** 开头的请求通常是指那些通过 <groupId>org.webjars</groupId> 引入的依赖】

例如,如果在 pom.xml 文件中添加了以下依赖:

<dependency><groupId>org.webjars</groupId><artifactId>jquery</artifactId><version>3.3.1</version>
</dependency>

那么就可以通过访问 http://localhost:8080/webjars/jquery/3.3.1/jquery.js 来获取 jQuery 库的 JavaScript 文件。

也可以在External Libraries这里查看:

查看External Libraries里的jQuery

2. 静态资源访问

在 Spring Boot 项目中,可以通过多种路径前缀来访问静态资源。这些路径前缀包括(优先级也是下面这个顺序从高到低):

  1. classpath:/META-INF/resources/

  2. classpath:/resources/

  3. classpath:/static/

  4. classpath:/public/

在 Maven 项目中,这些目录可能位于:

  • src/main/resources/META-INF/resources/

  • src/main/resources/resources/

  • src/main/resources/static/

  • src/main/resources/public/

这些路径通常对应于项目中的目录结构,例如 Maven 项目中的 src/main/resources 目录。通过这些路径,可以访问存放在这些目录下的静态资源,如 HTML、CSS、JavaScript 文件等。

例如,如果在 src/main/resources/static 目录下有一个名为 abc 的文件,可以通过访问 http://localhost:8080/abc 来获取这个文件。

3. 欢迎页配置

在 Spring Boot 项目中,可以通过配置来设置欢迎页。当用户访问应用的根路径(如 http://localhost:8080/)时,Spring Boot 会尝试在静态资源文件夹下查找 index.html 文件作为欢迎页。

如果在静态资源文件夹下存在多个 index.html 文件,Spring Boot 会按照一定的规则选择一个作为欢迎页。通常,它会查找第一个找到的 index.html 文件。

这种方式使得配置欢迎页变得非常简单,只需要在静态资源文件夹下放置一个 index.html 文件即可。

Springboot自动指定resources下的index.html

二、SpringBoot整合springmvc

springboot整合mvc本质来说就是对它的组件实现了自动装配:

中央转发器(DispatcherServlet

控制器

视图解析器

静态资源访问

消息转换器

格式化

静态资源管理

这些组件在springmvc中的运作流程和功能详见下面这篇博客:

SpringMVC(二)原理_springmvc和maven-CSDN博客文章浏览阅读1.2k次,点赞27次,收藏13次。1. 当启动Tomcat服务器的时候,因为配置了load-on-startup标签,所以会创建DispatcherServlet对象,就会加载springmvc.xml配置文件。前缀是/html/,后缀是.html,所以return时,返回的其实是,/html/suc.html,即一个前端界面。7.点击重写,选择D:盘apache-maven下conf下的logging下的setting.xml,点击确定。4. 根据执行方法的返回值,再根据配置的视图解析器,去指定的目录下查找指定名称的JSP文件。_springmvc和maven https://blog.csdn.net/m0_74977981/article/details/144885878?spm=1001.2014.3001.5501(内置有图解)

概述

Spring Boot对Spring MVC进行了自动配置,简化了Spring MVC的使用。它通过自动配置类(如WebMvcAutoConfiguration)和注解扫描,使得开发者无需手动配置大量的Spring MVC相关组件,如DispatcherServlet、视图解析器、消息转换器等。同时,Spring Boot还提供了扩展机制,允许开发者根据业务需求进行自定义配置。

Spring MVC组件的自动配置

中央转发器(DispatcherServlet)

  • 自动配置:Spring Boot自动接管了DispatcherServlet的配置,无需在web.xml中手动配置。DispatcherServlet的配置由DispatcherServletAutoConfiguration类完成。

  • 默认配置:默认情况下,DispatcherServlet拦截/路径下的所有请求(包括静态资源,但不包括JSP请求)。可以通过server.servletPath属性修改其拦截路径。

控制器(Controller)

  • 自动管理:在Spring Boot的注解扫描范围内,使用@Controller@RestController注解的类会被自动识别并管理为Spring MVC的控制器。

  • 注解扫描:Spring Boot默认会扫描与主应用类同级或子级的包中的注解类。如果需要扫描其他包,可以通过@ComponentScan注解指定。

视图解析器

  • 自动配置:Spring Boot自动配置了视图解析器,包括InternalResourceViewResolverContentNegotiatingViewResolver等。

  • 默认配置:默认的视图解析器前缀为classpath:/templates/,后缀为.html(如果使用Thymeleaf模板引擎的话-引入了Thymeleaf的依赖)。可以通过application.properties文件中的spring.mvc.view.prefixspring.mvc.view.suffix属性进行自定义(这个出自于WebMvcProperties封装类)。

实现springmvc的文件上传

当我们做文件上传的时候我们也会发现multipartResolver是自动被配置好的,它被封装在MultipartAutoConfiguration类中,处 org.springframework.boot.autoconfigure.web.servlet 包下。

注意看这个类的前缀

可以通过配置文件配置如下属性:

# 是否启用文件上传支持,默认为 true
spring.servlet.multipart.enabled=true# 上传文件的临时存储目录
spring.servlet.multipart.location=# 单个文件的最大大小,默认为 1MB
spring.servlet.multipart.max-file-size=1MB# 整个请求的最大大小,默认为 10MB
spring.servlet.multipart.max-request-size=10MB# 文件写入磁盘的阈值,默认值为 0
spring.servlet.multipart.file-size-threshold=0# 是否延迟解析多部分请求,默认为 false
spring.servlet.multipart.resolve-lazily=false

在讲解示例之前,照例展示我用的pom.xml文件: 

<?xml version="1.0" encoding="UTF-8"?>
<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 https://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.7.0</version><relativePath/> <!-- lookup parent from repository --></parent><groupId>com.qcby</groupId><artifactId>springboot2</artifactId><version>0.0.1-SNAPSHOT</version><name>springboot2</name><description>springboot2</description><properties><java.version>8</java.version></properties><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.webjars</groupId><artifactId>jquery</artifactId><version>3.3.1</version></dependency><!--热部署--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-devtools</artifactId><optional>true</optional></dependency><!--thymeleaf模块支撑--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-thymeleaf</artifactId></dependency><!--消息转换扩展--><dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><version>1.2.47</version></dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build>
</project>
顺带附赠演示项目的目录结构

upload.html

<!DOCTYPE html>
<html lang="en">
<head><title>File Upload</title>
</head>
<body>
<form action="/upload" method="post" enctype="multipart/form-data"><input name="pic" type="file"><input type="submit">
</form>
</body>
</html><!-- 
action 属性:指定表单数据提交的目标 URL。在这段代码中,action="/upload" 表示表单数据将被发送到服务器的 /upload 路径进行处理。
method 属性:规定表单数据的提交方式,常见的有 GET 和 POST。这里使用 method="post",意味着表单数据会以 HTTP POST 请求的方式发送到服务器,适合用于提交包含敏感信息或大量数据的表单,如文件上传。
enctype 属性:指定表单数据在发送到服务器之前的编码方式。对于文件上传,必须使用 enctype="multipart/form-data",这种编码方式允许表单数据以多部分的形式进行传输,能够处理二进制文件数据。
-->

FileUploadController.java(/upload)

package com.qcby.springboot2;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;import javax.servlet.http.HttpServletRequest;
import java.io.*;@Controller //标记为一个控制器类
public class FileUploadController {@ResponseBody@RequestMapping(value = "/upload", method = RequestMethod.POST)public String upload(@RequestParam("pic") MultipartFile file, HttpServletRequest request) {//@RequestParam("pic") MultipartFile file:从请求中获取名为 pic 的文件参数(在html表单中设置了),MultipartFile 是 Spring 框架提供的用于处理文件上传的接口。String contentType = file.getContentType();String fileName = file.getOriginalFilename();String filePath = "D:\\001_Myclass001\\javava\\TestAll"; // 修改路径try {this.uploadFile(file.getBytes(), filePath, fileName);} catch (Exception e) {// TODO: handle exceptionreturn "upload error";}return "upload";  //上传成功后在前端返回字符串}public static void uploadFile(byte[] file, String filePath, String fileName) throws Exception {File targetFile = new File(filePath);if (!targetFile.exists()) {targetFile.mkdirs();}FileOutputStream out = new FileOutputStream(filePath + File.separator + fileName); // 使用 File.separatorout.write(file);out.flush();out.close();}
}

启动项目框架,输入“http://localhost:8080/upload”(因为我没有在配置文件中更改路径或端口号):

得到:

访问后得到

选择文件并提交后就可以得到:

提交成功后得到

消息转换和格式化

1.消息转换器

概念

消息转换器(Message Converters)是 Spring MVC 中的一个核心组件,用于在 HTTP 请求和响应中进行数据的序列化和反序列化,这是前后端交互(交互产生的信息都是消息)过程中不可或缺的一部分。当客户端发送请求时,消息转换器会将请求体中的数据转换为 Java 对象;当服务器返回响应时,消息转换器会将 Java 对象转换为合适的响应体格式(如 JSON、XML 等)。

Springboot自动配置了消息转换器(HttpMessageConvertersAutoConfiguration类中)

2.格式化

格式化通常指的是将数据转换成特定格式的过程,以便它可以用于显示、存储或传输(封装在)。

实现格式化功能可以通过实现WebMvcConfigurer接口和在配置文件中编写配置这两种方式来实现。

以时间格式化为例:

①实现WebMvcConfigurer接口

②配置文件编写

实现WebMvcConfigurer接口和在配置文件中编写配置这两种有什么区别呢?

最大的区别就是通过实现接口的方式配置功能更加自由。

如下是配置文件的几种选项

但是通过实现接口的方式进行配置可以有更多选择。

 三、Springboot扩展springmvc

在实际开发中springboot并非完全自动化,很多跟业务相关我们需要自己扩展,springboot给我提供了接口,我们可以来通过实现WebMvcConfigurer接口来扩展。

瞅一眼项目封装的WebMvcConfigurer接口

我为这个源码加上了注释,标明每个方法是可以拓展什么:

package org.springframework.web.servlet.config.annotation;import java.util.List;
import org.springframework.format.FormatterRegistry;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.lang.Nullable;
import org.springframework.validation.MessageCodesResolver;
import org.springframework.validation.Validator;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.method.support.HandlerMethodReturnValueHandler;
import org.springframework.web.servlet.HandlerExceptionResolver;public interface WebMvcConfigurer {// 配置路径匹配的选项default void configurePathMatch(PathMatchConfigurer configurer) {}// 配置内容协商选项(例如,基于请求头的内容类型和接受类型来选择响应的媒体类型)default void configureContentNegotiation(ContentNegotiationConfigurer configurer) {}// 配置异步请求处理(例如,使用DeferredResult或Callable来处理长时间运行的任务)default void configureAsyncSupport(AsyncSupportConfigurer configurer) {}// 配置默认的Servlet处理(例如,映射到dispatcherServlet的URL路径)default void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {}// 添加自定义格式化器到FormatterRegistry,用于数据绑定时的格式化和解析default void addFormatters(FormatterRegistry registry) {}// 添加拦截器到拦截器注册表,用于拦截和处理请求default void addInterceptors(InterceptorRegistry registry) {}// 添加资源处理器到资源处理器注册表,用于处理静态资源请求default void addResourceHandlers(ResourceHandlerRegistry registry) {}// 添加跨域资源共享(CORS)映射到CORS注册表default void addCorsMappings(CorsRegistry registry) {}// 添加视图控制器到视图控制器注册表,用于处理特定的URL路径default void addViewControllers(ViewControllerRegistry registry) {}// 配置视图解析器选项default void configureViewResolvers(ViewResolverRegistry registry) {}// 添加自定义参数解析器到参数解析器列表,用于解析控制器方法的参数default void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers) {}// 添加自定义返回值处理器到返回值处理器列表,用于处理控制器方法的返回值default void addReturnValueHandlers(List<HandlerMethodReturnValueHandler> handlers) {}// 配置消息转换器列表,用于处理HTTP请求和响应的序列化和反序列化default void configureMessageConverters(List<HttpMessageConverter<?>> converters) {}// 扩展消息转换器列表,可以添加或修改现有的消息转换器default void extendMessageConverters(List<HttpMessageConverter<?>> converters) {}// 配置异常解析器列表,用于解析和处理异常default void configureHandlerExceptionResolvers(List<HandlerExceptionResolver> resolvers) {}// 扩展异常解析器列表,可以添加或修改现有的异常解析器default void extendHandlerExceptionResolvers(List<HandlerExceptionResolver> resolvers) {}// 提供一个自定义的验证器(Validator)实例,用于数据验证@Nullabledefault Validator getValidator() {return null;}// 提供一个自定义的消息代码解析器(MessageCodesResolver)实例,用于解析验证错误消息的代码@Nullabledefault MessageCodesResolver getMessageCodesResolver() {return null;}
}

    下面就来简单用一下实现接口配置来实现业务:

    1.在容器中注册视图控制器(请求转发)

    @Controller
    public class MyMVCCofnig implements WebMvcConfigurer {@Overridepublic void addViewControllers(ViewControllerRegistry registry) {registry.addViewController("/tx").setViewName("success");//将 /tx 路径映射到 success 视图下(前端页面)}

    2.拦截器设置

    拦截类:

    package com.qcby.springboot2;import org.springframework.stereotype.Component;
    import org.springframework.web.servlet.HandlerInterceptor;
    import org.springframework.web.servlet.ModelAndView;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;/*** 拦截器*/
    @Component
    public class MyInterceptor implements HandlerInterceptor {@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {System.out.println("前置拦截");return true;}@Overridepublic void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {System.out.println("后置拦截");}@Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {System.out.println("最终拦截");}
    }
    

    实现WebMvcConfigurer类的Java:

    package com.qcby.springboot2;import com.alibaba.fastjson.serializer.SerializerFeature;
    import com.alibaba.fastjson.support.config.FastJsonConfig;
    import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.http.converter.HttpMessageConverter;
    import org.springframework.stereotype.Controller;
    import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
    import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
    import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;import java.util.List;@Controller
    public class MyMVCCofnig implements WebMvcConfigurer {/*** 重写拦截器** 配置一个名为MyInterceptor的拦截器,使其应用于所有请求路径,除了/hello2(拦截所有请求,除了hello2)*可以得到结果,在访问hello2时,并不会在控制台打印拦截,但是当访问hello1时(对比),就会打印三条拦截消息* */@Autowiredprivate MyInterceptor myInterceptor;@Overridepublic void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(myInterceptor).addPathPatterns("/**").excludePathPatterns("/hello2");}
    }
    

    再来一个controller类:

    package com.qcby.springboot2;import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.RestController;@RestController
    public class HelloController1 {@GetMapping("/hello1")public String hello() {return "Hello, World 1!";}@GetMapping("/hello2")public String hello2() {return "Hello, World 2!";}
    }

    可以得到:

    访问hello1

    由于除了hello2请求,其他的都会受到拦截,所以这里的hello1请求就会收到后台的拦截类提醒(准确来说访问除hello2外的所有请求都会收到拦截通知):


     现在清空后台再来访问一下hello2试验一下:

    访问hello2
    后台空空

    补充(配置类的加载顺序)

    可以注意到在上面展示的那些源码中,经常会有@AutoConfigureOrder@Order这两个注解:

    首先@AutoConfigureOrder@Order 注解是用于控制Spring Boot配置类的加载顺序的。

    • @Order 是通用的,适用于所有Spring管理的Bean,控制加载或执行顺序。

    • @AutoConfigureOrder 是专门用于Spring Boot自动配置类的,确保自动配置类的加载顺序。

    • 序列规则:两者都遵循“值越小,优先级越高”的规则,但默认值不同(@Order 默认为 Integer.MAX_VALUE@AutoConfigureOrder 默认为 0)。

    相关文章:

    SpringBoot 第二课(Ⅰ) 整合springmvc(详解)

    目录 一、SpringBoot对静态资源的映射规则 1. WebJars 资源访问 2. 静态资源访问 3. 欢迎页配置 二、SpringBoot整合springmvc 概述 Spring MVC组件的自动配置 中央转发器&#xff08;DispatcherServlet&#xff09; 控制器&#xff08;Controller&#xff09; 视图解…...

    Kafka 八股文

    一、基础概念 1. Kafka 是什么&#xff1f;它的核心组件有哪些&#xff1f; Kafka 的定义 Kafka 是一个 分布式流处理平台&#xff0c;最初由 LinkedIn 开发&#xff0c;后成为 Apache 顶级项目。它主要用于 高吞吐量的实时数据流处理&#xff0c;支持发布-订阅模式的消息传递…...

    OpenHarmony 开源鸿蒙北向开发——3.配置SDK

    安装、配置完成之后我们就要配置SDK。 我们创建工程后&#xff0c;点击右上角设置 进入设置 进入OpenHarmony SDK&#xff0c;选择编辑 这里配置一下SDK安装位置 点击完成 这里我们API版本勾选第一个即可 确认安装 勾选接受 这里要等一会 安装完成后&#xff0c;点击完成...

    电子工程师转战汽车OEM主机厂之路

    文章目录 1 电子工程师2 汽车系统工程师 第一篇分享一个笔者2018年的一个心得文章&#xff0c;回头想想从事汽车行业也小8年了&#xff0c;从懵懂稚嫩到所谓的老油条&#xff0c;也是难忘的经历&#xff0c;希望我的经历对从事电子行业和汽车行业的小伙伴有所帮助。 1 电子工程…...

    vulhub Matrix-Breakout

    1.下载靶机&#xff0c;打开靶机和kali虚拟机 2.查询kali和靶机ip 3.浏览器访问 访问81端口有登陆界面 4.扫描敏感目录 kali dirb 扫描 一一访问 robot.txt提示我们继续找找&#xff0c;可能是因为我们的字典太小了&#xff0c;我们换个扫描器换个字典试下,利用kali自带的最大…...

    Unity3D开发AI桌面精灵/宠物系列 【二】 语音唤醒 ivw 的两种方式-Windows本地或第三方讯飞等

    Unity3D 交互式AI桌面宠物开发系列【二】ivw 语音唤醒 该系列主要介绍怎么制作AI桌面宠物的流程&#xff0c;我会从项目开始创建初期到最终可以和AI宠物进行交互为止&#xff0c;项目已经开发完成&#xff0c;我会仔细梳理一下流程&#xff0c;分步讲解。 这篇文章主要讲有关于…...

    三月九次前端面试复盘:当场景题成为通关密钥

    三月初集中面了包括字节、美团、滴滴在内的9家公司&#xff0c;经历7场技术面2场Leader面后&#xff0c;发现如今的面试逻辑已发生根本转变。这里分享真实经历与题目&#xff0c;供近期求职者参考。 一、面试形态变化&#xff1a;从理论背诵到实战推演 1. 八股文边缘化&#…...

    STM32 —— 嵌入式系统、通用计算机系统、物联网三层架构

    目录 一、嵌入式系统的概念 二、通用计算机系统与嵌入式系统的比较 用途 硬件 软件 性能与功耗 开发与维护 三、嵌入式系统与物联网的关系 四、物联网的三层架构 1. 感知层&#xff08;Perception Layer&#xff09; 2. 网络层&#xff08;Network Layer&#xff09; …...

    如何选择合适的 AI 模型?(开源 vs 商业 API,应用场景分析)

    1. 引言 在 AI 迅猛发展的今天&#xff0c;各类 AI 模型层出不穷&#xff0c;从开源模型&#xff08;如 DeepSeek、Llama、Qwen&#xff09;到商业 API&#xff08;如 OpenAI 的 ChatGPT、Anthropic 的 Claude、Google Gemini&#xff09;&#xff0c;每种方案都有其优势与适用…...

    视频对讲系统中,强插和强拆;视频分发功能

    强插和强拆 在视频对讲系统中&#xff0c;强插和强拆是两个具有特定功能的操作&#xff0c;具体含义如下&#xff1a; 强插功能&#xff1a;指在视频对讲过程中&#xff0c;具有更高权限的用户或管理员可以强行插入正在进行的通话或视频连接。例如&#xff0c;当小区保安室监控…...

    C++输入输出流第一弹:标准输入输出流 详解(带测试代码)

    目录 C输入输出流 流的四种状态&#xff08;重点&#xff09; 标准输入输出流 标准输入流 逗号表达式 1. 逗号表达式的基本规则 示例 2. 图片中的代码分析 关键点解析 3. 常见误区 误区 1&#xff1a;逗号表达式等同于逻辑与 && 误区 2&#xff1a;忽略输入…...

    {瞎掰} 手机安装app问题:app签名,手机 or OS官方商店 其他非官方app源,安全防护 突破限制

    以下&#xff0c;在华为安卓系统手机中&#xff0c;在安装app过程中得到的一些可能是错误的经验。 商品化 app 的收钱方式&#xff1a;通过商店来收钱&#xff0c;通过 app 本身提供的注册码功能来收钱&#xff0c;或是其他的收钱方式。 手机安装 app的特点 从官方商店里安装…...

    鸿蒙NEXT项目实战-百得知识库05

    代码仓地址&#xff0c;大家记得点个star IbestKnowTeach: 百得知识库基于鸿蒙NEXT稳定版实现的一款企业级开发项目案例。 本案例涉及到多个鸿蒙相关技术知识点&#xff1a; 1、布局 2、配置文件 3、组件的封装和使用 4、路由的使用 5、请求响应拦截器的封装 6、位置服务 7、三…...

    记录一次,rabbitmq开启stomp插件之后,还是连不上15674端口的问题

    原因是装在docker 里面的rabbitmq 没有映射15674端口&#xff0c;需重新删除容器之后重新运行 docker run -d --name rabbitmq -p 5672:5672 -p 15672:15672 -p 15674:15674 -p 1883:1883 -p 15675:15675 rabbitmq:版本号 进入docker容器开启插件 docker exec -it rabbitm…...

    黑马node.js教程(nodejs教程)——AJAX-Day01-04.案例_地区查询——查询某个省某个城市所有地区(代码示例)

    文章目录 代码示例效果 代码示例 axiosTest.html <!DOCTYPE html> <!-- 文档类型声明&#xff0c;告诉浏览器这是一个HTML5文档 --> <html lang"en"> <!-- HTML根元素&#xff0c;设置文档语言为英语 --><head> <!-- 头部区域&am…...

    vue 自制列表,循环滚动

    需求人员表示&#xff0c;超过高度的表格内容需要滚动展示&#xff0c;所以效果图如下&#xff1a; 自定义列表样式&#xff0c;主要是通过flex布局&#xff0c;控制 类th 与 类td 的宽度保持一致&#xff0c;标签结构还是参考了table的结构&#xff0c;由thead与tbody包裹tr再…...

    【QA】模板方法模式在Qt中有哪些应用?

    在 Qt 框架中&#xff0c;模板方法模式&#xff08;Template Method Pattern&#xff09;被广泛应用于框架的设计中&#xff0c;通过定义算法骨架并允许子类在不改变结构的情况下重写部分步骤。以下是 Qt 中典型的应用场景及示例&#xff1a; 1. 事件处理&#xff08;Event Ha…...

    图论——kruskal算法

    53. 寻宝(第七期模拟笔试) 题目描述 在世界的某个区域,有一些分散的神秘岛屿,每个岛屿上都有一种珍稀的资源或者宝藏。国王打算在这些岛屿上建公路,方便运输。 不同岛屿之间,路途距离不同,国王希望你可以规划建公路的方案,如何可以以最短的总公路距离将 所有岛屿联通…...

    Windows主机、虚拟机Ubuntu、开发板,三者之间文件互传

    以下内容源于日常学习的整理&#xff0c;欢迎交流。 下图是Windows主机、虚拟机Ubuntu、开发者三者之间文件互传的方式示意图&#xff1a; 注意&#xff0c;下面谈及的所有方式&#xff0c;都要求两者的IP地址处于同一网段&#xff0c;涉及到的软件资源见felm。 一、Windows主…...

    Flutter Dart 泛型详解

    引言 在 Flutter 开发中&#xff0c;Dart 语言的泛型是一项强大且实用的特性。泛型允许我们在定义类、方法或接口时使用类型参数&#xff0c;这样可以编写更加灵活、可复用且类型安全的代码。下面将详细介绍 Dart 泛型的各个方面&#xff0c;并结合代码示例进行说明。 1. 泛型…...

    Windows Docker 报错: has no HTTPS proxy,换源

    pull python 3.7报错&#xff1a; 尝试拉取Docker 测试库hello world也失败 尝试使用临时镜像源&#xff0c;可以成功拉取&#xff1a; sudo docker pull docker.m.daocloud.io/hello-world说明确实是网络问题&#xff0c;需要配置镜像源&#xff0c;为了方便&#xff0c;在d…...

    Java:Arrays类:操作数组的工具类

    文章目录 Arrays类常见方法SetAll(); 代码排序如果数组中存储的是自定义对象 Arrays类 常见方法 SetAll(); 注意&#xff1a; 不能用新的数组接是因为修改的是原数组&#xff0c;所以完了要输出原数组发现会产生变化参数是数组下标变成灰色是因为还能简化&#xff08;Lambda…...

    【面试场景题-Redis中String类型和map类型的区别】

    今天在面试中碰到一个场景题&#xff1a;在 Redis 中存储 100 万用户数据时&#xff0c;使用 String 类型和 Hash&#xff08;Map&#xff09;类型的主要区别是什么&#xff1f;体现在以下几个方面&#xff1a; 1. 存储结构与内存占用 String 类型 存储方式&#xff1a;每个用…...

    List附加对象

    List里面的某个对象需要修改&#xff0c;赋值 可以使用ALL或者ForEach&#xff0c;All的话&#xff0c;不能直接使用赋值对象只能赋值对象的某个字段 static void Main(string[] args){List<UserData> UserDatas new List<UserData>{new UserData { Id 1, Name …...

    VLLM专题(三十六)—自动前缀缓存

    PagedAttention 的核心思想是将每个请求的 KV 缓存划分为 KV 块。每个块包含固定数量的标记(tokens)对应的注意力键(keys)和值(values)。PagedAttention 算法允许将这些块存储在非连续的物理内存中,从而通过按需分配内存来消除内存碎片。 为了自动缓存 KV 缓存,我们利…...

    相机光学(四十七)——相纸材质

    1. 光面相纸 光面相纸表面光滑&#xff0c;亮度高&#xff0c;反光性好&#xff0c;能够呈现出清晰、鲜艳的图像效果&#xff0c;适合用于表现色彩艳丽、反差要求较高的题材&#xff0c;如产品照、艺术照和风景照。然而&#xff0c;这种相纸容易沾上指纹和灰尘。 2. 绒面相纸…...

    数据表100多字段如何写mapper文件的xml

    编写一个包含100多个字段的插入语句通常涉及到使用<mapper>标签来定义映射规则&#xff0c;特别是在使用MyBatis这样的持久层框架时。 1. 定义<mapper>命名空间 order表 <mapper namespace"com.example.mapper.orderMapper"><!-- 插入语句 --…...

    只是“更轻更薄”?不!遨游三防平板还选择“更强更韧”

    当消费电子领域普遍追求“更轻更薄”的设计美学时&#xff0c;遨游三防平板不止于此&#xff0c;还选择了另一条道路——“更强更韧”。在智能制造的复杂场景中&#xff0c;三防平板需直面高温、油污、撞击与极端气候的考验。普通消费级平板因防护性能不足&#xff0c;常因环境…...

    拉取镜像太慢?一文解决!

    # 拉取 Docker 镜像太慢&#xff1f;一文解决&#xff01;&#x1f680;在国内使用 Docker 拉取镜像时&#xff0c;可能会遇到速度慢甚至失败的情况。别担心&#xff01;本文带你快速优化 Docker 拉取方法&#xff01;&#x1f525;01 | 确保 Docker Hub 登录认证 &#x1f510…...

    基于RAGFlow本地部署DeepSeek-R1大模型与知识库:从配置到应用的全流程解析

    作者&#xff1a;后端小肥肠 &#x1f34a; 有疑问可私信或评论区联系我。 &#x1f951; 创作不易未经允许严禁转载。 姊妹篇&#xff1a; DeepSpeek服务器繁忙&#xff1f;这几种替代方案帮你流畅使用&#xff01;&#xff08;附本地部署教程&#xff09;-CSDN博客 10分钟上手…...