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

SpringMVC请求处理流程:DispatcherServlet工作原理

在这里插入图片描述

文章目录

    • 引言
    • 一、DispatcherServlet概述
    • 二、DispatcherServlet初始化过程
    • 三、请求接收与处理器匹配
    • 四、请求参数绑定与处理器执行
    • 五、视图解析与渲染
    • 六、异常处理机制
    • 总结

引言

SpringMVC框架是Java Web开发中最流行的MVC框架之一,其核心组件DispatcherServlet作为前端控制器,负责协调整个请求处理流程。理解DispatcherServlet的工作原理对于掌握SpringMVC框架至关重要,不仅有助于开发高质量的Web应用,还能在遇到问题时快速定位和解决。本文将深入剖析SpringMVC的请求处理流程,揭示DispatcherServlet的内部运作机制,通过代码示例展示各个环节的实现细节,帮助开发者全面把握SpringMVC的核心工作流程,从而更加高效地进行Web应用开发。

一、DispatcherServlet概述

DispatcherServlet是SpringMVC框架的核心,它扮演着前端控制器(Front Controller)的角色,是整个请求处理流程的调度中心。作为一个标准的Servlet,DispatcherServlet继承自HttpServlet,遵循Servlet生命周期,在Web容器启动时初始化并加载SpringMVC相关配置。它的主要职责是接收HTTP请求,并根据请求信息将其分发给相应的处理器(Handler),随后协调视图解析器(ViewResolver)渲染结果,最终返回响应给客户端。这种集中式的请求处理机制极大地简化了Web开发的复杂性,实现了松耦合的MVC架构模式。

import org.springframework.web.servlet.DispatcherServlet;
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
import javax.servlet.ServletRegistration;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;/*** 通过编程方式注册DispatcherServlet* 这通常在Servlet 3.0+环境的WebApplicationInitializer实现类中完成*/
public class MyWebAppInitializer implements org.springframework.web.WebApplicationInitializer {@Overridepublic void onStartup(ServletContext servletContext) throws ServletException {// 创建Spring Web应用上下文AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext();// 注册配置类context.register(WebConfig.class);// 创建并注册DispatcherServletDispatcherServlet dispatcherServlet = new DispatcherServlet(context);ServletRegistration.Dynamic registration = servletContext.addServlet("dispatcher", dispatcherServlet);// 配置DispatcherServletregistration.setLoadOnStartup(1); // 设置启动优先级registration.addMapping("/"); // 设置URL映射模式registration.setAsyncSupported(true); // 启用异步支持// 可以添加初始化参数registration.setInitParameter("throwExceptionIfNoHandlerFound", "true");}
}

二、DispatcherServlet初始化过程

DispatcherServlet的初始化是整个SpringMVC框架启动的关键环节。当Web容器启动时,DispatcherServlet会执行初始化流程,创建Spring应用上下文(WebApplicationContext),并加载各种处理请求所需的组件。初始化过程主要分为两个阶段:Servlet标准初始化和SpringMVC特定初始化。在标准初始化阶段,容器调用DispatcherServlet的init()方法;在SpringMVC特定初始化阶段,它会初始化九大组件,包括HandlerMapping、HandlerAdapter、ViewResolver等。这些组件共同构成了SpringMVC的核心处理能力,为后续的请求处理提供必要支持。

import org.springframework.web.servlet.DispatcherServlet;
import org.springframework.web.servlet.HandlerMapping;
import org.springframework.web.servlet.HandlerAdapter;
import org.springframework.web.servlet.ViewResolver;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.springframework.web.servlet.view.InternalResourceViewResolver;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter;/*** SpringMVC配置类,配置DispatcherServlet所需的核心组件*/
@Configuration
@EnableWebMvc
public class WebConfig implements WebMvcConfigurer {/*** 配置HandlerMapping,负责请求与处理器的映射*/@Beanpublic HandlerMapping handlerMapping() {RequestMappingHandlerMapping mapping = new RequestMappingHandlerMapping();// 可以设置相关属性mapping.setOrder(0); // 设置优先级mapping.setUseSuffixPatternMatch(false); // 禁用后缀模式匹配return mapping;}/*** 配置HandlerAdapter,负责执行处理器*/@Beanpublic HandlerAdapter handlerAdapter() {return new RequestMappingHandlerAdapter();}/*** 配置ViewResolver,负责解析视图*/@Beanpublic ViewResolver viewResolver() {InternalResourceViewResolver resolver = new InternalResourceViewResolver();resolver.setPrefix("/WEB-INF/views/");resolver.setSuffix(".jsp");return resolver;}// 可以配置其他组件,如LocaleResolver、ThemeResolver等
}

三、请求接收与处理器匹配

当客户端发送HTTP请求到达Web服务器后,DispatcherServlet首先接收请求并开始处理流程。DispatcherServlet通过调用doService()方法,将请求委托给doDispatch()方法进行具体处理。在这个阶段,DispatcherServlet会遍历所有注册的HandlerMapping实现,查找与当前请求匹配的Handler(处理器)。常用的HandlerMapping包括RequestMappingHandlerMapping(基于注解)和SimpleUrlHandlerMapping(基于URL配置)。一旦找到匹配的Handler,DispatcherServlet还会获取相关的拦截器(Interceptor),组合形成HandlerExecutionChain(处理器执行链),为后续的请求处理做准备。

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.springframework.stereotype.Component;import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;/*** 控制器示例,演示请求映射*/
@RestController
@RequestMapping("/api/users")
public class UserController {@GetMappingpublic String listUsers(@RequestParam(required = false) String filter) {// 处理获取用户列表请求return "User list filtered by: " + (filter != null ? filter : "none");}@GetMapping("/{id}")public String getUserById(@PathVariable Long id) {// 处理获取特定用户请求return "User details for ID: " + id;}
}/*** 自定义拦截器,将被添加到HandlerExecutionChain中*/
@Component
public class LoggingInterceptor implements HandlerInterceptor {@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {System.out.println("LoggingInterceptor.preHandle: " + request.getRequestURI());// 返回true继续处理,返回false中断处理return true;}@Overridepublic void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) {System.out.println("LoggingInterceptor.postHandle: " + request.getRequestURI());}@Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {System.out.println("LoggingInterceptor.afterCompletion: " + request.getRequestURI());if (ex != null) {System.out.println("Exception occurred: " + ex.getMessage());}}
}/*** 配置拦截器,将其注册到SpringMVC框架*/
@Configuration
public class InterceptorConfig implements WebMvcConfigurer {@Overridepublic void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(new LoggingInterceptor()).addPathPatterns("/api/**") // 指定拦截路径.excludePathPatterns("/api/public/**"); // 指定排除路径}
}

四、请求参数绑定与处理器执行

找到匹配的Handler后,DispatcherServlet需要调用合适的HandlerAdapter来执行处理器。在SpringMVC中,最常用的是RequestMappingHandlerAdapter,它负责执行基于@RequestMapping注解的控制器方法。在执行前,HandlerAdapter会进行请求参数的解析与绑定,将HTTP请求中的参数转换为控制器方法所需的参数。这个过程涉及多种类型转换器和参数解析器,如RequestParamMethodArgumentResolver、PathVariableMethodArgumentResolver等。参数绑定完成后,HandlerAdapter调用控制器方法,执行业务逻辑,并获取处理结果(ModelAndView或返回值)。这一阶段是整个请求处理的核心环节。

import org.springframework.web.bind.annotation.*;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.beans.propertyeditors.CustomDateEditor;import javax.validation.Valid;
import java.text.SimpleDateFormat;
import java.util.Date;/*** 演示参数绑定的控制器*/
@Controller
@RequestMapping("/products")
public class ProductController {/*** 初始化WebDataBinder,用于自定义参数绑定规则*/@InitBinderpublic void initBinder(WebDataBinder binder) {// 注册自定义日期编辑器SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");dateFormat.setLenient(false);binder.registerCustomEditor(Date.class, new CustomDateEditor(dateFormat, true));}/*** 展示创建产品表单*/@GetMapping("/new")public String showCreateForm(Model model) {model.addAttribute("product", new Product());return "product/create";}/*** 处理产品创建请求* 演示多种参数绑定方式*/@PostMappingpublic String createProduct(@Valid @ModelAttribute("product") Product product, // 表单对象绑定和验证BindingResult bindingResult, // 验证结果@RequestParam(required = false) String category, // 请求参数@CookieValue(value = "sessionId", required = false) String sessionId, // Cookie值@RequestHeader("User-Agent") String userAgent, // 请求头Model model // 模型) {// 检查验证结果if (bindingResult.hasErrors()) {return "product/create";}// 执行业务逻辑System.out.println("Creating product: " + product.getName());System.out.println("Category: " + category);System.out.println("Session ID: " + sessionId);System.out.println("User Agent: " + userAgent);// 添加成功消息到模型model.addAttribute("message", "Product created successfully!");return "redirect:/products";}
}/*** 产品实体类*/
public class Product {private Long id;private String name;private Double price;private Date releaseDate;// Getters and Setterspublic Long getId() { return id; }public void setId(Long id) { this.id = id; }public String getName() { return name; }public void setName(String name) { this.name = name; }public Double getPrice() { return price; }public void setPrice(Double price) { this.price = price; }public Date getReleaseDate() { return releaseDate; }public void setReleaseDate(Date releaseDate) { this.releaseDate = releaseDate; }
}

五、视图解析与渲染

当控制器方法执行完毕后,它通常会返回一个逻辑视图名或直接返回数据。对于返回逻辑视图名的情况,DispatcherServlet需要将其解析为具体的视图对象。视图解析过程由ViewResolver接口的实现类负责,如InternalResourceViewResolver(用于JSP)、ThymeleafViewResolver(用于Thymeleaf模板)等。DispatcherServlet会遍历已注册的ViewResolver,查找能够解析当前逻辑视图名的解析器。一旦找到合适的视图对象,就会调用其render()方法,将模型数据(Model)渲染到视图中,生成响应内容。对于REST风格的接口,返回值可能被直接转换为JSON/XML,这种情况下不需要视图解析步骤。

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.ViewResolver;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.ViewResolverRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.springframework.web.servlet.view.InternalResourceViewResolver;
import org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer;
import org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver;
import org.springframework.web.servlet.view.json.MappingJackson2JsonView;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.ResponseBody;/*** 视图解析器配置类*/
@Configuration
@EnableWebMvc
public class ViewResolverConfig implements WebMvcConfigurer {/*** 配置JSP视图解析器*/@Beanpublic ViewResolver jspViewResolver() {InternalResourceViewResolver resolver = new InternalResourceViewResolver();resolver.setPrefix("/WEB-INF/views/");resolver.setSuffix(".jsp");resolver.setViewClass(org.springframework.web.servlet.view.JstlView.class);resolver.setOrder(2); // 设置优先级return resolver;}/*** 配置FreeMarker视图解析器*/@Beanpublic ViewResolver freeMarkerViewResolver() {FreeMarkerViewResolver resolver = new FreeMarkerViewResolver();resolver.setCache(true);resolver.setPrefix("");resolver.setSuffix(".ftl");resolver.setContentType("text/html; charset=UTF-8");resolver.setOrder(1); // 优先级高于JSP解析器return resolver;}/*** 配置FreeMarker引擎*/@Beanpublic FreeMarkerConfigurer freeMarkerConfigurer() {FreeMarkerConfigurer configurer = new FreeMarkerConfigurer();configurer.setTemplateLoaderPath("/WEB-INF/templates/");configurer.setDefaultEncoding("UTF-8");return configurer;}/*** 内容协商视图解析器配置*/@Overridepublic void configureViewResolvers(ViewResolverRegistry registry) {registry.enableContentNegotiation(new MappingJackson2JsonView());}
}/*** 演示不同视图解析方式的控制器*/
@Controller
public class ViewController {/*** 返回JSP视图*/@GetMapping("/page/jsp")public String jspView(Model model) {model.addAttribute("message", "Hello from JSP!");return "hello"; // 解析为/WEB-INF/views/hello.jsp}/*** 返回FreeMarker视图*/@GetMapping("/page/freemarker")public String freemarkerView(Model model) {model.addAttribute("message", "Hello from FreeMarker!");return "hello"; // 解析为/WEB-INF/templates/hello.ftl}/*** 直接返回ModelAndView*/@GetMapping("/page/manual")public ModelAndView manualView() {ModelAndView mav = new ModelAndView("custom");mav.addObject("message", "Hello from custom view!");return mav;}/*** 返回JSON数据(不使用视图解析)*/@GetMapping("/api/data/{id}")@ResponseBodypublic Product jsonData(@PathVariable Long id) {Product product = new Product();product.setId(id);product.setName("Sample Product");product.setPrice(99.99);return product; // 直接转换为JSON返回}
}

六、异常处理机制

在请求处理过程中,可能会发生各种异常,如业务逻辑异常、参数验证异常等。SpringMVC提供了完善的异常处理机制,由DispatcherServlet协调,确保异常被正确处理并返回适当的响应。核心组件是HandlerExceptionResolver接口的实现类,包括DefaultHandlerExceptionResolver(处理标准Spring异常)、ExceptionHandlerExceptionResolver(处理@ExceptionHandler注解)等。当异常发生时,DispatcherServlet会遍历已注册的异常解析器,查找能够处理当前异常的解析器。异常处理可以通过@ExceptionHandler注解、@ControllerAdvice全局异常处理类或实现HandlerExceptionResolver接口来自定义。良好的异常处理设计能够提高系统的健壮性和用户体验。

import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.NoHandlerFoundException;
import org.springframework.http.HttpStatus;
import org.springframework.web.context.request.WebRequest;
import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler;
import org.springframework.http.ResponseEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.validation.BindException;import javax.validation.ConstraintViolationException;
import java.util.HashMap;
import java.util.Map;
import java.util.Date;/*** 全局异常处理器*/
@ControllerAdvice
public class GlobalExceptionHandler extends ResponseEntityExceptionHandler {/*** 处理业务逻辑异常*/@ExceptionHandler(BusinessException.class)@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)@ResponseBodypublic ErrorResponse handleBusinessException(BusinessException ex) {return new ErrorResponse(HttpStatus.INTERNAL_SERVER_ERROR.value(),ex.getMessage(),new Date());}/*** 处理资源未找到异常*/@ExceptionHandler(ResourceNotFoundException.class)@ResponseStatus(HttpStatus.NOT_FOUND)@ResponseBodypublic ErrorResponse handleResourceNotFoundException(ResourceNotFoundException ex) {return new ErrorResponse(HttpStatus.NOT_FOUND.value(),ex.getMessage(),new Date());}/*** 处理参数验证异常*/@ExceptionHandler(ConstraintViolationException.class)@ResponseStatus(HttpStatus.BAD_REQUEST)@ResponseBodypublic Map<String, Object> handleValidationExceptions(ConstraintViolationException ex) {Map<String, Object> errors = new HashMap<>();ex.getConstraintViolations().forEach(violation -> {String fieldName = violation.getPropertyPath().toString();String errorMessage = violation.getMessage();errors.put(fieldName, errorMessage);});return errors;}/*** 处理404错误(需配置throwExceptionIfNoHandlerFound=true)*/@Overrideprotected ResponseEntity<Object> handleNoHandlerFoundException(NoHandlerFoundException ex, HttpHeaders headers, HttpStatus status, WebRequest request) {ErrorResponse error = new ErrorResponse(HttpStatus.NOT_FOUND.value(),"Resource not found: " + ex.getRequestURL(),new Date());return new ResponseEntity<>(error, HttpStatus.NOT_FOUND);}/*** 处理表单绑定异常*/@Overrideprotected ResponseEntity<Object> handleBindException(BindException ex, HttpHeaders headers, HttpStatus status, WebRequest request) {Map<String, String> errors = new HashMap<>();ex.getBindingResult().getFieldErrors().forEach(error -> errors.put(error.getField(), error.getDefaultMessage()));return new ResponseEntity<>(errors, HttpStatus.BAD_REQUEST);}/*** 处理所有其他未捕获的异常*/@ExceptionHandler(Exception.class)public ModelAndView handleGenericException(Exception ex) {ModelAndView modelAndView = new ModelAndView("error/generic");modelAndView.addObject("errorMessage", ex.getMessage());modelAndView.addObject("timestamp", new Date());return modelAndView;}
}/*** 自定义业务异常*/
public class BusinessException extends RuntimeException {public BusinessException(String message) {super(message);}
}/*** 自定义资源未找到异常*/
public class ResourceNotFoundException extends RuntimeException {public ResourceNotFoundException(String message) {super(message);}
}/*** 错误响应DTO*/
public class ErrorResponse {private int status;private String message;private Date timestamp;public ErrorResponse(int status, String message, Date timestamp) {this.status = status;this.message = message;this.timestamp = timestamp;}// Getters and Setterspublic int getStatus() { return status; }public void setStatus(int status) { this.status = status; }public String getMessage() { return message; }public void setMessage(String message) { this.message = message; }public Date getTimestamp() { return timestamp; }public void setTimestamp(Date timestamp) { this.timestamp = timestamp; }
}

总结

SpringMVC的请求处理流程是一个精心设计的管道,由DispatcherServlet作为中央调度器协调各个组件的工作。这一流程始于DispatcherServlet接收HTTP请求,随后通过HandlerMapping查找匹配的Handler,利用HandlerAdapter执行处理器逻辑,最后通过ViewResolver解析视图并渲染响应结果。整个过程高度模块化,各组件职责明确,通过策略模式和组合模式实现了高度的可扩展性和灵活性。了解这一流程不仅有助于开发者编写高质量的代码,还能在遇到问题时快速定位根源。在实际应用中,可以通过自定义HandlerMapping、HandlerAdapter、ViewResolver等组件来扩展框架能力,满足特定业务需求。此外,合理配置拦截器和异常处理器,能够提升应用的安全性和用户体验。掌握SpringMVC的请求处理流程对于Java Web开发者而言是至关重要的基础知识,是构建高性能、可维护Web应用的关键。

相关文章:

SpringMVC请求处理流程:DispatcherServlet工作原理

文章目录 引言一、DispatcherServlet概述二、DispatcherServlet初始化过程三、请求接收与处理器匹配四、请求参数绑定与处理器执行五、视图解析与渲染六、异常处理机制总结 引言 SpringMVC框架是Java Web开发中最流行的MVC框架之一&#xff0c;其核心组件DispatcherServlet作为…...

YOLOv8目标检测推理流程及C++代码

这部分主要是使用c++对Onnx模型进行推理,边先贴代码,过段时间再详细补充下代码说明。 代码主要分成三部分,1.main_det.cpp推理函数主入口;2.inference_det.h 头文件及inference_det.cpp具体函数实现;3.CMakeList.txt. 1.main_det 推理配置信息全部写在config.txt中,执行…...

解锁数据潜能,永洪科技以数据之力简化中粮可口可乐决策之路

企业数字化转型是指企业利用数字技术和信息通信技术来改变自身的商业模式、流程和增值服务&#xff0c;以提高企业的竞争力和创新能力。数字化转型已经成为企业发展的重要战略&#xff0c;尤其在当前信息技术高速发展的时代。数字化转型还涉及到企业与消费者之间的互动和沟通。…...

Redis3 Hash 类型命令详解

1. 什么是 Redis Hash&#xff1f; Redis Hash 是一种 键值对集合&#xff0c;类似于 Java 里的 HashMap&#xff0c;可以用来存储对象的数据。例如&#xff0c;你可以将用户信息存储在 Redis 的 Hash 结构中&#xff0c;每个字段代表用户的一个属性。 示例&#xff1a; HSE…...

双链路提升网络传输的可靠性扩展可用带宽

为了提升网络传输的可靠性或增加网络可用带宽&#xff0c; 通常使用双链路冗余备份或者双链路聚合的方式。 本文介绍几种双链路网络通信的案例。 5GWiFi冗余传输 双Socket绑定不同网络接口&#xff1a;通过Android的ConnectivityManager绑定5G蜂窝网络和WiFi的Socket连接&…...

深入浅出:UniApp 从入门到精通全指南

https://juejin.cn/post/7440119937644101684 uni-app官网 uniapp安卓离线打包流程_uniapp离线打包-CSDN博客 本文是关于 UniApp 从入门到精通的全指南&#xff0c;涵盖基础入门&#xff08;环境搭建、创建项目、项目结构、编写运行&#xff09;、核心概念与进阶知识&#x…...

MDM 如何彻底改变医疗设备的远程管理

在现代医疗行业迅速发展的格局中&#xff0c;医院和诊所越来越依赖诸如医疗平板和移动工作站等移动设备。这些设备在提高工作效率和提供卓越的患者护理方面发挥着关键作用。然而&#xff0c;随着它们的广泛使用&#xff0c;也带来了一系列挑战&#xff0c;例如在不同地点确保数…...

前端性能优化之同时插入100000个元素页面不卡顿

面试官&#xff1a;同时插入100000个元素怎么让页面不卡顿 优化前写法 首先我们来看下面的一段&#xff0c;点击按钮后&#xff0c;循环100000次&#xff0c;每次都插入一个元素&#xff0c;并且插入区域上方还有一个小球在滚动&#xff0c;在插入的过程中我们可以观察小球的…...

PHP之Cookie和Session

在你有别的编程语言的基础下&#xff0c;你想学习PHP&#xff0c;可能要了解的一些关于cookie和session的信息。 Cookie 参数信息 setcookie(name,value,expire, path, domain); name : Cookie的名称。 value : Cookie的值。 expire : Cookie的过期时间&#xff0c;可以是一…...

vscode 配置debug的环境

vscode配置debug的环境 配置好python解释器&#xff0c; ctrl shift P 就可以指定python了。 当前环境下建立 .vscode 文件夹新建 .vscode/launch.json 文件文件的配置如下 {"version": "0.2.0","configurations": [{"name": &qu…...

socket基础学习以及java搭建

在 Java 中&#xff0c;Socket 编程用于实现网络通信。Java 提供了丰富的网络 API&#xff0c;使得通过 Socket 进行通信变得简单和高效。Java 的 Socket 编程常见于客户端-服务器应用中&#xff0c;比如聊天程序、文件传输工具等。 1. Socket 基本概念 Socket 编程的基本概念…...

Exoplayer2源码编译FFmpeg拓展模块实现音频软解码

在前面文章最新版本Exoplayer扩展FFmpeg音频软解码保姆级教程中介绍了最新版本的Exoplayer(androidx.Media3)编译FFmpeg模块的流程&#xff0c;有就是media3版本的explayer最低支持的sdk版本是21也就是Android5.x,但是市面上还是有很多IOT设备是很老的android4.4(sdk19)的&…...

Docker安装嵌入框架Text Embeddings Inference (TEI)

Docker安装Text Embeddings Inference (TEI) 1 简单介绍 文本嵌入推理&#xff08;TEI&#xff0c;Text Embeddings Inference &#xff09;是HuggingFace研发的一个用于部署和服务开源文本嵌入和序列分类模型的工具包。TEI兼容OpenAI的嵌入模型的规范。 # 官网地址 https:/…...

使用easyocr、PyPDF2对图像及PDF文档进行识别

一、概述 本 Python 脚本的主要功能是对当前目录及其子目录下的图片和 PDF 文件进行光学字符识别&#xff08;OCR&#xff09;处理。它使用 easyocr 库处理图片中的文字&#xff0c;使用 PyPDF2 库提取 PDF 文件中的文本&#xff0c;并将处理结果保存为文本文件。同时&#xff…...

MAUI(C#)安卓开发起步

初级代码游戏的专栏介绍与文章目录-CSDN博客 我的github&#xff1a;codetoys&#xff0c;所有代码都将会位于ctfc库中。已经放入库中我会指出在库中的位置。 这些代码大部分以Linux为目标但部分代码是纯C的&#xff0c;可以在任何平台上使用。 源码指引&#xff1a;github源…...

oracle decode

1. 基本语法 DECODE(expression, search1, result1, search2, result2, ..., default_result) expression &#xff1a;需要比较的表达式或列。search1, search2, ... &#xff1a;要匹配的值。result1, result2, ... &#xff1a;当 expression 等于 search 时返回的结果。def…...

826考研

初试总分第一的hh佬小红书&#xff1a;https://www.xiaohongshu.com/user/profile/64e106aa000000000100fe33 深研院巨佬经验贴&#xff1a;https://zhuanlan.zhihu.com/p/690464528 本部羊神经验贴&#xff1a;https://zhuanlan.zhihu.com/p/689494655 本部学硕佬经验贴&#…...

PPT小黑第26套

对应大猫28 层次级别是错的&#xff0c;看着是十页&#xff0c;导入ppt之后四十多页 选中所有 红色蓝色黑色 文本选择标题&#xff1a;选择 -格式相似文本&#xff08;检查有没有漏选 漏选的话 按住ctrl 点下一个&#xff09; 要求新建幻灯片中不包含原素材中的任何格式&…...

【Linux-网络】HTTP的清风与HTTPS的密语

&#x1f3ac; 个人主页&#xff1a;谁在夜里看海. &#x1f4d6; 个人专栏&#xff1a;《C系列》《Linux系列》《算法系列》 ⛰️ 道阻且长&#xff0c;行则将至 目录 &#x1f4da; 引言 &#x1f4da; 一、HTTP &#x1f4d6; 1.概述 &#x1f4d6; 2.URL &#x1f5…...

Vue 与 Nuxt 的区别

Nuxt 实现服务端渲染SSR Nuxt.js 是基于 Vue.js 的一个框架&#xff0c;它为构建 Vue.js 应用提供了更高级的功能和更便捷的开发体验。 一、定位与功能 Vue.js 是一个前端 JavaScript 框架&#xff0c;专注于构建用户界面和单页应用&#xff08;SPA&#xff09;。 核心功能…...

华为OD机试-最长的密码(Java 2024 E卷 100分)

题目描述 小王正在进行游戏大闯关,有一个关卡需要输入一个密码才能通过。密码获得的条件如下: 在一个密码本中,每一页都有一个由26个小写字母组成的密码,每一页的密码不同。需要从这个密码本中寻找这样一个最长的密码,从它的末尾开始依次去掉一位得到的新密码也在密码本…...

利用golang embed特性嵌入前端资源问题解决

embed嵌入前端资源&#xff0c;配置前端路由的代码如下 func StartHttpService(port string, assetsFs embed.FS) error {//r : gin.Default()gin.SetMode(gin.ReleaseMode)r : gin.New()r.Use(CORSMiddleware())// 静态文件服务dist, err : fs.Sub(assetsFs, "assets/di…...

解决docker认证问题 failed to authorize: failed to fetch oauth token

报错信息[bash1]解决方案 全局代理打开“buildkit”: false &#xff0c;见[图1] [bash1] >docker build -t ffpg . [] Building 71.8s (3/3) FINISHED docker:desktop-linux> [internal] load bui…...

【Flink银行反欺诈系统设计方案】3.欺诈的7种场景和架构方案、核心表设计

【Flink银行反欺诈系统设计方案】3.欺诈的7种场景和架构方案、核心表设计 1. **欺诈场景分类与案例说明**1.1 **大额交易欺诈**1.2 **异地交易欺诈**1.3 **高频交易欺诈**1.4 **异常时间交易欺诈**1.5 **账户行为异常**1.6 **设备指纹异常**1.7 **交易金额突变** 2. **普适性软…...

docker拉取失败

备份原始配置文件 sudo cp /etc/docker/daemon.json /etc/docker/daemon.json.bak 清理或修复 daemon.json 文件 sudo nano /etc/docker/daemon.json 删除 文件中的所有内容&#xff0c;确保文件为空。 cv下面这个文件内容 { "registry-mirrors": [ &…...

无人机应用探索:玻纤增强复合材料的疲劳性能研究

随着无人机技术的快速发展&#xff0c;轻量化已成为其结构设计的核心需求。玻纤增强复合材料凭借高强度、低密度和优异的耐环境性能&#xff0c;成为无人机机身、旋翼支架等关键部件的理想选择。然而&#xff0c;无人机在服役过程中需应对复杂多变的环境&#xff1a;高空飞行时…...

Visual Studio工具

高亮显示匹配的标签&#xff08;小括号&#xff0c;中括号&#xff0c;大括号&#xff09;...

STM32Cubemx配置E22-xxxT22D lora模块实现定点传输

文章目录 一、STM32Cubemx配置二、定点传输**什么是定点传输&#xff1f;****定点传输的特点****定点传输的工作方式****E22 模块定点传输配置****如何启用定点传输&#xff1f;****示例** **应用场景****总结** **配置 1&#xff1a;C0 00 07 00 02 04 62 00 17 40****解析** …...

iterm2更新后主题报错

报错 .oh-my-zsh/themes/agnoster.zsh-theme:307: parse error near <<<。方法1&#xff1a;更新Oh My Zsh主题&#xff08;以agnoster为例&#xff09; 适用场景&#xff1a;使用Oh My Zsh自带主题&#xff08;如agnoster&#xff09;时出现语法错误。 备份当前主题…...

WPF+WebView 基础

1、基于.NET8&#xff0c;通过NuGet添加Microsoft.Web.WebView2。 2、MainWindow.xaml代码如下。 <Window x:Class"Demo.MainWindow"xmlns"http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x"http://schemas.microsoft.com/win…...