SpringBoot3-web开发笔记(下)
内容协商
实现:一套系统适配多端数据返回
多端内容适配:
1. 默认规则
SpringBoot 多端内容适配。
基于请求头内容协商:(默认开启)
客户端向服务端发送请求,携带HTTP标准的Accept请求头。
Accept: application/json(要求返回json形式的数据)、text/xml、text/yaml
服务端根据客户端请求头期望的数据类型进行动态返回
基于请求参数内容协商:(需要开启)
客户端发送参数时,携带一个format参数,其值就是我们要求的参数的形式
发送请求 GET /projects/spring-boot?format=json
匹配到 @GetMapping("/projects/spring-boot")
根据参数协商,优先返回 json 类型数据【需要开启参数匹配设置】
发送请求 GET /projects/spring-boot?format=xml,优先返回 xml 类型数据
代码举例:
Application.properties配置文件:
#使用参数进行内容协商
spring.mvc.contentnegotiation.favor-parameter=true
#自定义参数名,默认为format
spring.mvc.contentnegotiation.parameter-name=format
实体类
@Data
@JacksonXmlRootElement//可以写出xml文档
public class Person {
private Integer id;
private String username;
private String email;
private int age;
}
controller类
@RestController
@Slf4j
public class HelloController {
/**
* @RequestBody默认对象以json形式返回
* 想要返回xml形式的数据步骤:
* ①引入支持写出xml内容依赖:jackson-dataformat-xml
* ②在实体类加上注解 @JacksonXmlRootElement//可以写出xml文档
* ③可以 基于请求头内容协商或 基于请求参数内容协商 两种方式:要求返回xml/json形式的数据
* @return
*/
@GetMapping("/person")
public Person person(){
Person person = new Person();
person.setId(1);
person.setUsername("张三");
person.setEmail("aaa@qq.com");
person.setAge(19);
return person;
}
}
测试;
HttpMessageConverter原理(内容协商的底层原理)
希望返回yaml形式的数据
● HttpMessageConverter 怎么工作?合适工作?
● 通过定制 HttpMessageConverter 来实现多端内容协商
● 编写WebMvcConfigurer提供的configureMessageConverters底层,修改底层的MessageConverter
1. @ResponseBody由HttpMessageConverter处理
标注了@ResponseBody的返回值 将会由支持它的 HttpMessageConverter写给浏览器
如果controller方法的返回值标注了 @ResponseBody 注解
过程
①请求进来先来到DispatcherServlet的doDispatch()进行处理
② 找到一个 HandlerAdapter 适配器。利用适配器执行目标方法
③到RequestMappingHandlerAdapter来执行,调用invokeHandlerMethod()来执行目标方法
④目标方法执行之前,准备好两个东西
HandlerMethodArgumentResolver:参数解析器,确定目标方法每个参数值
HandlerMethodReturnValueHandler:返回值处理器,确定目标方法的返回值该怎么处理
⑤RequestMappingHandlerAdapter 里面的invokeAndHandle()(在invokeHandlerMethod()中调用此方法)真正执行目标方法
目标方法执行完成,会返回返回值对象
找到一个合适的返回值处理器 HandlerMethodReturnValueHandler(然后寻找合适的MessageConverter)
最终找到 RequestResponseBodyMethodProcessor能处理 标注了 @ResponseBody注解的方法
RequestResponseBodyMethodProcessor 调用writeWithMessageConverters ,利用MessageConverter把返回值写出去
上面解释:@ResponseBody由HttpMessageConverter处理
HttpMessageConverter 会先进行内容协商
遍历所有的MessageConverter看谁支持这种内容类型的数据
总结;@ResponseBody标注的方法最终会由MessaConverter进行内容协商写出去,系统中有什么MessageConverter(导那个依赖就有那个的MessageConverter)能处理,就用那个。
WebMvcAutoConfiguration提供几种默认HttpMessageConverters
● EnableWebMvcConfiguration通过 addDefaultHttpMessageConverters添加了默认的MessageConverter;如下:
○ ByteArrayHttpMessageConverter: 支持字节数据读写(将对象写成字节数组)
○ StringHttpMessageConverter: 支持字符串读写(写成字符串)
○ ResourceHttpMessageConverter:支持资源读写
○ ResourceRegionHttpMessageConverter: 支持分区资源写出
○ AllEncompassingFormHttpMessageConverter:支持表单xml/json读写
○ MappingJackson2HttpMessageConverter: 支持请求响应体Json读写
系统提供默认的MessageConverter 功能有限,仅用于json或者普通返回数据。额外增加新的内容协商功能,必须增加新的HttpMessageConverter
WebMvcAutoConfiguration
提供了很多默认设置。
判断系统中是否有响应的类,如果有就加入响应的HttpMessageConverter
增加yaml格式内容协商
/**
* 想要返回yaml格式的数据
* 步骤:
* ①导入相应的包
* 支持返回yaml格式的数据
* <dependency>
* <groupId>com.fasterxml.jackson.dataformat</groupId>
* <artifactId>jackson-dataformat-yaml</artifactId>
* </dependency>
* ② 在handler方法中通过mapper干涉(在底层,将返回值对象转成json形式,xml形式,yaml形式,... 都是由mapper来干涉的)
* 创建mapper对象,并传入yaml工厂的对象new YAMLFactory()
* new ObjectMapper(new YAMLFactory());
* 通过mapper调用writeValueAsString(person) ,传入要返回的对象,
* 此字符串就是yaml格式的
* ③内容协商(告知系统,存在一种yaml格式)
* 在application.properties中编写;
* #增加一种新的类型(返回对象的格式)
* #新格式的key--》yaml 新格式的value--》application/yaml(客户端发送请求指明返回对象格式的请求头Accept的值)
* spring.mvc.contentnegotiation.media-types.yaml=application/yaml
* ④在配置类中重写configureMessageConverters方法新增一个MessageConverter组件
增加HttpMessageConverter组件,专门负责把对象写出为yaml格式
⑤创建一个自定义的MessageConverter类
*
*/
controller类
@RestController
@Slf4j
public class HelloController {
@GetMapping("/person2")
public String person2() throws JsonProcessingException {
Person person = new Person();
person.setId(1);
person.setUsername("张三");
person.setEmail("aaa@qq.com");
person.setAge(19);
ObjectMapper mapper = new ObjectMapper(new YAMLFactory());//传入yaml工厂的对象new YAMLFactory()
//在底层,将返回值对象转成json形式,xml形式,yaml形式,... 都是由mapper来干涉的
String s = mapper.writeValueAsString(person);
System.out.println(s);//------------------------②在handler方法中通过mapper干涉
return s;
}
}
Application.properties文件-----------------③内容协商(告知系统,存在一种yaml格式)
#增加一种新的类型(返回对象的格式)
#新格式的key--》yaml 新格式的value--》application/yaml(客户端发送请求指明返回对象格式的请求头Accept的值)
spring.mvc.contentnegotiation.media-types.yaml=application/yaml
配置类(手自一体模式)-----------------------④在配置类中重写configureMessageConverters方法新增一个MessageConverter组件
@Configuration//这是一个配置类
public class MyConfig implements WebMvcConfigurer {
//配置能把对象转为yaml的messageConverter
/**
*通过converters.add()方法传入自定义的MessageConverter
* @param converters
*/
@Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
converters.add(new MyYamlHttpMessageConverter());
}
}
⑤自定义的MessageConverter
/**
* 创建一个yaml的MessageConverter
* 步骤:
* ①继承AbstractHttpMessageConverter<泛型> 该泛型代表,可以将什么样的类型转化为我们自定义的格式
* ②创建一个空参构造器在其中:
* 1创建mapper对象,并传入yaml工厂的对象new YAMLFactory(),通过mapper干涉对象的格式转换
* 2告诉SpringBoot这个MessageConverter支持那种媒体类型
* 创建一个媒体类(MediaType)对象,传入type("application/text")与subtype(yaml),字符编码----------与配置类中定义的媒体类型名一致
* 在构造器的首行传入调用super()传入MediaType对象
* ③实现三个方法
*/
public class MyYamlHttpMessageConverter extends AbstractHttpMessageConverter<Object> {
private ObjectMapper objectMapper= null;//把对象转成yaml
public MyYamlHttpMessageConverter(){
//告诉SpringBoot这个MessageConverter支持那种媒体类型
super(new MediaType("application", "yaml",Charset.forName("UTF-8")));
YAMLFactory factory = new YAMLFactory().disable(YAMLGenerator.Feature.WRITE_DOC_START_MARKER);
this.objectMapper=new ObjectMapper(factory);
}
@Override
protected boolean supports(Class<?> clazz) {
//只要是对象类型,不是基本类型都支持转换
return true;
}
/**
*readInternal方法配合注解;@RequestBody
* 把对象怎么读进来
*/
@Override
protected Object readInternal(Class<?> clazz, HttpInputMessage inputMessage) throws IOException, HttpMessageNotReadableException {
return null;
}//读数据
/**
*writeInternal方法配合注解@ResponseBody
* 把对象怎么写出去
* methodReturnValue--------------方法的返回值
* outputMessage---------------对应响应的输出流
* 步骤:
* ①通过outputMessage调用getBody()得到一个输出流------------body
* ②通过mapper对象调用writeValue(body,methodReturnValue)方法,传入输出流body与methodReturnValue返回值对象
* ③关闭输出流
*/
@Override
protected void writeInternal(Object methodReturnValue, HttpOutputMessage outputMessage) throws IOException, HttpMessageNotWritableException {
OutputStream body = outputMessage.getBody();//得到输出流
try {
this.objectMapper.writeValue(body,methodReturnValue);
} finally {
body.close();
}
// try(OutputStream os = outputMessage.getBody()){
// this.objectMapper.writeValue(os,methodReturnValue);
// }//------------------------try-with写法自动关流
}
}
总结:
如何增加其他
● 配置媒体类型支持:
○ spring.mvc.contentnegotiation.media-types.yaml=text/yaml
● 编写对应的HttpMessageConverter,要告诉Boot这个支持的媒体类型
● 把MessageConverter组件加入到底层
○ 容器中放一个`WebMvcConfigurer` 组件,并配置底层的MessageConverter
web开发-Thymeleaf
模板引擎
● 由于 SpringBoot 使用了嵌入式 Servlet 容器。所以 JSP 默认是不能使用的。
● 如果需要服务端页面渲染,优先考虑使用 模板引擎。
模板引擎页面默认放在 src/main/resources/templates
SpringBoot 包含以下模板引擎的自动配置
● FreeMarker
● Groovy
● Thymeleaf
● Mustache
Thymelea整合
自动配置原理
1. 开启了 org.springframework.boot.autoconfigure.thymeleaf.ThymeleafAutoConfiguration 自动配置
2. 属性绑定在 ThymeleafProperties 中,对应配置文件 spring.thymeleaf 内容
3. 所有的模板页面默认在 classpath:/templates文件夹下
4. 默认效果
a. 所有的模板页面在 classpath:/templates/下面找--------前缀
b. 找后缀名为.html的页面
可以修改
spring.thymeleaf.prefix=前缀
spring.thymeleaf.suffix=后缀
#缓存的开启与关闭(默认时true开启的)
#推荐开发期间关闭,上线以后开启
spring.thymeleaf.cache=false
步骤:
①导入依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
②handler方法中利用模板引擎跳转到指定页面
* 1,由共享数据,将需要给页面共享的数据放到model中
* model调用addAttribute("msg",name)传入接收参数的变量名与参数
* 页面:<span th:text="${msg}"></span> ${}利用模板字符串
* 2,直接返回页面的地址(去掉前缀与后缀),实现跳转
* @return
* * 模板的逻辑视图名
* * 物理视图=前缀+逻辑视图名+后缀
* * 真实地址=classpath:/templates/welcome.html
测试代码
controller类
@Controller//适配服务端渲染 前后端不分离模式
public class WelcomeController {
/**
* 利用模板引擎跳转到指定页面
* ①由共享数据,将需要给页面共享的数据放到model中
* model调用addAttribute("msg",name)传入接收参数的变量名与参数
* 页面:<span th:text="${msg}"></span> ${}利用模板字符串
* ②直接返回页面的地址(去掉前缀与后缀),实现跳转
* @return
* * 模板的逻辑视图名
* * 物理视图=前缀+逻辑视图名+后缀
* * 真实地址=classpath:/templates/welcome.html
*/
@GetMapping("/well")
public String hello(@RequestParam("name") String name, Model model){
model.addAttribute("msg",name);
return "welcome";
}
}
核心用法
th:xxx:动态渲染指定的 html 标签属性值、或者th指令(遍历、判断等)
● th:text:标签体内文本值渲染
○ th:utext:不会转义,显示为html原本的样子。
● th:属性:标签指定属性渲染
● th:attr:标签任意属性渲染
● th:ifth:each...:其他th指令
代码举例:html文件
<body>
<h1>你好: <span th:text="${msg}"></span></h1>
<hr>
th:任意html属性;实现动态替换任意属性的值
th:text 替换标签体的内容 (哈哈被替换为msg的内容)---------------不会识别html的标签,会将html标签转义
th:utext 替换标签体的内容----------------会识别html的标签
<h1 th:text="${msg}">哈哈</h1>
<h1 th:utext="${msg}">呵呵</h1>
th:src 动态的路径
<img th:src="${imgUrl}" style="width:300px"/>
th:attr 任意属性指定(所有的属性都可以从attr中动态取出)
<img th:attr="src=${imgUrl},style=${style}"/>
th:其他指令
<img th:src="${imgUrl}" th:if="${show}"/>
</body>
表达式:用来动态取值
● ${}:变量取值;使用model共享给页面的值都直接用${}
● @{}:url路径;(自动处理应用上下文路径,支持绝对相对路径,动态拼接参数)
举例:
@{} 专门用来去各种路径
<img th:src="@{${imgUrl}}" th:if="${show}"/>
● #{}:国际化消息
● ~{}:片段引用
● *{}:变量选择:需要配合th:object绑定对象
系统工具&内置对象
● param:请求参数对象
● session:session对象
● application:application对象
● #execInfo:模板执行信息
● #messages:国际化消息
● #uris:uri/url工具
● #conversions:类型转换工具
● #dates:日期工具,是java.util.Date对象的工具类
● #calendars:类似#dates,只不过是java.util.Calendar对象的工具类
● #temporals: JDK8+ java.time API 工具类
● #numbers:数字操作工具
● #strings:字符串操作
● #objects:对象操作
● #bools:bool操作
● #arrays:array工具
● #lists:list工具
● #sets:set工具
● #maps:map工具
● #aggregates:集合聚合工具(sum、avg)
● #ids:id生成工具
代码举例:
转大写:<h1 th:text="${#strings.toUpperCase(msg)}">哈哈</h1>
语法示例
表达式:
● 变量取值:${...}
● url 取值:@{...}
● 国际化消息:#{...}
● 变量选择:*{...}
● 片段引用: ~{...}
常见:
● 文本: 'one text','another one!',...
● 数字: 0,34,3.0,12.3,...
● 布尔:true、false
● null: null
● 变量名: one,sometext,main...
文本操作:
● 拼串: +
● 文本替换:| The name is ${name} |
举例:
拼接操作 | |代表要进行拼接操作
<h1 th:text="${'前缀'+msg+'后缀'}">哈哈</h1>
<h1 th:text="|前缀:${msg} 后缀|">哈哈</h1>
布尔操作:
● 二进制运算: and,or
● 取反:!,not
比较运算:
● 比较:>,<,<=,>=(gt,lt,ge,le)
● 等值运算:==,!=(eq,ne)
条件运算:
● if-then: (if)?(then)
● if-then-else: (if)?(then):(else)
● default: (value)?:(defaultValue)
Thymeleaf遍历
遍历语法: th:each="元素名,迭代状态 : ${集合}"
迭代状态 有以下属性:
● index:当前遍历元素的索引,从0开始
● count:当前遍历元素的索引,从1开始
● size:需要遍历元素的总数量
● current:当前正在遍历的元素对象
● even/odd:是否偶数/奇数行
● first:是否第一个元素
● last:是否最后一个元素
Thymeleaf判断
th:if
如果if中的语句为true,渲染该元素,否完全移除(不会生成空标签)
th:switch
行内写法:[[...]] or [(...)]
代码举例:
controller类
@Controller//适配服务端渲染 前后端不分离模式
public class WelcomeController {
@GetMapping("/list")
public String list(Model model){
List<Person> list = Arrays.asList(
new Person(1, "张三1", "zsl@qq.com", 15),
new Person(1, "张三2", "zsl@qq.com", 15),
new Person(1, "张三3", "zsl@qq.com", 15),
new Person(1, "张三4", "zsl@qq.com", 15),
new Person(1, "张三5", "zsl@qq.com", 15)
);
model.addAttribute("persons",list);//与页面共享数据
return "list";
}
}
List.html文件
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<table>
<thead>
<tr>
<th>id</th>
<th>username</th>
<th>email</th>
<th>age</th>
<th>状态索引</th>
</tr>
</thead>
<tbody>
<tr th:each="person,stats : ${persons}">
<!-- 行内写法:[[...]] or [(...)]-->
<th>[[${person.id}]]</th>
<th th:text="${person.username}"></th>
<!-- 判断语法-->
<!--th:if-->
<th th:if="${#strings.isEmpty(person.email)}" th:text="联系不上"></th>
<th th:if="not ${#strings.isEmpty(person.email)}" th:text="${person.email}"></th>
<!-- 三目运算符 <th th:text="|${person.age}-${person.age>=18? '成年':'未成年'}|"></th>-->
<!-- th:switch-->
<th th:switch="${person.age}">
<button th:case="15">未成年</button>
<button th:case="16">未成年</button>
<button th:case="17">未成年</button>
<button th:case="18">成年</button>
<button th:case="19">成年</button>
</th>
<th th:text="${stats.index}"></th>
</tr>
</tbody>
</table>
</body>
</html>
属性优先级
Order | Feature | Attributes |
1 | 片段包含 | th:insert th:replace |
2 | 遍历 | th:each |
3 | 判断 | th:if th:unless th:switch th:case |
4 | 定义本地变量 | th:object th:with |
5 | 通用方式属性修改 | th:attr th:attrprepend th:attrappend |
6 | 指定属性修改 | th:value th:href th:src ... |
7 | 文本值 | th:text th:utext |
8 | 片段指定 | th:fragment |
9 | 片段移除 | th:remove |
片段包含>遍历>判断
变量选择
<div th:object="${session.user}">
<p>Name: <span th:text="*{firstName}">Sebastian</span>.</p>
<p>Surname: <span th:text="*{lastName}">Pepper</span>.</p>
<p>Nationality: <span th:text="*{nationality}">Saturn</span>.</p>
</div>
等同于
<div>
<p>Name: <span th:text="${session.user.firstName}">Sebastian</span>.</p>
<p>Surname: <span th:text="${session.user.lastName}">Pepper</span>.</p>
<p>Nationality: <span th:text="${session.user.nationality}">Saturn</span>.</p>
</div
模板布局
(把公共的部分抽取出来,在别的页面可以引用)
● 定义模板: th:fragment="片段名"
● 引用模板:~{templatename::selector}即 ~{模板名:: 片段名}
● 插入模板:th:insert、th:replace="~{模板名:: 片段名}"
代码举例
写在footer.html文件中的公共部分
<footer th:fragment="copy">© 2011 The Good Thymes Virtual Grocery</footer>
其他文件引用公共部分
引用格式: ~{模板名:: 片段名}
<body>
<div th:insert="~{footer :: copy}"></div>
<div th:replace="~{footer :: copy}"></div>
</body>
<body>
结果:
<body>
<div>
<footer>© 2011 The Good Thymes Virtual Grocery</footer>
</div>
<footer>© 2011 The Good Thymes Virtual Grocery</footer>
</body>
</body>
Devtools使用
(修改.xml文件,浏览器显示的内容立即同步更新)
当修改Thymeleaf模板文件(.html)时:
自动更新加载
即时生效,刷新浏览器即可看到更改
java代码的修改,如果devtools热启动了,可能会引起一些bug,难以排查
使用:
①导入依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
</dependency>
②修改完.xml文件后要ctrl+f9刷新
相关文章:
SpringBoot3-web开发笔记(下)
内容协商 实现:一套系统适配多端数据返回 多端内容适配: 1. 默认规则 SpringBoot 多端内容适配。 基于请求头内容协商:(默认开启) 客户端向服务端发送请求,携带HTTP标准的Accept请求头。 Accept: applica…...
关于无线网络安全的基础知识,涵盖常见威胁、防护措施和实用建议
无线网络(WiFi)的普及极大地方便了我们的生活,但其开放性也带来了诸多安全隐患。以下是关于无线网络安全的基础知识,涵盖常见威胁、防护措施和实用建议: 一、无线网络常见安全威胁 窃听(Eavesdropping) 攻击者通过监听无线信号,截获未加密的数据(如登录密码、聊天记录…...
《基于 RNN 的股票预测模型代码优化:从重塑到直接可视化》
在深度学习领域,使用循环神经网络(RNN)进行股票价格预测是一个常见且具有挑战性的任务。本文将围绕一段基于 RNN 的股票预测代码的改动前后差别展开,深入剖析代码的优化思路和效果。 原始代码思路与问题 原始代码实现了一个完整…...
【leetcode刷题日记】lc.347-前 K 个高频元素
目录 1.题目 2.代码 1.题目 给你一个整数数组 nums 和一个整数 k ,请你返回其中出现频率前 k 高的元素。你可以按 任意顺序 返回答案。 示例 1: 输入: nums [1,1,1,2,2,3], k 2 输出: [1,2]示例 2: 输入: nums [1], k 1 输出: [1] 提示: 1 <…...
进程I·介绍、查看、创建与状态
目录 介绍 PCB(进程控制块) task_struct 查看、创建进程 进程状态 小知识 介绍 进程:PCB(process control block)(内核数据结构) 代码和数据 进程创建:操作系统将其相关属性信…...
[k8s]随笔- spec内容整理
面对 Kubernetes 中 spec 字段的复杂性,关键在于建立 层次化的分类逻辑 和 功能导向的归纳方法。以下是具体的规整思路和实践步骤,帮助你理清脉络、高效使用: 一、按资源类型分层:先分“大类”,再钻“细节” K8s 资源…...
程序化广告行业(81/89):行业术语解析与日常交流词汇指南
程序化广告行业(81/89):行业术语解析与日常交流词汇指南 在程序化广告这个不断发展的行业中,持续学习和知识共享是我们紧跟潮流、提升能力的关键。一直以来,我都希望能和大家一起探索这个领域,共同进步。今…...
层归一化(Layer Normalization) vs 批量归一化(Batch Normalization)
层归一化和批量归一化都是 归一化方法,目的是让训练更稳定、收敛更快,但应用场景和工作方式大不相同。 名称一句话解释BatchNorm对 同一通道、不同样本之间 做归一化,适合图像任务,依赖 Batch Size。LayerNorm对 每个样本自身所有特征维度 做归一化,适合序列任务,不依赖 …...
【杂谈】-开源 AI 的复兴:Llama 4 引领潮流
开源 AI 的复兴:Llama 4 引领潮流 文章目录 开源 AI 的复兴:Llama 4 引领潮流一、Llama 4:开源 AI 的挑战者二、真实利他还是战略布局?三、对开发者、企业和人工智能未来的启示 在过去的几年里,AI 领域发生了重大转变。…...
instructor 库实现缓存
目录 代码代码解释1. 基础设置2. 客户端初始化3. 数据模型定义4. 缓存设置5. 缓存装饰器6. 示例函数工作流程 示例类似例子 代码 import functools import inspect import instructor import diskcachefrom openai import OpenAI, AsyncOpenAI from pydantic import BaseModel…...
【日志链路】⭐️SpringBoot 整合 TraceId 日志链路追踪!
💥💥✈️✈️欢迎阅读本文章❤️❤️💥💥 🏆本篇文章阅读大约耗时6分钟。 ⛳️motto:不积跬步、无以千里 📋📋📋本文目录如下:🎁🎁&am…...
QT6 源(16):存储 QT 里元对象的类信息的类 QMetaClassInfo 的类,只有两个成员函数 name()、value(),比元对象属性简单多了
(1)所在头文件 qmetaobject.h : class Q_CORE_EXPORT QMetaClassInfo { private: //private 属性里包含了至关重要的数据成员的定义,放前面struct Data {enum { Size 2 };const uint * d; //包含了数组的起始地址uint name ()…...
deskflow使用教程:一个可以让两台电脑鼠标键盘截图剪贴板共同使用的开源项目
首先去开源网站下载:Release v1.21.2 deskflow/deskflow 两台电脑都要下载这个文件 下载好后直接打开找到你想要的exe desflow.exe 然后你打开他,将两台电脑的TLS都关掉 下面步骤两台电脑都要完成: 电脑点开edit-》preferences 把这个取…...
波束形成(BF)从算法仿真到工程源码实现-第六节-广义旁瓣消除算法(GSC)
一、概述 本节我们讨论广义旁瓣消除算法(GSC),包括原理分析及代码实现。 更多资料和代码可以进入https://t.zsxq.com/qgmoN ,同时欢迎大家提出宝贵的建议,以共同探讨学习。 二、原理分析 广义旁瓣消除(GSC)算法 GSC算法是与LCMV算法等效的&…...
企业数字化转型需要注重的深层维度:生成式AI时代的战略重构
企业数字化转型正在经历从"技术适配"到"基因重组"的质变。生成式AI技术的突破性发展,要求企业超越传统信息化框架,构建全新的数字化转型认知体系。本文将从战略认知、技术融合、组织进化、伦理治理、生态协作五个维度,系统解构企业数字化转型需注重的核…...
图论之并查集——含例题
目录 介绍 秩是什么 例子——快速入门 例题 使用路径压缩,不使用秩合并 使用路径压缩和秩合并 无向图和有向图 介绍 并查集是一种用于 处理不相交集合的合并与查询问题的数据结构。它主要涉及以下基本概念和操作: 基本概念: 集合&…...
解释型语言和编译型语言的区别
Python 的执行过程通常涉及字节码,而不是直接将代码编译为机器码。以下是详细的解释: ### **Python 的执行过程** 1. **源代码到字节码**: - Python 源代码(.py 文件)首先被编译为字节码(.pyc 文件&…...
零基础上手Python数据分析 (14):DataFrame 数据分组与聚合 - 玩转数据透视,从明细到洞察
写在前面 —— 像搭积木一样分析数据,掌握Pandas GroupBy,轻松实现分组统计与聚合 回顾一下,上篇博客我们学习了如何使用 Pandas 合并与连接多个 DataFrame,将分散的数据整合到一起。 现在,我们拥有了更完整、更丰富的数据视图。 接下来,一个非常常见的分析需求就是 对…...
Honor of Kings (S39) 13-win streak
Honor of Kings (S39) 13-win streak S39赛季13连胜,庄周,廉颇硬辅助,对面有回血就先出红莲斗盆,有遇到马克没带净化的,出【冰霜冲击】破他大招 S39,庄周廉颇前排硬辅助全肉全堆血13连胜_哔哩哔哩bilibi…...
输出流-----超级详细的在程序中向文件.txt中写入内容
1.使用Fileoutputstream对象,如果在目录中已经存在该文件,那么将不会在创建,如果该目录中没有该文件,那么将会自动创建文件。 2.在目录中a.txt文件中写入一个h字符,这种方式是写入单个字符。 //在目录中a.txt文件中写入…...
【Mysql】死锁问题详解
【Mysql】死锁问题详解 【一】Mysql中锁分类和加锁情况【1】按锁的粒度分类(1)全局锁(2)表级锁1、表共享读锁(Table Read Lock)2、表独占写锁(Table Write Lock)3、元数据锁…...
C语言实现用户管理系统
以下是一个简单的C语言用户管理系统示例,它实现了用户信息的添加、删除、修改和查询功能。代码中包含了详细的注释和解释,帮助你理解每个部分的作用。 #include <stdio.h> #include <stdlib.h> #include <string.h>#define MAX_USERS…...
SAP BDC:企业数据管理的新纪元
2025年4月,SAP在纽约发布了其全新企业数据平台——Business Data Cloud(BDC),标志着企业数据管理和AI集成战略的重大升级。BDC不仅整合了SAP内部和外部的结构化与非结构化数据,还借助与Databricks的合作,推…...
数学建模学习资料免费分享:历年赛题与优秀论文、算法课程、数学软件等
本文介绍并分享自己当初准备数学建模比赛时,收集的所有资料,包括历年赛题与论文、排版模板、算法讲解课程与书籍、评分标准、数学建模软件等各类资料。 最近,准备将自己在学习过程中,到处收集到的各类资料都整理一下,并…...
计算机的运算方式
1. 计算机运算的基本概念 计算机的运算由 算术逻辑单元(ALU) 执行,其核心功能是完成 算术运算 和 逻辑运算。所有运算均基于二进制编码,通过硬件电路实现高速计算。 运算对象:二进制数(定点数、浮点数&am…...
Tkinter事件与绑定
在Tkinter中,事件和事件绑定是实现用户交互的核心机制。通过事件机制,您可以捕捉用户的操作(例如鼠标点击、键盘输入等)并执行相应的回调函数。事件绑定是将事件与处理该事件的函数(或方法)关联起来。掌握事件和绑定技术是开发交互式应用程序的关键。 5.1 事件概述 事件…...
CAD 像素点显示图片——CAD二次开发 OpenCV实现
效果如下: 部分代码如下: public class Opencv1{[CommandMethod("xx1")]public void Opencv(){Document doc Application.DocumentManager.MdiActiveDocument;Database db doc.Database;Editor ed doc.Editor;// 设置采样精度,这…...
即梦+剪映:三国演义变中国好声音制作详解!
最近在刷抖音时,发现这种电影人物唱歌视频比较火热,今天手把手教大家如何制作这种让电影人物唱歌的视频! 一、素材准备 1、准备好视频或人物图片素材 这里需要准备一张人物截图或者电影视频片段,大家可以去各大视频网站找原始素…...
04-线程
一、线程的概念 1、进程是系统分配资源的最少单位,操作系统会为每一个进程分配一块虚拟内存空间! 线程是系统调度最少的单位,操作系统分配时间片的过程,就是系统调度! 线程也会占用时间片! 2、线程的内存资源 线程的内存资源是…...
7.渐入佳境 -- 优雅的断开套接字连接
前言 本章将讨论如何优雅地断开相互连接的套接字。之前用的方法不够优雅是因为,我们是调用close或closesocket函数单方面断开连接的。 一、基于TCP的半关闭 TCP中的断开连接过程比建立连接过程更重要,因为连接过程中一般不会出现大的变数,…...
Django3 - 开启Django Hello World
一、开启Django Hello World 要学习Django首先需要了解Django的操作指令,了解了每个指令的作用,才能在MyDjango项目里编写Hello World网页,然后通过该网页我们可以简单了解Django的开发过程。 1.1 Django的操作指令 无论是创建项目还是创建项…...
JavaScript 基础特性
一、变量特性 1.1 变量提升 console.log(temp); // undefined(变量提升但未初始化) var temp hello; 现象:var声明的变量会提升至作用域顶部,但赋值不提升 建议:改用 let/const 避免变量提升问题 1.2 变量泄露 fo…...
MATLAB遇到内部问题,需要关闭,Crash Decoding : Disabled - No sandbox or build area path
1.故障界面 MATLAB运行时突然中断,停止运行。故障界面如图: MATLAB Log File: C:\Users\wei\AppData\Local\Temp\matlab_crash_dump.21720-1 ------------------------------------------------ MATLAB Log File -----------------------------------…...
L1-5 吉老师的回归
题目 L1-078 吉老师的回归(15分) 曾经在天梯赛大杀四方的吉老师决定回归天梯赛赛场啦! 为了简化题目,我们不妨假设天梯赛的每道题目可以用一个不超过 500 的、只包括可打印符号的字符串描述出来,如:Probl…...
0413-多态、Object类方法、访问权限修饰符、装箱拆箱、128陷阱
1:A and A 2:A and A 3: A and D 4: B and A 5: B and A 6:A and D 7:B and A 8: B and A 9:A and D package 第四章对象和类;public class ForthThir {//多态:父类的引用指向子类的对象,只能调父类的方法和子类重写的方法,不能调子类独有的方法&…...
Kubernetes控制平面组件:APIServer 准入控制机制详解
云原生学习路线导航页(持续更新中) kubernetes学习系列快捷链接 Kubernetes架构原则和对象设计(一)Kubernetes架构原则和对象设计(二)Kubernetes架构原则和对象设计(三)Kubernetes控…...
苍穹外卖day02
菜品相关接口开发 图片上传-阿里云OSS 依赖注入 <dependency><groupId>com.aliyun.oss</groupId><artifactId>aliyun-sdk-oss</artifactId><version>${aliyun.sdk.oss}</version> </dependency> 配置密钥 sky:alioss:end…...
SpringBoot 自定义输出控制台图标
对于控制台输出的这个图标大家都不陌生吧,不仅在SpringBoot中有这种图标,在docker 、 nginx 启动时都有自身独特的图标,这是怎么实现的呢。 需要利用一个网站生成 banner 图标(首页-bootschool.net), 将图标…...
联想电脑开机出现Defalut Boot Device Missing or Boot Failed怎么办
目录 一、恢复bios默认设置 二、关机重启 三、“物理”方法 在图书馆敲代码时,去吃了午饭回来发现刚开机就出现了下图的问题(崩溃),想起之前也发生过一次 这样的问题,现在把我用到的方法写在下面,可能对…...
CST1020.基于Spring Boot+Vue汽车租赁管理系统
计算机/JAVA毕业设计 【CST1020.基于Spring BootVue汽车租赁管理系统】 【项目介绍】 汽车租赁管理系统,基于 Spring Boot Vue 实现,功能丰富、界面精美 【业务模块】 客户管理:查询客户信息、根据条件精准检索、添加客户信息、身份证号校验…...
ArkTS基础语法:从声明到类型的深度解析
# ArkTS基础语法:从声明到类型的深度解析 在鸿蒙应用开发的领域中,ArkTS作为重要的编程语言,其基础语法是开发者们必须掌握的关键内容。今天,我们就围绕ArkTS的声明和类型相关知识展开深入探讨,帮助大家更好地理解和运…...
Day15:关于MySQL的编程技术——基础知识
前言:先创建一个练习的数据库和数据 1.创建数据库并创建数据表的基本结构 -- 创建练习数据库 CREATE DATABASE db_programming; USE db_programming;-- 创建员工表(包含各种数据类型) CREATE TABLE employees (emp_id INT PRIMARY KEY AUTO…...
wsl下编译eXosip和osip库(Ubuntu 22.04)
1.下载eXosip和osip osip下载路径 Index of /mirror/gnu.org/savannah/osip eXosip下载路径 Index of /nongnu/exosip 我选的osip和eXosip版本为 5.2.0 2.编译osip库 tar -zxvf libosip2-5.2.0.tar.gz cd libosip2-5.2.0 ./configure make make install 在编译…...
《轨道力学导论》——第九章:轨道确定与导航
第九章 轨道确定与导航 引言 轨道确定与导航是轨道力学中最为核心的实践领域之一,它将理论与实际应用紧密结合,解决了"我们在哪里"以及"我们将去向何方"这两个航天活动中最基本的问题。无论是地球轨道上的人造卫星、飞向深空的探测…...
几何与游标
在arcgis中,数据组织方式如下 数据库(datasets): 要素类(feature class): 几何(geometry) 属性(attribute) 元数据(metadata) 游标: 查询游标:用于对数据进行查询的游标 arcpy.da.SearchCursor() 作用:用于对数据进行只读查询操作。它可以帮助你逐行读取数据表或…...
【使用jenkins+docker自动化部署java项目】
背景: 有A(打包机129),B(游戏服130) 2个机器,他们都安装有docker,请完成部署。 一、准备好java项目,写好Dockerfile # 基础镜像,使用包含 JDK 17 的 OpenJDK 镜像 FROM openjdk:17-jdk-slim# 设置工作目录 WORKDIR /…...
Vue3+Element Plus如何实现左树右表页面案例:即根据左边的树筛选右侧表功能实现
文章目录 一、最终效果二、源代码2.1 AddDataSource.vue2.2 LeftTree.vue2.3 FieldDrawer.vue2.4 RightTable.vue2.5 Emp.vue 三、代码解读3.1 AddDataSource.vue —— 数据源新增对话框3.2 LeftTree.vue —— 数据源树视图3.3 FieldDrawer.vue —— 字段详情抽屉3.4 RightTabl…...
Redisson的红锁,分段锁,公平锁,联锁。。。。。。
红锁:Redisson红锁可以防止主从集群锁丢失问题。Redisson红锁要求,必须要构建至少三个Redis主从集群,若一个请求要申请锁,必须向所有主从集群中提交key写入请求,只有当大多数集群(过半集群)锁写…...
system V 共享内存
system V是一种标准,linux内核支持这种标准,专门设计了一个ipc模板(通信的接口设计,原理,接口,相似性) 使用各自的虚拟地址访问物理内存 共享内存描述共享内存的内核数据结构它所对应的物理空间 进程间通信的本质&…...
ResNet改进(27):融合EfficientViT 高效混合网络设计
在计算机视觉领域,卷积神经网络(CNN)和视觉Transformer(ViT)各有优势。 今天分享的是一种将两者巧妙结合的方案——在ResNet18基础上引入轻量化ViT模块的设计思路。 整体架构概览 这个混合网络主要由三部分组成: ResNet18骨干网络:作为特征提取器,去掉了原模型的平均池化…...