52、基于函数式方式开发 Spring WebFlux 应用

news2025/1/2 0:09:44

★ Spring WebFlux的两种开发方式

1. 采用类似于Spring MVC的注解的方式来开发。
   此时开发时感觉Spring MVC差异不大,但底层依然是反应式API。

2. 使用函数式编程来开发

★ 使用函数式方式开发Web Flux

使用函数式开发WebFlux时需要开发两个组件:

▲ Handler:作用:该处理器组件相当于控制器,它负责处理客户端的请求、并对客户端生成响应。

       该Handler组件的每个方法都只带一个ServerRequest参数(不是Servlet API)——代表客户端请求对象,

       且每个方法的返回值类型都是Mono<ServerResponse>,代表作为服务器响应的消息发布者。
       
       mono 代表一个消息发布者

▲ Router:作用:该组件通过函数式的编程方式来定义URL与Handler处理方法之间的映射关系。

★ WebFlux通过ServerRequest获取请求数据的两种方式:

这两种方式并不是可以自由选择的,而是根据数据的来源不同,需要采用对应的获取策略。

 - 对于以请求体提交的数据,通常会通过formData()(表单数据)或bodyToFlux()或bodyToMono()(RESTful)方法来获取,

   由于这种方式都需要通过网络IO读取数据,可能会造成阻塞,

   因此它们都采用了订阅-发布的异步方式,这三个方法的返回值都是Mono或Flux(消息发布者)。

 - 对于URL中的数据(包括传统请求参数和路径参数),由于它们只要直接解析URL字符串即可读取数据,

   不会造成阻塞,因此没有采用订阅-发布的异步方式。直接用pathVariable()或queryParam()方法即可读取数据。

★ Handler方法的返回值

Handler作用: 该处理器组件相当于控制器,它负责处理客户端的请求、并对客户端生成响应。

Handler处理方法的返回值类型是Mono<ServerResponse>,
调用ServerResponse的ok()(相当于将响应状态码设为200)、
contentType()方法返回ServerResponse.BodyBuilder对象。
有了ServerResponse.BodyBuilder对象之后,根据响应类型不同,
可调用如下两个方法来生成Mono<ServerResponse>作为返回值:

▲ render(String name, Map<String,?> model):使用模板引擎来生成响应,

   其中第一个参数代表逻辑视图名,第二个参数代表传给模板的model数据。render()方法还有其他重载形式,功能类似。

▲ body(P publisher, Class<T> elementClass):直接设置响应体类生成响应,同样用于生成RESTful响应。

   body()方法还有其他重载形式,功能类似。

★ 使用Router定义URL与Handler方法的对应关系

Router作用: 该组件通过函数式的编程方式来定义URL与Handler处理方法之间的映射关系。

 ▲ Router就是容器中RouterFunctions类型的Bean。
    ——通常来说,就是使用@Configuration修饰的配置类来配置该Bean即可。

 return RouterFunctions
   // 定义映射地址和处理器方法之间的对应关系
   .route(RequestPredicates.POST("/login")
      .and(RequestPredicates.accept(MediaType.TEXT_HTML)), handler::login)
   .andRoute(RequestPredicates.GET("/viewBook/{id}")
      .and(RequestPredicates.accept(MediaType.TEXT_HTML)), handler::viewBook);

代码演示:

同个请求,演示跟 spring mvc 不同的实现方法。

请求的数据是简单的url数据,就是前端传来的数据(id)是写在url 的。

总结:通过添加 Handler 类,相当于之前的controller ,然后创建一个 Router 配置类,通过在配置类 配置 Router Bean 这个bean,来实现对客户端请求来的URL 与 Handler处理方法之间的映射关系。最终响应回json格式的数据或者 html 页面。

Handler:该处理器组件相当于控制器,它负责处理客户端的请求、并对客户端生成响应,这个类就是handler组件

现在弄一个 Handler 类,用来处理客户端的请求,是一个处理数据的类,相当于controller

这个方法是生成 RESTful 响应的,就是 Json 响应
在这里插入图片描述
这个方法是生成 HTML 响应的
在这里插入图片描述

Router:作用:该组件通过函数式的编程方式来定义URL与Handler处理方法之间的映射关系。

配置 Router Bean ,负责完成请求 URL 和 Handler 处理方法之间的映射。

设置方法的请求路径是 “/viewBookabc/{id}” ,走这个路径就会访问这个 handler::viewBook 方法。
而 handler::viewBooks 是 lambda 中的方法引用 ,会找到 BookHandler 类中的 viewBook 方法

bean 方法里面的参数是 BookHandler,所以可以用 lambda 的方法引用功能 来引用该类的viewBook方法。

负责完成 【请求URL】 和 【Handler处理方法】 之间的映射。

Handler处理方法:就是 BookHandler 的 viewBook 方法。
在这里插入图片描述

返回响应给html的页面
在这里插入图片描述

这个bean在项目启动的时候就会被加载。
在这里插入图片描述

调用方法看看流程:
访问方法,就会走 BookHandler 的 这个方法。
在这里插入图片描述

测试结果:

在这里插入图片描述

完整代码:

BookHandler

// Handler:该处理器组件相当于控制器,它负责处理客户端的请求、并对客户端生成响应,这个类就是handler组件
@Component
public class BookHandler
{
    private BookService bookService;

    //有参构造器完成依赖注入
    public BookHandler(BookService bookService)
    {
        this.bookService = bookService;
    }


    // Handler:该处理器组件相当于控制器,它负责处理客户端的请求、并对客户端生成响应,这个类就是handler组件

    //这个方法是生成 RESTful 响应的
    public Mono<ServerResponse> viewBook(ServerRequest request)
    {
        //如果请求参数是通过 URL 字符串即可解析,可用 pathVariable()或queryParam()方法获取参数
        Integer id = Integer.parseInt(request.pathVariable("id"));
        Book book = bookService.getBook(id);
        //ok()  表示服务器响应正常
        Mono<ServerResponse> body = ServerResponse.ok()
                //选择生成 JSON 响应类型
                .contentType(MediaType.APPLICATION_JSON)
                //如果要生成 JSON 响应,直接用 body 方法
                //参数1:代表数据发布者(Publisher),参数2:指定 Mono 中每个数据项的类型
                //Mono 的 justOrEmpty 将单个及可能为null的数据包装成 Mono
                //如果是设计良好的应用(就是底层数据库的访问也是用 reactor api ,
                // 这样此处从数据库返回的数据就是 Mono 或者 Flux,根本不需要包装)
                .body(Mono.justOrEmpty(book), Book.class);
        return body;
    }

    //这个方法是生成 HTML 响应的
    public Mono<ServerResponse> viewBookHtml(ServerRequest request)
    {
        //如果请求参数是通过 URL 字符串即可解析,可用 pathVariable()或queryParam()方法获取参数
        Integer id = Integer.parseInt(request.pathVariable("id"));
        Book book = bookService.getBook(id);
        //ok()  表示服务器响应正常
        Mono<ServerResponse> render = ServerResponse.ok()
                //选择生成 HTML 响应类型
                .contentType(MediaType.TEXT_HTML)
                //参数1:逻辑视图名   参数2:相当于 spring mvc 的 model,用于向视图页面传输数据
                .render("viewBook", Map.of("book", book));
        return render;
    }
}

RouterConfig

package cn.ljh.FunctionalFlux.router;

import cn.ljh.FunctionalFlux.handler.BookHandler;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.MediaType;
import org.springframework.web.reactive.function.server.RequestPredicates;
import org.springframework.web.reactive.function.server.RouterFunction;
import org.springframework.web.reactive.function.server.RouterFunctions;
import org.springframework.web.reactive.function.server.ServerResponse;

@Configuration //配置类
public class RouterConfig
{
    //配置 Router Bean ,负责完成请求 URL 和 Handler 处理方法之间的映射。

    @Bean
    public RouterFunction<ServerResponse> routerFunctions(BookHandler handler)
    {
        //MediaType.APPLICATION_JSON 设置响应类型 ,  handler::viewBooks  是 lambda 中的方法引用
        RouterFunction<ServerResponse> route =
                RouterFunctions
                        //这里就映射到 BookHandler 类里面的 viewBook 方法,/viewBookabc/{id}这个是我们这边给的访问路径
                        .route(RequestPredicates.GET("/viewBookabc/{id}")
                                .and(RequestPredicates.accept(MediaType.APPLICATION_JSON)), handler::viewBook)

                        //这里就映射到 BookHandler 类里面的 viewBookHtml 方法,/viewBookHtml/{id}这个是我们这边给的访问路径
                        .andRoute(RequestPredicates.GET("/viewBookHtml/{id}")
                                .and(RequestPredicates.accept(MediaType.TEXT_HTML)), handler::viewBookHtml);
        return route;
    }
}

上面的代码演示,请求的数据是简单的url数据,就是前端传来的数据(id)是写在url 的。

这次演示的是前端以 表单 的方式 或 restful 方式提交数据。

演示:以 RESTful 方式提交的数据的处理

这边接收前端传来的数据并进行处理,相当于controller
在这里插入图片描述

这里的bean就是处理 请求url 和 handler处理方法 之间的映射关系
在这里插入图片描述

测试结果:
成功处理添加书本的方法,添加的书本的数据在postman中实现。
在这里插入图片描述

演示:通过表单页面提交请求

写一个简单的表单页面
在这里插入图片描述

前端通过表单页面提交请求
在这里插入图片描述

添加 请求 URL 和 Handler 处理方法之间的映射
在这里插入图片描述

测试结果:

注意:发现因为 handler处理方法那里,因为使用了map ,把源 Mono 转成新的 Mono,当时转换的结果没去用它,所以出现添加不成功的问题。

如图:
如果不需要使用 Mono 转换之后的结果,此时就不需要使用 map() 方法
map() 方法就是负责将 源Mono 转换成新的 Mono
如果只是希望用到 Mono 中的数据,此时成为消费数据,
就是把这条消息消费掉就行,因为不需要把 Mono 的结果返回到视图页面,所以不需要用map方法进行转换。
在这里插入图片描述

测试成功:
成功通过表单页面提交请求
在这里插入图片描述

前端注意小知识:

在 templates 路径下的静态页面是不能直接访问的,得通过控制器的处理方法进行转发才能访问到。
或者直接把页面放在静态资源目录(static、public),才能直接访问。
注意:页面得是静态页面,不能有动态内容,不能是动态页面。

在这里插入图片描述

完整代码:

domain
在这里插入图片描述

处理类:BookHandler,类似于controller

package cn.ljh.FunctionalFlux.handler;


import cn.ljh.FunctionalFlux.domain.Book;
import cn.ljh.FunctionalFlux.service.BookService;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Component;
import org.springframework.util.MultiValueMap;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.reactive.function.server.ServerRequest;
import org.springframework.web.reactive.function.server.ServerResponse;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

import java.time.Duration;
import java.util.Collection;
import java.util.Map;


// Handler:该处理器组件相当于控制器,它负责处理客户端的请求、并对客户端生成响应,这个类就是handler组件
@Component
public class BookHandler
{
    private BookService bookService;

    //有参构造器完成依赖注入
    public BookHandler(BookService bookService)
    {
        this.bookService = bookService;
    }


    // Handler:该处理器组件相当于控制器,它负责处理客户端的请求、并对客户端生成响应,这个类就是handler组件

    //这个方法是生成 RESTful 响应的 ,就是 Json 响应
    public Mono<ServerResponse> viewBook(ServerRequest request)
    {
        //如果请求参数是通过 URL 字符串即可解析,可用 pathVariable()或queryParam()方法获取参数
        Integer id = Integer.parseInt(request.pathVariable("id"));
        Book book = bookService.getBook(id);
        //ok()  表示服务器响应正常
        Mono<ServerResponse> body = ServerResponse.ok()
                //选择生成 JSON 响应类型
                .contentType(MediaType.APPLICATION_JSON)
                //如果要生成 JSON 响应,直接用 body 方法
                //参数1:代表数据发布者(Publisher),参数2:指定 Mono 中每个数据项的类型
                //Mono 的 justOrEmpty 将单个及可能为null的数据包装成 Mono
                //如果是设计良好的应用(就是底层数据库的访问也是用 reactor api ,
                // 这样此处从数据库返回的数据就是 Mono 或者 Flux,根本不需要包装)
                .body(Mono.justOrEmpty(book), Book.class);
        return body;
    }

    //这个方法是生成 HTML 响应的
    public Mono<ServerResponse> viewBookHtml(ServerRequest request)
    {
        //如果请求参数是通过 URL 字符串即可解析,可用 pathVariable()或queryParam()方法获取参数
        Integer id = Integer.parseInt(request.pathVariable("id"));
        Book book = bookService.getBook(id);
        //ok()  表示服务器响应正常
        Mono<ServerResponse> render = ServerResponse.ok()
                //选择生成 HTML 响应类型
                .contentType(MediaType.TEXT_HTML)
                //参数1:逻辑视图名   参数2:相当于 spring mvc 的 model,用于向视图页面传输数据
                .render("viewBook", Map.of("book", book));
        return render;
    }


    //以 RESTful 方式提交的数据的处理
    public Mono<ServerResponse> addBook(ServerRequest request)
    {
        //假设数据来自 RESTful 的 POST 请求,此时用 bodyToMono() 或 bodyToFlux() 来获取数据
        //bodyToFlux():如果请求的数据中包含多个数据,就用这个。
        //bodyToMono():如果请求的数据只有一个数据,那就用这个
        //这两个方法参数指定了 Mono 或 Flux 中数据的类型

        // 添加一本图书,只是一个对象,所以用.bodyToMono() ,
        // 如果是一个集合,就应该使用 .bodyToFlux()

        Mono<Book> bookMono = request.bodyToMono(Book.class);
        //map() 负责将 Mono 或者 Flux 中的元素,转换成新的 Mono 或 Flux 中的元素
        Mono<Book> resultMono = bookMono.map(book ->
        {
            //添加 Book 对象
            bookService.addBook(book);
            return book;
        });
        Mono<ServerResponse> body = ServerResponse.ok()
                //选择生成 JSON 响应类型
                .contentType(MediaType.APPLICATION_JSON)
                //如果要生成 JSON 响应,直接用 body 方法
                //参数1:代表数据发布者(Publisher),参数2:指定 Mono 中每个数据项的类型
                //Mono 的 justOrEmpty 将单个及可能为null的数据包装成 Mono
                //如果是设计良好的应用(就是底层数据库的访问也是用 reactor api ,
                // 这样此处从数据库返回的数据就是 Mono 或者 Flux,根本不需要包装)
                .body(resultMono, Book.class);
        return body;
    }


    //通过表单页面提交请求
    public Mono<ServerResponse> addBookHtml(ServerRequest request)
    {
        //假设数据来自 表单页面 的 POST 请求,通过 formData() 获取表单的数据
        Mono<MultiValueMap<String, String>> formData = request.formData();

        /*
         * 如果不需要使用 Mono 转换之后的结果,此时就不需要使用 map() 方法
         * map() 方法就是负责将 源Mono 转换成新的 Mono
         * 如果只是希望用到 Mono 中的数据,此时成为消费数据
         */
        formData.subscribe(map ->
        {
            String name = map.get("name").get(0);
            String price = map.get("price").get(0);
            String author = map.get("author").get(0);
            Book book = new Book(null, name, Double.parseDouble(price), author);
            bookService.addBook(book);
        });
        Mono<ServerResponse> render = ServerResponse.ok()
                //选择生成 JSON 响应类型
                .contentType(MediaType.TEXT_HTML)
                .render("addBookResult", Map.of("tip", "添加书籍成功"));
        return render;
    }


}

配置类:RouterConfig,添加个bean处理url和handler类中的方法的映射关系

package cn.ljh.FunctionalFlux.router;

import cn.ljh.FunctionalFlux.handler.BookHandler;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.MediaType;
import org.springframework.web.reactive.function.server.RequestPredicates;
import org.springframework.web.reactive.function.server.RouterFunction;
import org.springframework.web.reactive.function.server.RouterFunctions;
import org.springframework.web.reactive.function.server.ServerResponse;

@Configuration //配置类
public class RouterConfig
{
    //配置 Router Bean ,负责完成请求 URL 和 Handler 处理方法之间的映射。
    @Bean
    public RouterFunction<ServerResponse> routerFunctions(BookHandler handler)
    {
        //MediaType.APPLICATION_JSON 设置响应类型 ,  handler::viewBooks  是 lambda 中的方法引用
        RouterFunction<ServerResponse> route =
                RouterFunctions
                        //这里就映射到 BookHandler 类里面的 viewBook 方法,/viewBookabc/{id}这个是我们这边给的访问路径
                        .route(RequestPredicates.GET("/viewBookabc/{id}")
                                .and(RequestPredicates.accept(MediaType.APPLICATION_JSON)), handler::viewBook)

                        //这里就映射到 BookHandler 类里面的 viewBookHtml 方法,/viewBookHtml/{id}这个是我们这边给的访问路径
                        .andRoute(RequestPredicates.GET("/viewBookHtml/{id}")
                                .and(RequestPredicates.accept(MediaType.TEXT_HTML)), handler::viewBookHtml)

                        //这里就映射到 BookHandler 类里面的 addBook 方法,/addBook 这个是我们这边给的访问路径
                        .andRoute(RequestPredicates.POST("/addBook")
                                .and(RequestPredicates.accept(MediaType.APPLICATION_JSON)), handler::addBook)

                        //这里就映射到 BookHandler 类里面的 addBookHtml 方法,/addBookHtml/{id}这个是我们这边给的访问路径
                        .andRoute(RequestPredicates.POST("/addBookHtml")
                                .and(RequestPredicates.accept(MediaType.TEXT_HTML)), handler::addBookHtml);
        return route;
    }
}

BookService

package cn.ljh.FunctionalFlux.service;


import cn.ljh.FunctionalFlux.domain.Book;
import java.util.Collection;

public interface BookService
{
    Book getBook(Integer id);

    Integer addBook(Book book);

    Collection<Book> getAllBooks();
}

BookServiceImpl

package cn.ljh.FunctionalFlux.service.impl;


import cn.ljh.FunctionalFlux.domain.Book;
import cn.ljh.FunctionalFlux.service.BookService;
import org.springframework.stereotype.Service;

import java.util.*;

//添加这个@Service注解,springboot就可以自动扫描这个Service组件的实现类,然后把这个类部署成容器中的bean。
@Service
public class BookServiceImpl implements BookService
{
    //添加一个 Map 集合,假设为数据库
    public static final Map<Integer, Book> bookDB = new LinkedHashMap<>();

    //创建一个自增id
    static int nextId = 4;

    //初始化这个数据库
    static
    {
        bookDB.put(1, new Book(1, "火影忍者", 100.0, "岸本"));
        bookDB.put(2, new Book(2, "家庭教师", 110.0, "天野明"));
        bookDB.put(3, new Book(3, "七龙珠Z", 120.0, "鸟山明"));
    }


    //查看图书
    @Override
    public Book getBook(Integer id)
    {
        Book book = bookDB.get(id);
        if (book == null){
            throw new RuntimeException("没有此图书信息!");
        }
        return book;
    }

    //添加图书
    @Override
    public Integer addBook(Book book)
    {
        book.setId(nextId);
        bookDB.put(nextId,book);
        //返回id,先返回在自增。
        return nextId++;
    }

    //查看所有的图书
    @Override
    public Collection<Book> getAllBooks()
    {
        //获取集合中的所有元素
        Collection<Book> values = bookDB.values();
        return values;
    }
}

添加图书页面:addBook.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>添加图书页面</title>
</head>
<body>
<h2>添加图书页面</h2>

<form method="post" action="/addBookHtml">
    书名:<input name="name"  id="name" type="text"><br>
    价格:<input name="price"  id="price" type="text"><br>
    作者:<input name="author"  id="author" type="text"><br>
    <input type="submit" value="提交"/>
    <input type="reset" value="重设"/>
</form>
</body>
</html>

添加图书结果页面:addBookResult.html

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>添加图书结果</title>
</head>
<body>
<h2>添加图书结果</h2>
<div th:text="${tip}">
</div>
</body>
</html>

根据id查询图书:viewBook.html

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>查看图书</title>
</head>
<body>
<h2>查看图书</h2>
<div th:text="${book.name}"></div>
<div th:text="${book.price}"></div>
<div th:text="${book.author}"></div>

</div>
</body>
</html>

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

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

相关文章

基于Java+SpringBoot+Vue前后端分离成绩管理系统设计和实现

博主介绍&#xff1a;✌全网粉丝30W,csdn特邀作者、博客专家、CSDN新星计划导师、Java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专…

vue 脚手架新手入门(vue cli 3)

文章目录 1、vue中的 “:” 绑定和 “” 监听1.1、v-model 双向绑定 2、if 、else 、for3、computed 计算属性4、生命周期&#xff08;属性加载顺序&#xff09;5、watch 侦听器6、 components 组件6.1、props 从父组件获取收据6.2、emits 向父组件触发事件6.3、slots插槽&…

UART串口的8倍过采样和16倍过采样原理

由于在空闲状态时&#xff0c;传送线为逻辑“1”状态&#xff0c;而数据的传送总是以一个起始位“0”开始&#xff0c;所以当接收器检测到一个从"1"向"0”的跳变时&#xff0c;便视为可能的起始位&#xff08;要排除干扰引起的跳变) ;起始位被确认后,就知道发送…

java八股文面试[数据库]——JOIN优化

JOIN 是 MySQL 用来进行联表操作的&#xff0c;用来匹配两个表的数据&#xff0c;筛选并合并出符合我们要求的结果集。 JOIN 操作有多种方式&#xff0c;取决于最终数据的合并效果。常用连接方式的有以下几种: 什么是驱动表 ? 多表关联查询时,第一个被处理的表就是驱动表,使用…

大陆学者周志华当选IJCAI理事会主席,系54年来首次

8月25日&#xff0c;在澳门举行的第32届国际人工智能联合会议&#xff08;IJCAI &#xff09;2023闭幕式上&#xff0c;IJCAI 执行委员会宣布&#xff0c;南京大学周志华教授当选为新一届的国际人工智能联合会理事会&#xff08;IJCAI Trustee&#xff09;主席。周志华是中国大…

KT142C-sop16语音芯片ic的功能介绍 支持pwm和dac输出 usb直接更新内置空间

1.1 简介 KT142C是一个提供串口的SOP16语音芯片&#xff0c;完美的集成了MP3的硬解码。内置330KByte的空间&#xff0c;最大支持330秒的语音长度&#xff0c;支持多段语音&#xff0c;支持直驱0.5W的扬声器无需外置功放 软件支持串口通信协议&#xff0c;默认波特率9600.同时…

java网络编程,套接字socket

目录 一 网络概述 二 网络的类型分类 三 网络体系结构 四 网络通信协议概述 五 网络通信协议种类 六 Socket简介 七 Socket路径 八 java网络编程三要素 九 基于UDP协议的Socket编程 十 基于TCP协议的Socket编程 十一 基于TCP协议和UDP的区别 一 网络概述 多台相互连…

机器学习入门教学——独热编码One-hot

1、前言 在机器学习过程中&#xff0c;我们经常需要对特征进行分类&#xff0c;例如&#xff1a;性别有男、女&#xff0c;国籍有中国、英国、美国等&#xff0c;种族有黄、白、黑。 但是分类器并不能直接对数据进行分类&#xff0c;所以我们需要先对数据进行处理。如果要作为…

通信原理板块——正弦波加窄带高斯噪声、高斯白噪声、带限白噪声

1、正弦波加窄带高斯噪声 调制系统中&#xff0c;传输的信号是用正弦波作为载波的已调信号。通常信号经过信道传输时总会受到噪声的干扰&#xff0c;为了减少噪声的影响&#xff0c;在解调器的前端设置一个带通滤波器&#xff0c;以滤除信号频带以外的噪声。带通滤波器的输出是…

git: ‘lfs‘ is not a git command unclear

首先可以尝试 git lfs install 是否可以&#xff0c;不可以后就看这个连接&#xff1a;https://stackoverflow.com/questions/48734119/git-lfs-is-not-a-git-command-unclear。 我的是ubuntu&#xff0c;所以&#xff1a; git-lfs requires git version 1.8.3.1 or later. Yo…

linux运维(一)

一、端口号的范围是从1&#xff5e;65535。 其中1&#xff5e;1024是被RFC 3232规定好了的&#xff0c;被称作“众所周知的端口”(Well Known Ports)&#xff1b; 从1025&#xff5e;65535的端口被称为动态端口&#xff08;Dynamic Ports&#xff09;&#xff0c;可用来建立与…

Fast RCNN

【简介】 Fast RCNN[6]网络是RCNN和SPPNet的改进版&#xff0c;该网路使得我们可以在相同的网络配置下同时训练一个检测器和边框回归器。该网络首先输入图像&#xff0c;图像被传递到CNN中提取特征&#xff0c;并返回感兴趣的区域ROI&#xff0c;之后再ROI上运用ROI池化层以保证…

Openvslam

文章目录 Openvslam 学习报告什么是Openvslam概念特点 安装和运行OpenVSLAM克隆源代码安装依赖库测试&#xff08;环境已经安装成功&#xff09;运行运行失败的总结运行成功 系统设计模块和函数接口调用流程流程图参考资料 Openvslam 学习报告 什么是Openvslam 概念 OpenVSL…

FPGA GTH aurora 8b/10b编解码 PCIE 视频传输,提供2套工程源码加QT上位机源码和技术支持

目录 1、前言免责声明 2、我这里已有的 GT 高速接口解决方案3、GTH 全网最细解读GTH 基本结构GTH 发送和接收处理流程GTH 的参考时钟GTH 发送接口GTH 接收接口GTH IP核调用和使用 4、设计思路框架视频源选择silicon9011解码芯片配置及采集动态彩条视频数据组包GTH aurora 8b/10…

Vue3+Vue-i18n+I18N ALLY+VSCODE 自动翻译多国语言

ps: 效果图放前面,符合的往下看&#xff0c;不符合的出门右转&#xff0c;希望多多点赞评论支持。 三种语言模式&#xff0c;分别是中文、英文、日文 批量翻译 最后的结果 配置vue-i18n 1、下载安装vue-i18n&#xff0c;9以上的版本。 2、创建对应文件夹 3、对应文件夹中代…

【迪文屏幕】开发资料

1、应用手册 《T5L DGUSII 应用开发指南202306.pdf》&#xff0c;这个文档上面&#xff0c;详细介绍了各种控件的使用方法。 这个文档可以在官方论坛上找到&#xff0c;也可以直接在csdn上下载。 2、DGUS Tool 界面设计工具&#xff0c;根据所选屏幕的系统选择对应的工具&am…

MES管理系统中,物料BOM为何如此重要

在制造企业中&#xff0c;物料清单&#xff08;BOM&#xff09;是描述产品组成结构的核心文件。它列出了制造产品所需的全部零件和组件&#xff0c;以及这些零件和组件的数量和所需工艺。BOM是MES生产管理系统的主要对象之一&#xff0c;它对于生产计划的制定、工艺路线的选择、…

Redis未授权访问漏洞实战

文章目录 概述Redis概述Redis 介绍Redis 简单使用Redis未授权漏洞危害 漏洞复现启动靶场环境POC漏洞验证EXP漏洞利用 总结 本次测试仅供学习使用&#xff0c;如若非法他用&#xff0c;与平台和本文作者无关&#xff0c;需自行负责&#xff01; 概述 ​ 本文章主要是针对于vulh…

JDK源码解析-ConcurrentHashMap

1. ConcurrentHashMap 思考&#xff1a;HashTable是线程安全的&#xff0c;为什么不推荐使用&#xff1f; HashTable是一个线程安全的类&#xff0c;它使用synchronized来锁住整张Hash表来实现线程安全&#xff0c;即每次锁住整张表让线程独占&#xff0c;相当于所有线程进行…

封装一个贡献度面板组件

说在前面 贡献度面板&#xff08;Contribution Graph&#xff09;是指在代码仓库中按时间展示每位开发者的提交情况的可视化图表。它会显示不同日期的提交次数&#xff0c;并用颜色的深浅表示提交的数量。 贡献度面板展现的好处有以下几点&#xff1a; 可视化展示&#xff1…