【SpringBoot】FreeMarker视图渲染
目录
一、FreeMarker 简介
1.1 什么是FreeMarker?
1.2 Freemarker模板组成部分
1.3 为什么要使用FreeMarker
二、Springboot集成FreeMarker
2.1 配置
2.2 数据类型
2.2.1 字符串
2.2.2 数值
2.2.3 布尔值
2.2.4 日期
2.3 常见指令
2.3.2 assign
2.3.3 include
...
三、常见指令实现增删改查(综合案例)⭐
3.1 后端
3.2 前端
3.3 效果展示
3.3.1 新增功能
3.3.2 修改功能
3.3.3 查询功能
3.3.4 删除功能
一、FreeMarker 简介
1.1 什么是FreeMarker?
FreeMarker是一款 模板引擎 ,它允许开发人员使用模板和数据来生成输出文本,如HTML网页、电子邮件、配置文件和源代码等。它是一个Java类库,可以被嵌入到开发人员所创建的产品中。开发人员可以使用FreeMarker来动态生成和渲染视图,以便将数据呈现给最终用户。
官方手册https://freemarker.apache.org/
下面是一些关键点:
-
模板引擎: FreeMarker是一种模板引擎,允许开发者定义模板文件,其中包含要动态填充的占位符或表达式。这些模板文件可以包含HTML、XML、文本等。
-
动态内容生成: FreeMarker的主要用途是根据模板和数据生成最终的输出内容。模板中的占位符将被实际的数据替代,从而生成动态的、个性化的输出。
-
嵌入式组件: FreeMarker是一个Java类库,可以轻松地集成到Java应用程序中。这使得开发人员可以在他们的Java应用中使用FreeMarker来处理视图层的动态内容生成。
-
面向程序员: FreeMarker通常被程序员用于构建动态的用户界面或生成其他类型的文本输出。它不直接面向最终用户,而是提供给开发人员一个工具,使他们能够以更灵活和动态的方式生成内容。
1.2 Freemarker模板组成部分
FreeMarker模板文件主要由如下4个部分组成:
-
文本:直接输出的部分
-
注释:使用 <#-- ... --> 格式做注释,里面内容不会输出
-
插值:即 ${...} 或 #{...} 格式的部分,类似于占位符,将使用数据模型中的部分替代输出
-
FTL指令:即FreeMarker指令,全称是:FreeMarker Template Language,和HTML标记类似,但名字前加#予以区分,不会输出
1.3 为什么要使用FreeMarker
FreeMarker在Spring Boot中被广泛使用的原因与其特性和与Spring Boot的集成有关。
-
轻量级: FreeMarker相对轻量,不引入过多的依赖,易于集成和使用。
-
与Spring框架整合良好: FreeMarker与Spring框架集成良好,通过Spring Boot的自动配置,可以很容易地配置FreeMarker作为模板引擎。
-
Spring Boot 默认支持: Spring Boot对多个模板引擎提供了自动配置支持,包括FreeMarker。因此,Spring Boot项目中使用FreeMarker非常方便,只需在依赖中引入相应的starter即可。
-
开箱即用: FreeMarker可以作为Spring Boot的一部分,无需额外的配置。这使得开发者能够快速启动项目并使用FreeMarker构建视图。
-
简化模板文件的构建: FreeMarker的模板语法相对简洁,可以更容易地与后端Java代码交互。在Spring Boot项目中,Java对象的数据可以直接在FreeMarker模板中使用。
FreeMarker的诞生是为了取代JSP。虽然JSP功能强大,可以写Java代码实现复杂的逻辑处理,但是页面会有大量业务逻辑,不利于维护和阅读,更不利于前后台分工,容易破坏MVC结构,所以舍弃JSP,选择使用FreeMarker是大势所趋。
二、Springboot集成FreeMarker
2.1 配置
1、配置pom.xml,引入依赖:
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-freemarker</artifactId>
</dependency>
2、添加application.yml配置:
freemarker:# 设置模板后缀名suffix: .ftl# 设置文档类型content-type: text/html# 设置页面编码格式charset: UTF-8# 设置页面缓存cache: false# 设置ftl文件路径template-loader-path: classpath:/templates# 设置静态文件路径,js,css等mvc:static-path-pattern: /static/**
3、新建模板文件(.ftl)
在resources/templates目录新建一个.ftl文件
第一创建是没有这个文件类型的选项的,所以我们要定义个.ftl格式的文件:
settings --> Editor --> File and Code Templates
该内容模板于html差不多的,最后在创建文件的时候就有个一个.ftl格式的文件选项
index.ftl:
<!DOCTYPE html>
<html lang="zh">
<head><meta charset="UTF-8"><title>Freemarker</title>
</head>
<body>
<h1>Hello FreeMarker!!!</h1>
</body>
</html>
Controller:
package com.ycxw.boot.controller;import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;/*** @author 云村小威* @create 2023-12-13 18:57*/
@Controller
public class IndexController {@RequestMapping("/")public String home(){return "index";}
}
一个基本的数据显示就成功了
2.2 数据类型
2.2.1 字符串
在文本中确定字符串值的方法是看双引号,比如: "some text"
,或单引号,比如: 'some text'
。这两种形式是等同的。 如果文本自身包含用于字符引用的引号 ( "
或 '
)或反斜杠时, 应该在它们的前面再加一个反斜杠;这就是转义。 转义允许直接在文本中输入任何字符, 也包括换行。
${"It's \"quoted\" and this is a backslash: \\"}
字符串类型处理:
方法 | 含义 |
---|---|
?substring(start,end) | 截取字符串(左闭右开) |
?uncap_first | 首字母小写输出 |
?cap_first | 首字母大写输出 |
?lower_case | 字母转小写输出 |
?upper_case | 字母转大写输出 |
?length | 获取字符串长度 |
?starts_with("xx")?string | 是否以指定字符开头(boolean类型) |
?ends_with("xx")?string | 是否以指定字符结尾(boolean类型) |
?index_of("xx") | 获取指定字符的索引 |
?trim | 去除字符串前后空格 |
?replace("xx","xx") | 替换指定字符串 |
字符串空值情况处理:
FreeMarker 的变量必须赋值,否则就会抛出异常。而对于 FreeMarker 来说,null 值和不存在的变量是完全一样的,因为 FreeMarker 无法理解 null 值。
<#-- 如果值不存在,直接输出会报错 -->
<#--${str}-->
<#-- 使用!,当值不存在时,默认显示空字符串 -->
${str!}<br>
<#-- 使用!"xx",当值不存在时,默认显示指定字符串 -->
${str!"这是一个默认值"}<br>
<#-- 使用??,判断字符串是否为空;返回布尔类型。如果想要输出,需要将布尔类型转换成字符串 -->
${(str??)?string}<br>
注意事项:
使用??或?starts_with("xx"),判断字符串是否为空或指定字符开头;返回布尔类型。如果想要输出,需要将布尔类型转换成字符串在后面添加 ?c or ?string
例如:
${"嗨害嗨"?starts_with("我")} ${str??}不进行转换则会报错
2.2.2 数值
输入不带引号的数字就可以直接指定一个数字, 必须使用点作为小数的分隔符而不能是其他的分组分隔符。
${0.45}<br>
${18}<br>
<#-- 将数值转换成字符串输出 -->
${1000?c} <br>
<#-- 将数值转换成货币类型的字符串输出 -->
${1000?string.currency} <br>
<#-- 将数值转换成百分比类型的字符串输出 -->
${0.45?string.percent} <br>
<#-- 将浮点型数值保留指定小数位输出 (##表示保留两位小数) -->
${0.45723123?string["0.##"]} <br>
2.2.3 布尔值
直接写 true
或者 false
就表示一个布尔值了,不需使用引号。
在freemarker中布尔类型不能直接输出;如果输出要先转成字符串
${flag?c}<br>
${flag?string}<br>
${flag?string("yes","no")}<br>
2.2.4 日期
日期变量可以存储和日期/时间相关的数据。
在freemarker中日期类型不能直接输出;如果输出要先转成日期型或字符串
日期格式输出:
输出方式 | 说明 |
---|---|
?date | 年月日 |
?time | 时分秒 |
?datetime | 年月日时分秒 |
?string("自定义格式") | 指定格式 |
<#-- 输出日期格式 -->
${createDate?date} <br>
<#-- 输出时间格式 -->
${createDate?time} <br>
<#-- 输出日期时间格式 -->
${createDate?datetime} <br>
<#-- 输出格式化日期格式 -->
${createDate?string("yyyy年MM月dd日 HH时mm分ss秒")} <br>
注意事项:
在.ftl文件中不能直接创建时间需要通过后端传入时间进行显示(替换掉createDate)
2.3 常见指令
2.3.2 assign
使用该指令你可以创建一个新的变量, 或者替换一个已经存在的变量。
案例演示:
<#-- 创建一个str的变量 -->
<#assign str="hello">
<#-- 输出str -->
${str} <br>
<#-- 一次创建多个变量 -->
<#assign num=1 names=["嗨","害","嗨"] >
${num} and ${names?join(",")}
2.3.3 include
可以使用它在你的模板中插入另外一个 FreeMarker 模板文件 (由 path
参数指定)
该标签主要用于引入其他资源,简化数据
首先创建一个公共页面定义一个变量存储本地访问路径
在index.ftl中进行引入调用src数值
<#-- 引入公共页面 -->
<#include "common.ftl">
<a href="${src}/xxx"></a>
...
还有如:if/elseif/else、list指令在下面的综合案例中进行演示👇
三、常见指令实现增删改查(综合案例)⭐
3.1 后端
BookMapper.xml
<select id="list" resultMap="BaseResultMap" resultType="com.ycxw.boot.entity.Book">select<include refid="Base_Column_List"/>from t_bookwhere 1=1<if test="bookname !=null and bookname !=''">and bookname like CONCAT('%',#{bookname},'%')</if></select>
在此添加了模糊查询的方法,其他的增删改都是自动生成。
BookMapper.java
package com.ycxw.boot.mapper;import com.ycxw.boot.entity.Book;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Repository;import java.util.List;/**
* @author 云村小威
* @description 针对表【t_book(书本信息表)】的数据库操作Mapper
* @createDate 2023-12-12 14:50:45
* @Entity com.ycxw.boot.entity.Book
*/
@Repository
public interface BookMapper {List<Book> list(@Param("bookname")String bookname);...其他方法
}
BookService.java
package com.ycxw.boot.service;import com.ycxw.boot.entity.Book;
import org.apache.ibatis.annotations.Param;import java.util.List;/*** @author 云村小威* @create 2023-12-12 15:11*/
public interface BookService {List<Book> list(@Param("bookname")String bookname);int insert(Book record);int deleteByPrimaryKey(Long id);int updateByPrimaryKey(Book record);
}
BookServiceImpl.java
package com.ycxw.boot.service.impl;import com.ycxw.boot.entity.Book;
import com.ycxw.boot.mapper.BookMapper;
import com.ycxw.boot.service.BookService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;import java.util.List;/*** @author 云村小威* @create 2023-12-12 15:12*/
@Service
public class BookServiceImpl implements BookService {@Autowiredprivate BookMapper bookMapper;@Overridepublic List<Book> list(String bookname) {return bookMapper.list(bookname);}@Overridepublic int insert(Book record) {return bookMapper.insert(record);}@Overridepublic int deleteByPrimaryKey(Long id) {return bookMapper.deleteByPrimaryKey(id);}@Overridepublic int updateByPrimaryKey(Book record) {return bookMapper.updateByPrimaryKey(record);}
}
IndexController.java
package com.ycxw.boot.controller;import com.ycxw.boot.entity.Book;
import com.ycxw.boot.service.BookService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;import java.util.List;/*** @author 云村小威* @create 2023-12-13 18:57*/
@Controller
public class IndexController {@Autowiredprivate BookService bookService;/*** 查询所有** @param model* @return*/@RequestMapping("/")public String home(Model model) {List<Book> list = bookService.list(null);model.addAttribute("book", list);return "index";}/*** 新增** @param book* @return*/@PostMapping("/add")public String add(@RequestBody Book book) {bookService.insert(book);return "redirect:/";}/*** 删除** @param book* @return*/@RequestMapping("/del")public String del(Book book) {bookService.deleteByPrimaryKey(book.getId().longValue());return "redirect:/";}/*** 修改** @param book* @return*/@PutMapping("/edit")public String edit(@RequestBody Book book) {bookService.updateByPrimaryKey(book);return "redirect:/";}/*** 模糊查询** @param bookname* @param model* @return*/@RequestMapping(value = "/search", method = RequestMethod.POST)public String search(@RequestParam("bookname") String bookname, Model model) {// 在这里使用 bookname 进行相关的处理List<Book> list = bookService.list(bookname);model.addAttribute("book", list);return "index"; // 返回搜索结果页面}}
3.2 前端
common.ftl (公共资源)
<#--引入当前项目的运行路径-->
<#assign src="${springMacroRequestContext.contextPath}">
<#--引入样式与脚本-->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.0/dist/css/bootstrap.min.css">
<script src="https://code.jquery.com/jquery-3.6.1.min.js"></script>
<!-- 引入Bootstrap的JavaScript文件(需要在jQuery之后引入) -->
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.0/dist/js/bootstrap.bundle.min.js"></script>
index.ftl(自定义引擎模版)
<!DOCTYPE html>
<html lang="zh">
<head><meta charset="UTF-8"><title>FreeMarker</title><#--引入公共模块--><#include "common.ftl">
</head>
<body>
<div class="container mt-5" id="body"><div class="row justify-content-center"><div class="col-3"><input type="text" class="form-control" id="input" placeholder="请输入书籍名称"style="width: 300px"/></div><div class="col-2"><button type="submit" class="btn btn-dark mb-3" onclick="query()">搜索</button><button type="button" class="btn btn-outline-dark mb-3" data-bs-toggle="modal"data-bs-target="#exampleModal">新增书籍</button></div></div><div class="row"><table class="table table-hover" style="width: 65%;margin: auto"><thead class="table-dark"><tr><th>序号</th><th>书籍名称</th><th>价格</th><th>类型</th><th>操作</th></tr></thead><tbody><#if book??><#list book as b><tr><td>${b.id}</td><td>${b.bookname}</td><td>${b.price}</td><td>${b.booktype}</td><td><a href="${src}/del?id=${b.id}">删除</a><a href="javascript:void(0);"onclick="editModal('${b.id}', '${b.bookname}', '${b.booktype}', ${b.price})"data-bs-toggle="modal" data-bs-target="#editModal">修改</a></td></tr></#list></#if></tbody></table></div>
</div>
<!-- 新增弹窗 -->
<div class="modal fade" id="exampleModal" tabindex="-1" aria-labelledby="exampleModalLabel" aria-hidden="true"><div class="modal-dialog"><div class="modal-content"><div class="modal-header"><h5 class="modal-title" id="exampleModalLabel">新增书籍</h5><button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button></div><div class="modal-body"><!-- 表单 --><form><div class="mb-3"><label for="title" class="form-label">书籍名称</label><input type="text" class="form-control" id="name" placeholder="请输入标题"></div><div class="mb-3"><label for="author" class="form-label">类型</label><select class="form-select" id="bookType" aria-label="Default select example"><option selected>请选择书籍类型</option><option value="动作">动作</option><option value="冒险">冒险</option><option value="文学">文学</option></select></div><div class="mb-3"><label for="price" class="form-label">价格</label><input type="number" class="form-control" id="price" placeholder="请输入价格"></div><button type="button" class="btn btn-outline-dark" data-bs-dismiss="modal" aria-label="Close">取消</button><button type="button" class="btn btn-dark" onclick="add()">提交</button></form></div></div></div>
</div>
<!-- 修改弹窗 -->
<div class="modal fade" id="editModal" tabindex="-1" aria-labelledby="exampleModalLabel" aria-hidden="true"><div class="modal-dialog"><div class="modal-content"><div class="modal-header"><h5 class="modal-title" id="exampleModalLabel">修改书籍</h5><button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button></div><div class="modal-body"><!-- 表单 --><form><div class="mb-3"><label for="id" class="form-label">书籍编号</label><input type="text" class="form-control" id="id" disabled></div><div class="mb-3"><label for="title" class="form-label">书籍名称</label><input type="text" class="form-control" id="name_edit" placeholder="请输入标题"></div><div class="mb-3"><label for="author" class="form-label">类型</label><select class="form-select" id="type_edit" aria-label="Default select example"><option selected>请选择书籍类型</option><option value="动作">动作</option><option value="冒险">冒险</option><option value="文学">文学</option></select></div><div class="mb-3"><label for="price" class="form-label">价格</label><input type="number" class="form-control" id="price_edit" placeholder="请输入价格"></div><button type="button" class="btn btn-outline-dark" data-bs-dismiss="modal" aria-label="Close">取消</button><button type="button" class="btn btn-dark" onclick="edit()">确认修改</button></form></div></div></div>
</div>
</body>
<script>/*模糊查询*/function query() {//获取输入值var name = $("#input").val();// 发送AJAX请求$.ajax({url: "${src}/search",type: "POST",contentType: "application/x-www-form-urlencoded",data: {"bookname": name},success: function (data) {//更新整个页面元素$("#body").html(data);}});}/*新增方法*/function add() {// 获取表单数据var name = $("#name").val();var type = $("#bookType").val();var price = $("#price").val();// 创建一个对象来存储表单数据var book = {bookname: name,booktype: type,price: price};// 发送AJAX请求$.ajax({url: "${src}/add",type: "POST",contentType: "application/json",data: JSON.stringify(book),success: function (res) {console.log(res);// 请求成功处理逻辑alert("书籍添加成功!");// 关闭弹窗var modal = $("#exampleModal");modal.modal("hide");// 刷新页面location.reload();}});}/* 修改方法(回显数据) */function editModal(id, name, type, price) {// 将数据设置到弹窗表单中$("#id").val(id);$("#name_edit").val(name);$("#type_edit").val(type);$("#price_edit").val(price);// 显示修改弹窗$("#editModal").modal("show");}/*修改方法*/function edit() {// 获取表单数据var id = $("#id").val();var name = $("#name_edit").val();var type = $("#type_edit").val();var price = $("#price_edit").val();// 创建一个对象来存储表单数据var book = {id: id,bookname: name,booktype: type,price: price};// 发送AJAX请求$.ajax({url: "${src}/edit",type: "PUT",contentType: "application/json",data: JSON.stringify(book),success: function (res) {console.log(res);// 请求成功处理逻辑alert("书籍修改成功!");// 关闭弹窗var modal = $("#editModal");modal.modal("hide");// 刷新页面location.reload();}});}
</script>
</html>
3.3 效果展示
3.3.1 新增功能
3.3.2 修改功能
3.3.3 查询功能
3.3.4 删除功能
相关文章:

【SpringBoot】FreeMarker视图渲染
目录 一、FreeMarker 简介 1.1 什么是FreeMarker? 1.2 Freemarker模板组成部分 1.3 为什么要使用FreeMarker 二、Springboot集成FreeMarker 2.1 配置 2.2 数据类型 2.2.1 字符串 2.2.2 数值 2.2.3 布尔值 2.2.4 日期 2.3 常见指令 2.3.2 assign 2.3…...

巴尔加瓦算法图解:算法运用。
树 如果能将用户名插入到数组的正确位置就好了,这样就无需在插入后再排序。为此,有人设计了一种名为二叉查找树(binary search tree)的数据结构。 每个node的children 都不大于两个。对于其中的每个节点,左子节点的值都比它小,…...

Docker的镜像和容器的区别
1 Docker镜像 假设Linux内核是第0层,那么无论怎么运行Docker,它都是运行于内核层之上的。这个Docker镜像,是一个只读的镜像,位于第1层,它不能被修改或不能保存状态。 一个Docker镜像可以构建于另一个Docker镜像之上&…...

忘记 RAG:拥抱Agent设计,让 ChatGPT 更智能更贴近实际
RAG(检索增强生成)设计模式通常用于开发特定数据领域的基于实际情况的ChatGPT。 然而,重点主要是改进检索工具的效率,如嵌入式搜索、混合搜索和微调嵌入,而不是智能搜索。 这篇文章介绍了一种新的方法,灵感…...

利用路由懒加载和CDN分发策略,对Vue项目进行性能优化
目录 一、Vue项目 二、路由懒加载 三、CDN分发策略 四、如何对Vue项目进行性能优化 一、Vue项目 Vue是一种用于构建用户界面的JavaScript框架,它是一种渐进式框架,可以用于构建单页应用(SPA)和多页应用。Vue具有简单易学、灵…...

【Scala】1. 变量和数据类型
1. 变量和数据类型 1.1 for begining —— hello world 新建hello.scala文件,注意object名字与文件名一致。 object hello { def main(args:Array[String]): Unit { println("hello world!") } }运行后打印结果如下: hello world!Pr…...

何时以及如何选择制动电阻
制动电阻的选择是优化变频器应用的关键因素 制动电阻器在变频器中是如何工作的? 制动电阻器在 VFD 应用中的工作原理是将电机减速到驱动器设定的精确速度。它们对于电机的快速减速特别有用。制动电阻还可以将任何多余的能量馈入 VFD,以提升直流母线上的…...

消息中间件:Puslar、Kafka、RabbigMQ、ActiveMQ
消息队列 消息队列:它主要用来暂存生产者生产的消息,供后续其他消费者来消费。 它的功能主要有两个: 暂存(存储)队列(有序:先进先出 从目前互联网应用中使用消息队列的场景来看,…...

Rust开发WASM,浏览器运行WASM
首先需要安装wasm-pack cargo install wasm-pack 使用cargo创建工程 cargo new --lib mywasm 编辑Cargo.toml文件,修改lib的类型为cdylib,并且添加依赖wasm-bindgen [package] name "mywasm" version "0.1.0" edition "…...

Vue3编写简单的App组件(二)
一、Vue3页面渲染基本流程 1、入口文件 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><link rel"icon" href"/favicon.ico"><meta name"viewport" content"widthde…...

java Servlet 云平台教学系统myeclipse定制开发SQLServer数据库网页模式java编程jdbc
一、源码特点 JSP 云平台教学系统是一套完善的web设计系统,对理解JSP java编程开发语言有帮助 系统采用serlvet dao bean,系统具有完整的源代码和数据库 ,系统主要采用B/S模式开发。开发 环境为TOMCAT7.0,Myeclipse8.5开发,数据…...
QT初始程序
#include "widget.h"#include <QApplication>int main(int argc, char *argv[]){QApplication a(argc, argv);Widget w;w.show();return a.exec();} 解释: Qt系统提供的类头文件没有.h后缀Qt一个类对应一个头文件,类名和头文件名一致QA…...

ubuntu22.04@laptop OpenCV Get Started: 001_reading_displaying_write_image
ubuntu22.04laptop OpenCV Get Started: 001_reading_displaying_write_image 1. 源由2. Read/Display/Write应用Demo2.1 C应用Demo2.2 Python应用Demo 3. 过程分析3.1 导入OpenCV库3.2 读取图像文件3.3 显示图像3.4 保存图像文件 4. 总结5. 参考资料 1. 源由 读、写、显示图像…...

51单片机之LED灯模块篇
御风以翔 破浪以飏 🎥个人主页 🔥个人专栏 目录 点亮一盏LED灯 LED的组成原理 LED的硬件模型 点亮一盏LED灯的程序设计 LED灯闪烁 LED流水灯 独立按键控制LED灯亮灭 独立按键的组成原理 独立按键的硬件模型 独立按键控制LED灯状态 按键的抖动 独立按键…...

springboo冬奥会科普平台源码和论文
随着信息技术和网络技术的飞速发展,人类已进入全新信息化时代,传统管理技术已无法高效,便捷地管理信息。为了迎合时代需求,优化管理效率,各种各样的管理平台应运而生,各行各业相继进入信息管理时代…...

改进神经网络
Improve NN 文章目录 Improve NNtrain/dev/test setBias/Variancebasic recipeRegularizationLogistic RegressionNeural networkother ways optimization problemNormalizing inputsvanishing/exploding gradientsweight initializegradient checkNumerical approximationgrad…...

HarmonyOS 开发学习笔记
HarmonyOS 开发学习笔记 一、开发准备1.1、了解ArkTs语言1.2、TypeScript语法1.2.1、变量声明1.2.2、条件控制1.2.3、函数1.2.4、类和接口1.2.5、模块开发 1.3、快速入门 二、ArkUI组件2.1、Image组件2.2、Text文本显示组件2.3、TextInput文本输入框组件2.4、Button按钮组件2.5…...
maven java 如何打纯源码zip包
一、背景 打纯源码包给第三方进行安全漏洞扫描 二、maven插件 项目中加入下面的maven 插件 <!-- 要将源码放上去,需要加入这个插件 --><plugin><artifactId>maven-source-plugin</artifactId><version>2.4</version><con…...
Altium Designer(AD)原理图库添加阵列管脚图文教程及视频演示
🏡《专栏目录》 目录 视频演示1,概述2,添加方法3,总结视频演示 Altium Designer(AD24)原理图库添加阵列管脚 欢迎点击浏览更多高清视频演示 1,概述...

P3647 题解
文章目录 P3647 题解OverviewDescriptionSolutionLemmaProof Main Code P3647 题解 Overview 很好的题,但是难度较大。 模拟小数据!——【数据删除】 Description 给定一颗树,有边权,已知这棵树是由这两个操作得到的࿱…...

【机器视觉】单目测距——运动结构恢复
ps:图是随便找的,为了凑个封面 前言 在前面对光流法进行进一步改进,希望将2D光流推广至3D场景流时,发现2D转3D过程中存在尺度歧义问题,需要补全摄像头拍摄图像中缺失的深度信息,否则解空间不收敛…...
测试markdown--肇兴
day1: 1、去程:7:04 --11:32高铁 高铁右转上售票大厅2楼,穿过候车厅下一楼,上大巴车 ¥10/人 **2、到达:**12点多到达寨子,买门票,美团/抖音:¥78人 3、中饭&a…...
linux 错误码总结
1,错误码的概念与作用 在Linux系统中,错误码是系统调用或库函数在执行失败时返回的特定数值,用于指示具体的错误类型。这些错误码通过全局变量errno来存储和传递,errno由操作系统维护,保存最近一次发生的错误信息。值得注意的是,errno的值在每次系统调用或函数调用失败时…...
unix/linux,sudo,其发展历程详细时间线、由来、历史背景
sudo 的诞生和演化,本身就是一部 Unix/Linux 系统管理哲学变迁的微缩史。来,让我们拨开时间的迷雾,一同探寻 sudo 那波澜壮阔(也颇为实用主义)的发展历程。 历史背景:su的时代与困境 ( 20 世纪 70 年代 - 80 年代初) 在 sudo 出现之前,Unix 系统管理员和需要特权操作的…...

安宝特案例丨Vuzix AR智能眼镜集成专业软件,助力卢森堡医院药房转型,赢得辉瑞创新奖
在Vuzix M400 AR智能眼镜的助力下,卢森堡罗伯特舒曼医院(the Robert Schuman Hospitals, HRS)凭借在无菌制剂生产流程中引入增强现实技术(AR)创新项目,荣获了2024年6月7日由卢森堡医院药剂师协会࿰…...

人机融合智能 | “人智交互”跨学科新领域
本文系统地提出基于“以人为中心AI(HCAI)”理念的人-人工智能交互(人智交互)这一跨学科新领域及框架,定义人智交互领域的理念、基本理论和关键问题、方法、开发流程和参与团队等,阐述提出人智交互新领域的意义。然后,提出人智交互研究的三种新范式取向以及它们的意义。最后,总结…...

macOS 终端智能代理检测
🧠 终端智能代理检测:自动判断是否需要设置代理访问 GitHub 在开发中,使用 GitHub 是非常常见的需求。但有时候我们会发现某些命令失败、插件无法更新,例如: fatal: unable to access https://github.com/ohmyzsh/oh…...
js 设置3秒后执行
如何在JavaScript中延迟3秒执行操作 在JavaScript中,要设置一个操作在指定延迟后(例如3秒)执行,可以使用 setTimeout 函数。setTimeout 是JavaScript的核心计时器方法,它接受两个参数: 要执行的函数&…...
stm32进入Infinite_Loop原因(因为有系统中断函数未自定义实现)
这是系统中断服务程序的默认处理汇编函数,如果我们没有定义实现某个中断函数,那么当stm32产生了该中断时,就会默认跑这里来了,所以我们打开了什么中断,一定要记得实现对应的系统中断函数,否则会进来一直循环…...
使用 uv 工具快速部署并管理 vLLM 推理环境
uv:现代 Python 项目管理的高效助手 uv:Rust 驱动的 Python 包管理新时代 在部署大语言模型(LLM)推理服务时,vLLM 是一个备受关注的方案,具备高吞吐、低延迟和对 OpenAI API 的良好兼容性。为了提高部署效…...