Freemarker快速入门(SpringBoot版)

文章目录

  • Freemarker快速入门
    • 1、Freemarker概述
    • 2、Freemarker初体验
    • 3、数据类型
      • 3.0 常见操作符
      • 3.1 数值类型
      • 3.2 字符串类型
      • 3.3 布尔类型
      • 3.4 日期类型
      • 3.5 序列类型
      • 3.6 哈希类型
    • 4、运算符
      • 4.1 算术运算符
      • 4.2 逻辑运算符
      • 4.3 比较运算符
      • 4.4 空值运算符
    • 5、常用指令
      • 5.1 assign 自定义变量指令
      • 5.2 if elseif else 逻辑判断指令
      • 5.3 list 遍历指令
      • 5.4 macro 自定义指令
      • 5.5 nested 占位指令
      • 5.6 import 导入指令
      • 5.7 include 包含指令

Freemarker快速入门

在这里插入图片描述

1、Freemarker概述

  • Freemarker是什么

    Freemarker是一个强大的 Java 模板引擎,它允许开发人员将展示层与应用逻辑分离。通过提供一种灵活高效的方式,在运行时生成动态内容。Freemarker模板使用类似HTML的语法,但包含可以在运行时填充数据的占位符和控制结构。这使得创建动态网页、电子邮件和其他文本文档非常简单。

    Freemarker支持条件语句、循环、宏等各种功能,并且可以与不同的数据模型和框架集成。它在Java Web开发中被广泛应用于生成HTML视图、电子邮件模板和其他文本输出。

    个人理解:Freemarker是类似于JSP的模板引擎,只要我们理解了什么是模板引擎就知道Freemarker大概是一个什么东西了

    PS:如果你学习过 JSP 或者 Thmeleaf,我相信你对模板引擎不会陌生,关于 JSP 和 Thmeleaf 的详细介绍可以参考这两篇文章:JSP速通、Thmeleaf快速入门(Spring整合版)

  • 什么是模板引擎

    模板引擎是一种用于生成动态内容的工具或框架。它将应用程序的逻辑和数据与视图分离,允许开发人员使用预定义的模板来定义页面、电子邮件、报表等的结构和布局。通过在模板中使用占位符、条件语句、循环等控制结构,模板引擎可以动态地将数据填充到模板中,生成最终的输出结果。这样的方法可以提高开发效率,减少代码重复,并使前后端工作更加分离。模板引擎通常支持多种语法和标记,可以集成到不同的编程语言和框架中,以满足各种应用场景的需求。

    个人理解:模板引擎就是一类特殊的HTML页面,它将数据和页面骨架(HTML)、样式(CSS)与数据进行了分离,数据是需要我们动态填充(模板引擎这个概念很类似与前端的组件,模板引擎是一种后端的页面渲染技术)

  • 模板引擎的作用是什么

    个人理解:模板引擎的主要作用是将逻辑和数据进行分离,提高复用性,相当于是给我们一个模板,我们只需要往这个模板中填充数据即可

    • 分离视图和业务逻辑:模板引擎使开发人员能够将视图(如网页、电子邮件等)的结构和布局与应用程序的业务逻辑分开。这样,设计师和前端开发人员可以专注于界面设计,而后端开发人员可以专注于业务逻辑的实现。
    • 提高开发效率:使用模板引擎可以减少编写重复代码的工作量。开发人员只需定义一次模板,并根据需要填充不同的数据即可生成多个相似但内容不同的输出结果。这样可以节省时间并提高开发效率。
    • 支持可维护性和扩展性:通过将视图和业务逻辑分离,模板引擎使代码更易于维护和修改。开发人员可以更轻松地修改UI布局或样式,而无需修改底层的业务逻辑。此外,模板引擎还提供了灵活的控制结构和标记,使开发人员可以根据需要进行定制和扩展。
    • 支持多平台和多语言:模板引擎通常支持多种编程语言和框架,可以适用于不同的开发环境和应用场景。这使得开发人员能够在不同的项目中重用他们的模板知识和经验。
  • 常见的模板引擎有哪些

    模板引擎说明
    JSPJsp 为 Servlet 专用,不能单独进行使用
    Thymeleaf新技术,功能较为强大,但是执行的效率比较低
    FreeMarker性能好,强大的模板语言、轻量
    VelocityVelocity从2010年更新完 2.0 版本后,7年没有更新。Spring Boot 官方在 1.4 版本后对此也不在支持
  • Freemarker的组成

    • 模板:模板是FreeMarker的核心组件,它定义了要生成的输出内容的结构和格式。模板使用FreeMarker的模板语法编写,可以包含变量、表达式、标签和指令等。

      模板的组成:

      • 文本:文本会照着原样来输出。
      • 插值:这部分的输出会被计算的值来替换。插值由 ${ and } 所分隔(或者 #{ and },这种风格已经不建议再使用了;点击查看更多)。
      • FTL 标签:FTL标签和HTML标签很相似,但是它们却是给FreeMarker的指示, 而且不会打印在输出内容中。
      • 注释:注释和HTML的注释也很相似,但它们是由 <#---->来分隔的。注释会被FreeMarker直接忽略, 更不会在输出内容中显示。
    • 模板解析器:模板解析器负责将模板文件解析为抽象语法树(AST),以便进行后续的处理和渲染。模板解析器将模板语法解析为相应的AST节点,表示模板的结构和内容。

    • 数据模型:数据模型是FreeMarker所使用的数据源,它包含了要在模板中展示的数据。数据模型可以是任意的Java对象,例如POJO、Map、List等。在模板中可以通过表达式访问数据模型的属性和方法。

    • 标签和指令:FreeMarker提供了一些内置的标签和指令,用于控制模板的渲染和逻辑处理。标签和指令可以包含条件判断、循环控制、变量赋值等逻辑,以及数据展示和格式化等操作。

    • 模板渲染引擎:模板渲染引擎是FreeMarker的核心引擎,负责将模板和数据结合起来进行渲染。模板渲染引擎根据AST节点和数据模型,生成最终的输出内容。

    除了上述组件之外,FreeMarker还提供了一些辅助类和工具,用于扩展和定制模板引擎的功能。例如,提供了各种自定义标签和函数的扩展点,以及模板缓存和预编译等性能优化功能。

2、Freemarker初体验

由于平常大部分都是基于SpringBoot框架进行开发的,这里我就不基于Spring学习Freemarker了,直接基于SpringBoot演示Freemarker的使用

创建SpringBoot项目
添加依赖
编写模板
编写配置文件
编写Controller
测试
  • Step1:创建SpringBoot项目

    image-20231017223637599

  • Step2:添加依赖

            <!--Freemarker--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-freemarker</artifactId></dependency><!--Web环境--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency>
    
  • Step3:编写模板

    src/main/resources/templates目录下创建 index.ftl 文件

    根据 Spring Boot 约定,模板文件默认是放在 src/main/resources/templates 目录下,如果你想要自定义模板文件的位置,可以通过template-loader-path配置属性进行设置。

    <!DOCTYPE html>
    <html><head><meta charset="UTF-8"><title>Freemarker</title></head><body>Hello ${title}!</body>
    </html>
    
  • Step4:编写配置文件

    spring:freemarker:suffix: .ftl # 模板文件的后缀名,默认为 .ftl
    #    content-type: text/html # 响应的文档类型,默认为 text/html
    #    charset: UTF-8 # 页面的编码,默认为 UTF-8cache: false # 是否启用页面缓存,默认为 true。如果设置为 false,则每次请求都会重新解析模板文件
    #    template-loader-path: classpath:/templates/ # 模板文件的路径,默认为 classpath:/templates/。可以根据实际情况进行配置
    

    注意:suffix虽然有默认值 .ftl,但是仍然需要手动配置,否则无法成功响应模板

  • Step5:编写Controller

    package com.ghp.freemarker.controller;import org.springframework.stereotype.Controller;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.servlet.ModelAndView;/*** @author ghp* @title* @description*/
    @Controller
    @RequestMapping("/page")
    public class PageController {@GetMapping("/index1")public String toIndex1(){return "index1";}@GetMapping("/index2")public ModelAndView toIndex2 () {ModelAndView modelAndView = new ModelAndView("index2");modelAndView.addObject("title", "Freemarker");return modelAndView;}
    }
    

    注意:不要使用@RestController注解表示响应模板视图的 Controller 类,因为使用@RestController注解会将 Controller 类标识为一个 RESTful API 控制器,它主要用于返回数据或处理 API 请求,并不会返回视图页面

  • Step5:测试

    现在可以在浏览器上分别访问 http://localhost:8080/page/index1 和 http://localhost:8080/page/index2

    image-20231017223447188

3、数据类型

Freemarker是一个模板引擎,它主要用于生成动态的文本输出。它并没有特定的数据类型,而是使用 Java 对象作为模板的数据模型,所以这里的数据类型本质还是 Java 中的数据类型,本节主要讲解 Freemarker 中如何操作不同的数据类型

3.0 常见操作符

操作符描述
?c格式化对象
?string将对象转成字符串
?string.currency将对象转成货币类型的字符串
?string.percent将对象转成百分比类型的字符串
?string["0.#"]将数字转成字符串,并四舍五入保留一位小数
?time将日期按照“时:分:秒”输出
?date将日期按照“年-月-日”输出
?datetime将日期按照“年-月-日 时:分:秒”输出
?html对字字符串进行转移输出
?esc对字字符串进行转移输出
?reverse反转结果
?sort排序
?index获取当前遍历元素的索引
?sort_by按照某一个字段进行排序

3.1 数值类型

  • 设置值
  • 获取值

3.2 字符串类型

  • 设置值
  • 获取值

3.3 布尔类型

  • 设置值
  • 获取值

3.4 日期类型

  • 设置值
  • 获取值

3.5 序列类型

  • 设置值
  • 获取值

3.6 哈希类型

  • 设置值
  • 获取值

这里就统一编写吧,不一个一个的CV了,太浪费时间了,直接来一个整的

    /*** 演示 Freemarker 中不同的数据类型的相关操作** @return*/@GetMapping("/data_type")public ModelAndView toDataType() {// 响应的模板ModelAndView modelAndView = new ModelAndView("data_type");// 响应数值类型的数据modelAndView.addObject("number", 666);// 响应字符串类型的数据modelAndView.addObject("string", "Freemarker");// 响应布尔类型的数据modelAndView.addObject("boolean", true);// 响应日期类型的数据modelAndView.addObject("date", new Date());// 响应序列类型的数据(数组、List、Set)modelAndView.addObject("sequence", Arrays.asList("张三", "李四", "王五"));// 响应哈希类型的数据modelAndView.addObject("hash", new HashMap<String, String>(3) {{put("a", "A");put("b", "B");put("c", "C");}});// 还可以直接使用 addAllObjects 一次性全部添加modelAndView.addAllObjects(new HashMap<String, Object>(6) {{put("number2", 3.1415926);put("string2", "Freemarker");put("boolean2", false);put("date2", new Date());put("sequence2", new String[]{"张三", "李四", "王五"});put("hash2", new HashMap<String, String>(3) {{put("a", "A");put("b", "B");put("c", "C");}});User user1 = new User(1L, "张三", 19);User user2 = new User(2L, "李四", 20);User user3 = new User(3L, "李四", 21);ArrayList<User> userList = new ArrayList<>(3);Collections.addAll(userList, user1, user2, user3);put("userList", userList);Map<String, User> userMap = new HashMap<>(3);userMap.put("key1", user1);userMap.put("key2", user2);userMap.put("key3", user3);put("userMap", userMap);}});return modelAndView;}

image-20231018225602446

4、运算符

4.1 算术运算符

<!--算术运算+、-、*、/、%
-->
<#assign a1 = 8 a2 = 2 >
${a1} + ${a2} = ${a1 + a2} <br/>
${a1} - ${a2} = ${a1 - a2} <br/>
${a1} * ${a2} = ${a1 * a2} <br/>
${a1} / ${a2} = ${a1 / a2} <br/>
${a1} % ${a2} = ${a1 % a2} <br/>
<!--字符串运算-->
${"hello" + "," + "freemarker"}

4.2 逻辑运算符

<#--逻辑运算符&&、||、!
-->

4.3 比较运算符

<#--比较运算符> (gt): 大于号,推荐使用 gt< (lt): 小于号,推荐使用 lt>= (gte): 大于等于, 推荐是用 gte<= (lte): 小于等于,推荐使用 lte== : 等于!= : 不等于
-->

4.4 空值运算符

<#--空值运算符1. ??:判断是否为空,返回布尔类型如果不为空返回 false, 如果为空返回 true,不能直接输出${(name??)?string}2. !: 设置默认值,如果为空,则设置默认值1. 设置默认为空字符串:${name!}2. 设置指定默认值${name!'zhangsan'}
-->

5、常用指令

5.1 assign 自定义变量指令

使用 assign 指令你可以创建一个新的变量, 或者替换一个已经存在的变量。

<#--assign 自定义变量指令语法:<#assign 变量名=><#assign 变量名= 变量名=> (定义多个变量)
-->
<#assign str="hello">
${str} <br> 
<#assign num=1 names=["zhangsan","lisi","wangwu"] >
${num} -- ${names?join(",")}

5.2 if elseif else 逻辑判断指令

可以使用 if , elseif 和 else 指令来条件判断是否满足某些条件。

<h5> 2. if, else, elseif 逻辑判断指令</h5>
<#assign score = 60>
<#if score lt 60 ><h6>你个小渣渣!</h6><#elseif score == 80><h6>分不在高,及格就行!</h6><#elseif score gt 60 && score lt 80 ><h6>革命尚未成功,同志仍需努力!</h6><#else ><h6>哎哟不错哦!</h6>
</#if>
<#--判断数据是否存在-->
<#assign list="">
<#if list??>数据存在<#else >数据不存在
</#if>
<br>
<#if list2??>数据存在
<#else >数据不存在
</#if>

5.3 list 遍历指令

可以使用 list 指令来对序列进行遍历。

<h5>3. list指令</h5>
<#assign users = ["张三","李四","王五"]>
<#list users as user>${user} |
</#list>
<br>
<#--判断数据不为空,再执行遍历 (如果序列不存在,直接遍历会报错)-->
<#if users2??><#list users2 as user>${user}</#list>
</#if>
<br>
<#-- 当序列没有数据项时,使用默认信息 -->
<#assign users3 = []>
<#list users3 as user>${user} |<#else >用户数据不存在!
</#list>

5.4 macro 自定义指令

可以使用 macro 指令来自定义一些自定义指令。

<#--macro 自定义指令 (宏)1. 基本使用格式:<#macro 指令名>指令内容</#macro>使用:<@指令名></@指令名>2. 有参数的自定义指令格式:<#macro 指令名 参数名1 参数名2>指令内容</#macro>使用:<@指令名 参数名1=参数值1 参数名2=参数值2></@指令名>注:1. 指令可以被多次使用。2. 自定义指令中可以包含字符串,也可包含内置指令
-->
<#-- 定义基本的自定义指令 -->
<#macro address>© 1999–2015 The FreeMarker Project. All rights reserved. 
</#macro> 
<#-- 使用指令 -->
<@address></@address> <br> 
<@address></@address> <hr> 
<#-- 定义有参数的自定义指令 -->
<#macro queryUserByName uname>通过用户名查询用户信息 - ${uname} 
</#macro> 
<#-- 使用指令,并传递参数 -->
<@queryUserByName uname="admin"></@queryUserByName> <br> 
<#-- 定义有多个参数的自定义指令 -->
<#macro queryUserByParams uname uage>通过多个餐宿查询用户信息 - ${uname} - ${uage} </#macro> 
<#-- 使用指令,并传递多个参数 -->
<@queryUserByParams uname="admin" uage=18></@queryUserByParams> <br> 
<hr>
<#-- 自定义指令中包含内置指令 -->
<#macro cfb><#list 1..9 as i><#list 1..i as j>${j}*${i}=${j*i}&nbsp;</#list><br></#list> 
</#macro> 
<@cfb></@cfb> 
<@cfb></@cfb> 
<#-- 动态数据 -->
<#macro cfb2 num><#list 1..num as i><#list 1..i as j>${j}*${i}=${j*i}&nbsp;</#list><br></#list> 
</#macro> 
<@cfb2 num=5></@cfb2>

5.5 nested 占位指令

nested 指令执行自定义指令开始和结束标签中间的模板片段。嵌套的片段可以包含模板中任意合法的内容。

<#--nested 占位指令nested 相当于占位符,一般结合macro指令一起使用。可以将自定义指令中的内容通过nested指令占位,当使用自定义指令时,会将占位内容显示。
-->
<#macro test>这是一段文本!<#nested><#nested> 
</#macro> 
<@test><h4>这是文本后面的内容!</h4></@test>

5.6 import 导入指令

import 指令可以引入一个库。也就是说,它创建一个新的命名空间, 然后在那个命名空间中执行给定路径的模

板。可以使用引入的空间中的指令。

1)创建commons.ftl文件

<#macro cfb><#list 1..9 as i><#list 1..i as j>${j}*${i}=${j*i}&nbsp;</#list><br></#list> 
</#macro>

在其他ftl页面中通过import导入commons.ftl的命名空间,使用该命名空间中的指令

2)创建test.ftl文件

<#-- 导入命名空间 -->
<#import "commons.ftl" as common> 
<#-- 使用命名空间中的指令 -->
<@common.cfb></@common.cfb>

3)创建Controller

package org.example.controller;import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;/*** @author liyonghui* @description Freemarker常用指令* @date 2022/12/20 14:05*/
@WebServlet("/f04")
public class FreeMarker04 extends HttpServlet {@Overrideprotected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {//        请求转发到指定的页面,req.getRequestDispatcher("template/test.ftl").forward(req, resp);}
}

5.7 include 包含指令

可以使用 include 指令在你的模板中插入另外一个 FreeMarker 模板文件 。 被包含模板的输出格式是在 include

标签出现的位置插入的。 被包含的文件和包含它的模板共享变量,就像是被复制粘贴进去的一样。

<#--包含指令(引入其他页面文件) include-->
<#--html文件-->
<#include "test.html"> 
<#--freemarker文件-->
<#include "test.ftl"> 
<#--text文件-->
<#include "test.txt">

参考资料

  • 什么是 FreeMarker? - FreeMarker 中文官方参考手册 (foofun.cn)
  • Freemarker笔记.md · liyonghui/Freemarker_readme - Gitee.com
  • Spring Boot 整合 Freemarker 模板引擎 - spring 中文网 (springdoc.cn)

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

热门影视APP系统源码 可二开 后端+app+搭建教程

影视APP源码绿豆二开版 后端app搭建教程都在压缩包里&#xff0c;搭建步骤和绿豆一样 安装宝塔 yum install -y wget && wget -O install.sh http://download.bt.cn/install/install_6.0.sh && sh install.sh 安装环境 Nginx 1.20.2 MySQL5.6-5.7 php7.0-7.…

使用 VS Code 作为 VC++ 6.0 的编辑器

使用 VS Code 作为 VC 6.0 的编辑器 由于一些众所周知的原因&#xff0c;我们不得不使用经典&#xff08;过时&#xff09;的比我们年龄还大的已有 25 年历史的 VC 6.0 来学习 C 语言。而对于现在来说&#xff0c;这个经典的 IDE 过于简陋&#xff0c;并且早已不兼容新的操作系…

tomcat、nginx实现四层转发+七层代理+动静分离实验

实验环境&#xff1a; nginx1——20.0.0.11——客户端 静态页面&#xff1a; nginx2——20.0.0.21——代理服务器1 nginx3——20.0.0.31——代理服务器2 动态页面&#xff1a; tomcat1——20.0.0.12——后端服务器1 tomcat2——20.0.0.22——后端服务器2 实验步骤&…

基于LSTM-Adaboost的电力负荷预测(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

基于SSM的仓库管理系统设计与实现

末尾获取源码 开发语言&#xff1a;Java Java开发工具&#xff1a;JDK1.8 后端框架&#xff1a;SSM 前端&#xff1a;采用JSP技术开发 数据库&#xff1a;MySQL5.7和Navicat管理工具结合 服务器&#xff1a;Tomcat8.5 开发软件&#xff1a;IDEA / Eclipse 是否Maven项目&#x…

什么是模拟芯片,模拟芯片都有哪些测试指标?

模拟芯片又称处理模拟信号的集成电路 模拟集成电路主要是指由电容、电阻、晶体管等组成的模拟电路集成在一起用来处理模拟信号的集成电路。有许多的模拟集成电路&#xff0c;如运算放大器、模拟乘法器、锁相环、电源管理芯片等。 模拟集成电路的主要构成电路有&#xff1a;放…

代理模式(初学)

代理模式 一、什么是代理模式 代理模式&#xff1a;为其他对象提供一种代理以控制对这个对象的访问 二、简单例子 这里面的骏骏就起到了代理的身份&#xff0c;而贵贵则是被代理的身份。 三、代码实现 1、用一个接口&#xff08;GivingGifts&#xff09;来保存送礼物的动作…

一些bug总结

今天被几个小问题和bug折磨了一天&#xff0c;来总结一下… 权限问题 用vscode连接服务器&#xff0c;如果是在root用户连接的情况下新建的文件/文件夹&#xff0c;然后切换到别的用户的时候去写的代码 可能会遇到各种问题 解决方案是更改文件或文件夹的所有权。这可以通过使用…

win11 搭建Apache webdav 设置用户名密码 加密授权访问以及多个不同目录访问

Apache webdav 的搭建应该比较简单,但是搭建后还遇到了一些问题,也就是设置了访问用户名密码,咋就不生效呢,苦苦思索两日,终于发现了问题,本文就是分两个方面来编写 一、搭建 1.下载Apache 官网下载: https://www.apachehaus.com/cgi-bin/download.plx 2.下载后解压…

spring 资源操作:Resources

文章目录 Spring Resources概述Resource接口Resource的实现类UrlResource访问网络资源ClassPathResource 访问类路径下资源FileSystemResource 访问文件系统资源ServletContextResourceInputStreamResourceByteArrayResource Resource类图ResourceLoader 接口ResourceLoader 概…

6.DApp-用Web3实现前端与智能合约的交互

题记 用Web3实现前端与智能合约的交互&#xff0c;以下是操作流程和代码。 准备ganache环境 文章地址&#xff1a;4.DApp-MetaMask怎么连接本地Ganache-CSDN博客 准备智能合约 文章地址&#xff1a; 2.DApp-编写和运行solidity智能合约-CSDN博客 编写index.html文件 <!…

kubernetes

概述 K8S 是什么? K8S 的全称为 Kubernetes (K12345678S)&#xff0c;PS:“嘛&#xff0c;写全称也太累了吧&#xff0c;写”。不如整个缩 由来: K8S由coogle的Borg系统(博格系统&#xff0c;google内部使用的大规模容器编排工具)作为原型&#xff0c;后经GO语言延用Borg的…

python特别篇—github基本操作手册

一、开始使用 1.1 “Hello world” 1.1.1 github介绍 GitHub是一个基于Git版本控制系统的代码托管平台。它提供了一个在线的代码仓库&#xff0c;使开发者可以将自己的代码存储在云端&#xff0c;并与其他开发者进行协作。GitHub不仅仅是一个代码托管平台&#xff0c;还提供了…

【MultiOTP】在Linux上使用MultiOTP进行SSH登录

在前面的文章中【FreeRADIUS】使用FreeRADIUS进行SSH身份验证已经了解过如何通过Radius去来实现SSH和SUDO的登录&#xff0c;在接下来的文章中只是将密码从【LDAP PASSWORD Googlt OTP】改成了【MultiOTP】生成的passcode&#xff0c;不在需要密码&#xff0c;只需要OTP去登录…

MinIO (二) .net core中实现上传下载

这篇文章里&#xff0c;我们介绍在.net core webapi项目中操作MinIO。 首先要创建一个桶&#xff0c;命名为demo 英文文档看不太顺畅&#xff0c;在网上找了一个api中文文档&#xff0c;可供参考 .NET Client API参考文档 - MinIO 帮助文档 - 开发文档 - 文江博客 创建桶 点…

Java 操作 Excel:生成数据、设置单元格样式、设置数据有效性(hutool)

必读信息 该篇文章&#xff0c;主要通过 Java 代码对 Excel 文件的常用操作&#xff0c;包括&#xff1a;生成表格、修改单元格样式、设置数据有效性。 该篇文章&#xff0c;在官网文献下增加个人的看法和理解&#xff0c;如文中有出现不符、错误或需要补充的地方&#xff0c…

计算机算法分析与设计(13)---贪心算法(多机调度问题)

文章目录 一、问题概述1.1 思路分析1.2 实例分析 二、代码编写 一、问题概述 1.1 思路分析 1. 设有 n n n 个独立的作业 1 , 2 , … , n {1, 2, …, n} 1,2,…,n&#xff0c;由 m m m 台相同的机器 M 1 , M 2 , … , M m {M_1, M_2, …, M_m} M1​,M2​,…,Mm​ 进行加工处…

一文带你GO语言入门

什么是go语言? Go语言(又称Golang)是Google开发的一种静态强类型、编译型、并发型,并具有垃圾回收功能的编程语言。Go语言的主要特点包括:- 简洁和简单 - 语法简单明快,易于学习和使用 特点 高效 编译速度快,执行效率高 并发支持 原生支持并发,利用goroutine实现高效的并发…

AP5101C 高压线性恒流 LED电源驱动IC 3D打印机显示灯驱动器

1&#xff0c;产品描述 AP5101C 是一款高压线性 LED 恒流芯片 &#xff0c; 简单 、 内置功率管 &#xff0c; 适用于6- 100V 输入的高精度降压 LED 恒流驱动芯片。电流2.0A。AP5101C 可实现内置MOS 做 2.0A,外置 MOS 可做 3.0A 的。AP5101C 内置温度保护功能 &#xff0c;温度…

【C++】多态 -- 详解

⚪前言 声明一下&#xff0c;下面的代码和解释都是在 VS2019 下的 X86 程序中进行的&#xff0c;涉及的指针都是 4 bytes。如果要其他平台下&#xff0c;部分代码需要改动。比如&#xff1a;如果是 X64 程序&#xff0c;则需要考虑指针是 8 bytes 问题等等。其它编译环境下&…