SpringMVC-RESTful架构风格
目录
RESTful架构风格
1、RESTful概述
2、RESTful的六大原则
3、RESTful的实现
4、HiddenHttpMethodFilter
RESTful风格的CRUD
1、环境搭建
2、功能需求
3、功能:访问首页
4、功能:查询所有数据
5、功能:删除一条数据
6、功能:添加一条数据
SpringMVC处理静态资源
1、tomcat自己的web.xml
2、关于DefaultServlet
RESTful架构风格
1、RESTful概述
什么是REST
REST:
RepresentationalStateTransfer,表述层资源状态转移。(表现层:视图+控制器)它是在2000年,由Http协议的主要编写者Roy Fielding提出的,他觉得所有人都在胡乱使用Http,违背了他的设计思想。他就站出来,规定了一个web应用的,功能强、性能好、适宜通信的架构。这就是REST,
它指的是一组架构约束条件和原则。如果一个架构符合REST的约束条件和原则,我们就称它为
RESTful架构风格。REST本身并没有创造新的技术、组件或服务,简单来说,REST的目的就是设立规定,
促使人们更好地使用Http协议。理论上REST架构风格并不是绑定在HTTP上,只不过目前HTTP是唯一与REST相关的实例。不遵守REST规范,也能编写出web应用,这就类似于不使用设计模式也能开发程序一样。但基本都在使用。
资源
项目最终会部署到服务器上,被访问。
服务器中,万物皆资源。每个资源都是服务器上的一个可命名的抽象概念。
与面向对象的设计理念类似,
资源是以名词为核心来组织的,而不是方法。资源可以是一个文件,一张数据库表,或是更抽象的概念,比如一个视图,一个参数之类。
一个资源可以由一个或多个URI来标识。
URI
URI既是资源的名称,也是资源在web上的地址。客户端通过URI与资源进行交互。
REST 是面向资源的,这个概念非常重要,而资源是通过 URI 进行暴露。URI 的设计只要负责把资源通过合理方式暴露出来就可以了。对资源的操作与它无关,操作是通过 HTTP动词来体现,所以REST 通过 URI 暴露资源时,会强调不要在 URI 中出现动词。
资源的状态表述
资源的表述,指某个资源在某个特定时刻的状态的描述。这种状态,可以在客户端-服务器之间交换。
资源的表述可以有多种格式,例如HTML、XML、JSON、纯文本、图片、音视频等。
统一资源在请求-响应方向的表述,通常使用不同的格式
资源状态表述的转移
状态转移,指在客户端-服务器端之间转移 资源状态的表述。
通过转义和操作资源的表述,来实现间接操作资源的目的。
2、RESTful的六大原则
Roy Fielding在提出RESTful时,也阐述了REST架构的6大原则。他希望所有web应用都符合这六个特征,相当于是web应用的设计原则
如果某个服务违反了其他任意一项准则,严格意义上不能称之为RESTful风格。
1、C-S架构
数据的存储在Server端,Client端只需使用就行。两端彻底分离的好处使client端代码的可移植性变强,Server端的拓展性变强。两端单独开发,互不干扰。
2、无状态
http请求本身就是无状态的,基于C-S架构,客户端的每一次请求都必须带有充分的信息,才能够让服务端识别。
服务端能够根据请求的各种参数,无需保存客户端的状态,将响应正确返回给客户端。
无状态的好处:无状态的特征大大提高的服务端的健壮性和可拓展性。
无状态的坏处:每次请求必须携带身份状态信息,造成传输数据的冗余。但影响很细微,可以忽略
3、统一资源接口
这个才是REST架构的核心,统一的接口对于RESTful服务非常重要。客户端只需要关注实现接口就可以,接口的可读性加强,使用人员方便调用。
4、一致的数据格式
5、系统分层
客户端通常无法表明自己是直接还是间接与端服务器进行连接,分层时同样要考虑安全策略。
6、可缓存
管理得当的缓存会部分地或完全地除去客户端和服务端之间的交互,进一步改善性能和延展性。
3、RESTful的实现
REST 风格提倡 URL 地址使用统一的风格设计,从前到后各个单词使用斜杠分开,不使用问号键值对方式携带请求参数,而是将要发送给服务器的数据作为 URL 地址的一部分,以保证整体风格的一致性。
具体说,就是 HTTP 协议里面,四个表示操作方式的动词:GET、POST、PUT、DELETE。 它们分别对应四种基本操作:GET 用来获取资源,POST 用来新建资源,PUT 用来更新资源,DELETE 用来删除资源。
| 操作 | 传统方式 | REST风格 |
|---|---|---|
| 查询操作 | getUserById?id=1 | user/1 --> get请求方式 |
| 保存操作 | saveUser | user --> post请求方式 |
| 删除操作 | deleteUser?id=1 | user/1 --> delete请求方式 |
| 更新操作 | updateUser | user --> put请求方式 |
4、HiddenHttpMethodFilter
由于浏览器只支持发送get和post方式的请求,那么该如何发送put和delete请求呢?
SpringMVC 提供了 HiddenHttpMethodFilter 帮助我们
将 POST 请求转换为 DELETE 或 PUT 请求
HiddenHttpMethodFilter如何使用?
HiddenHttpMethodFilter 处理put和delete请求的条件:
- 当前请求的
请求方式必须为post- 当前请求
必须传输请求参数_method满足以上条件,HiddenHttpMethodFilter 过滤器就会将当前请求的请求方式转换为请求参数_method的值,因此
请求参数_method的值才是最终的请求方式
在web.xml中注册HiddenHttpMethodFilter
<filter><filter-name>HiddenHttpMethodFilter</filter-name><filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>
</filter>
<filter-mapping><filter-name>HiddenHttpMethodFilter</filter-name><url-pattern>/*</url-pattern>
</filter-mapping>
注意,在web.xml中注册时,必须先注册CharacterEncodingFilter,再注册HiddenHttpMethodFilter
即先注册字符编码过滤器,再注册Http隐藏方法过滤器
HiddenHttpMethodFilter需要获取请求方式,也属于请求参数,那就必须在设置好字符编码之后再去获取。
在前端页面中,使用隐藏域传递请求参数_method
<form th:action="@{/user}" method="post">修改用户信息<input type="hidden" name="_method" value="put"/>用户名:<input type="test" name="username"/>密码:<input type="password" name="password"/><input type="submit" value="提交">
</form><br>
此时,点击提交按钮,发出的就是一个put类型的请求
RESTful风格的CRUD
1、环境搭建
创建实体类
public class Employee {private Integer id;private String lastName;private String email;//1 male, 0 femaleprivate Integer gender;...
}
创建DAO,使用map集合模拟数据库资源
@Repository
public class EmployeeDAO {private static Map<Integer, Employee> employees = null;static {employees = new HashMap<Integer, Employee>();employees.put(1001, new Employee(1001, "E-AA", "aa@163.com", 1));employees.put(1002, new Employee(1002, "E-BB", "bb@163.com", 1));employees.put(1003, new Employee(1003, "E-CC", "cc@163.com", 0));employees.put(1004, new Employee(1004, "E-DD", "dd@163.com", 0));employees.put(1005, new Employee(1005, "E-EE", "ee@163.com", 1));}private static Integer initId = 1006;public void save(Employee employee) {if (employee.getId() == null) {employee.setId(initId++);}employees.put(employee.getId(), employee);}public Collection<Employee> getAll() {return employees.values();}public Employee get(Integer id) {return employees.get(id);}public void delete(Integer id) {employees.remove(id);}
}
@Repository 持久层组件标记
创建Controlle
public class EmployeeController {private EmployeeDAO employeeDAO;}
创建私有成员变量DAO,后续使用依赖注入
2、功能需求
| 功能 | URL 地址 | 请求方式 |
|---|---|---|
| 访问首页 | / | GET |
| 查询全部数据 | /employee | GET |
| 删除 | /employee/2 | DELETE |
| 跳转到添加数据页面 | /toAdd | GET |
| 执行保存 | /employee | POST |
| 跳转到更新数据页面 | /employee/2 | GET |
| 执行更新 | /employee | PUT |
使用RESTful风格,对相同资源的不同操作,请求地址相同,不同请求方式对应不同的操作。
3、功能:访问首页
由于只是页面跳转的功能,可以使用view-controller标签配置。
<mvc:view-controller path="/" view-name="index"/><mvc:annotation-driven />
首页的前端页面
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org"><head><meta charset="UTF-8"><title>Title</title></head><body><h3>RESTful风格的员工CRUD系统</h3><a th:href="@{/employee}">查看所有员工信息</a></body>
</html>
4、功能:查询所有数据
分析
不使用ajax异步访问,就只能先获取数据,再转发到其他页面来展示。
传参流程
首页点击超链接,被Spring前端控制器拦截,匹配到控制器方法;
控制器方法中,执行DAO的相应方法,将结果存入request域对象中,并转发到结果页面;
结果页面上,使用视图模板引擎获取域对象中的相关数据,并展示。
控制器方法
@GetMapping("/employee")
public String getEmployeeList(Model model){Collection<Employee> employeeList = employeeDAO.getAll();model.addAttribute("employeeList", employeeList);return "employee_list";
}
前端页面
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org"><head><meta charset="UTF-8"><title>员工信息</title></head><body><table border="1" cellspacing="0" cellpadding="0" style="text-align: center"><tr><th colspan="5">全部员工信息</th></tr><tr><th>id</th><th>lastName</th><th>email</th><th>gender</th><th>options</th></tr><tr th:each="employee : ${employeeList}"><td th:text="${employee.id}"></td><td th:text="${employee.lastName}"></td><td th:text="${employee.email}"></td><td th:text="${employee.gender}"></td><td><a href="">Delete</a><a href="">Update</a></td></tr></table></body>
</html>
效果

5、功能:删除一条数据
分析
删除操作,需要使用DELETE请求方式,则需要在Delete超链接上,绑定一个post表单的提交事件,该表单使用隐藏域,设置_method为DELETE
点击删除超链接,需要传递该行的员工id,
动态获取数据并拼接。拼接有两种方法:
<!--方法一--><a th:href="@{/employee/}+${employee.id}">Delete</a><!--方法二--><a th:href="@{'/employee/'+${employee.id}}">Delete</a>
步骤
- 创建发送delete请求方式的form表单
- 给delete超链接绑定事件
- 引入vue.js
- 给delete超链接绑定单击事件
- 通过vue处理单击事件
- 编写控制器方法,获取前端请求携带的id信息,调用DAO,根据id删除该数据
创建发送delete请求方式的form表单
<form id="deleteForm" method="post"><input type="hidden" name="_method" value="delete"/>
</form>
引入vue.js
<script type="text/javascript" th:src="@{/static/js/vue.js}"></script>
需要在webapp下创建static/js目录,放入vue.js
给delete超链接绑定单击事件
<a @click="deleteEmployee" th:href="@{'/employee/'+${employee.id}}">Delete</a>
这里做了两件事情:
- 给超链接绑定了单击事件,方法名称为deleteEmployee
- 拼接了请求路径,用RESTful风格传参,请求路径包含该行的id值
通过vue处理单击事件
<script type="text/javascript">var vue = new Vue({el:"#dataTable",methods:{deleteEmployee:function (event){//获取deleteForm这个表单元素var deleteForm = document.getElementById("deleteForm");//获取当前触发事件的href属性,即employee/1001deleteForm.action = event.target.href;//提交表单deleteForm.submit();//取消默认行为,阻止submit跳转页面event.preventDefault();}}});
</script>
注意
如果不做配置,vue.js无法被获取到,单击事件也就不起作用。
因为
SpringMVC默认无法访问静态资源。vue.js会被前端控制器 / 拦截到,显然没有它对应的控制器方法,返回了404需要在SpringMVC配置文件中,引入
默认的servlet,开放对静态资源的访问<mvc:default-servlet-handler/>静态资源在访问时,会先被前端控制器进行处理,如果前端控制器找不到对应的请求映射,就会交给默认的servlet来处理。如果默认的servlet找到了相对应的资源,就访问资源。如果找不到,就返回404。
控制器方法
@DeleteMapping("/employee/{id}")
public String delEmployee(@PathVariable Integer id){employeeDAO.delete(id);return "redirect:/employee";
}
6、功能:添加一条数据
在前端页面,设置添加员工的入口
<th>options(<a th:href="@{/toAdd}">添加员工</a>)</th>
效果

点击“添加员工”,跳转到添加员工的页面。用view-controller实现
<mvc:view-controller path="/toAdd" view-name="employee_add"/>
编写添加页面
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org"><head><meta charset="UTF-8"><title>添加员工信息</title></head><body><form th:action="@{/employee}" method="post">lastName:<input type="text" name="lastName"/><br>email:<input type="text" name="email"/><br>gender:<input type="radio" name="gender" value="1"/>男<input type="radio" name="gender" value="0"/>女<br><input type="submit" value="提交"/><input type="reset" value="重置"/></form></body>
</html>
样式

控制器方法
@GetMapping("/employee/{id}")
public String getEmployeeById(@PathVariable Integer id, Model model){//根据id获取员工对象Employee employee = employeeDAO.get(id);//将员工对象存入request域中,用于数据回显model.addAttribute("employee", employee);return "employee_update";
}@PutMapping("/employee")
public String updateEmployee(Employee employee){employeeDAO.save(employee);return "redirect:/employee";
}
修改的前端页面
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org"><head><meta charset="UTF-8"><title>更新员工数据</title></head><body><form th:action="@{/employee}" method="post"><input type="hidden" name="_method" value="put"/><input type="hidden" name="id" th:value="${employee.id}"/>lastName:<input type="text" name="lastName" th:value="${employee.lastName}"/><br>email:<input type="text" name="email" th:value="${employee.lastName}"/><br>gender:<input type="radio" name="gender" value="1" th:field="${employee.gender}"/>男<input type="radio" name="gender" value="0" th:field="${employee.gender}"/>女<br><input type="submit" value="提交"/><input type="reset" value="重置"/></form></body>
</html>
- 注意这里实现勾选框 回显的方式
th:field="${employee.gender}"可用于单选框或复选框的回显
若单选框的value和employee.gender的值一致,则添加checked="checked"属性
2. 注意,需要使用隐藏域传递id,达到覆盖原有数据的目的
SpringMVC处理静态资源
传统的web项目中,负责处理静态资源的是“默认的Servlet”
1、tomcat自己的web.xml
存放位置
tomcat目录下的conf目录内。
tomcat的web.xml,和工程中web.xml的关系
tomcat的web.xml文件,是全局配置,作用于部署在tomcat的所有web应用。
web应用中的web.xml,只针对于自身。
如果当前应用内的web.xml配置,与tomcat的web.xml配置产生了冲突,则以web应用的配置为准。
2、关于DefaultServlet
tomcat的web.xml中,注册了DefaultServlet
<servlet><servlet-name>default</servlet-name><servlet-class>org.apache.catalina.servlets.DefaultServlet</servlet-class><init-param><param-name>debug</param-name><param-value>0</param-value></init-param><init-param><param-name>listings</param-name><param-value>false</param-value></init-param><load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping><servlet-name>default</servlet-name><url-pattern>/</url-pattern>
</servlet-mapping>
DefaultServlet的url-pattern是 / 说明访问所有资源(除了jsp)时,都会进入DefaultServlet。
在SpringMVC中,DefaultServlet和DispacherServlet产生了冲突。冲突时,以当前工程中的配置为准,也就是DispacherServlet。
就是说,所有的请求都会被DispacherServlet处理。
但DispacherServlet处理请求的方式是,将请求地址与控制器方法的映射路径匹配,直到找到相对应的请求映射。但这种方式无法访问静态资源。例如需要访问vue.js资源,而此路径并没有相对应的控制器方法,所以会报404,找不到该资源。
而DefaultServlet可以找到vue.js这个请求的资源。
所以SpringMVC默认不能访问静态资源,必须手动开启对静态资源的访问,在核心配置中进行如下的配置:
<!--开启对静态资源的访问-->
<mvc:default-servlet-handler/>
但此时,所有的请求都将被DefaultServlet处理,则只能访问到静态资源,请求映射将全部失效。
所以,还需要配置开启注解驱动的标签:
<!--开启mvc注解驱动-->
<mvc:annotation-driven>
同时配置这两个标签,就能实现,
请求先被DispacherServlet处理,如果找不到,再被DefaultServlet处理。
关于控制台信息
如果不添加日志功能,只有DispacherServlet的处理结果会被输出,而DefaultServlet的结果不会显示。
相关文章:
SpringMVC-RESTful架构风格
目录 RESTful架构风格 1、RESTful概述 2、RESTful的六大原则 3、RESTful的实现 4、HiddenHttpMethodFilter RESTful风格的CRUD 1、环境搭建 2、功能需求 3、功能:访问首页 4、功能:查询所有数据 5、功能:删除一条数据 6、功能&…...
consistency-starter
使用说明 建议在B端使用,不推荐C端使用 功能 事务提交之后推送MQ a. 当一个程序中有多个MQ需要推送时,可以在事务内任意位置调用发送MQ方法,而不会因为程序报错而导致数据不一致问题.事务提交之后发起子线程执行异步任务程序中灵活指定时间执行子任务 a. 例如:业务要求执行A业…...
【Json】Spring Boot整合Json与Json数组
Spring Boot整合Json与Json数组 文章目录 Spring Boot整合Json与Json数组一,引入依赖二,常见Json数据格式-2.1 Json格式-2.2 数组格式-2.3 Json数组格式 三,在Java中如何使用-3.1 Json格式-3.2 数组格式-3.3 Json数组格式 四,Json…...
Adobe Photoshop 软件下载
Adobe Photoshop,简称“PS”,是由Adobe Systems开发和发行的图像处理软件。Photoshop主要处理以像素所构成的数字图像。 时至今日,Adobe Photoshop 已经成为当今世界上最流行、应用最广泛的图像处理软件。不但设计专业的学生要系统的学习这个…...
[ES6]解构与赋值
[ES6]解构与赋值 解构模型对象属性解构函数参数解构字符串的解构数组解构REST 运算符参与的解构--...数组解构属性解构 解构的赋值 解构赋值是对赋值运算符的扩展。 通过解构,可以更加简单的获取复杂对象的属性 解构模型 解构的源,解构赋值表达式的右…...
2023年3月 青少年软件编程(C语言) 等级考试试卷(五级)
1. 拼点游戏 C和S两位同学一起玩拼点游戏。有一堆白色卡牌和一堆蓝色卡牌,每张卡牌上写了一个整数点数。C随机抽取n张白色卡牌,S随机抽取n张蓝色卡牌,他们进行n回合拼点,每次两人各出一张卡牌,点数大者获得三颗巧克力&…...
Unity之ShaderGraph入门
前言 随着Unity版本的不断升级,URP(可编程渲染管线)也越来越普及了。不管是从效果还是性能,都是吊打老版的build-in-shader。所以无论如何我们都要开始 拥抱URP,升级Unity的时候到了。 引擎版本 我这里选择了Unity …...
Spring-学习修改尚硅谷最新教程笔记
二、Spring 1、Spring简介 1.1、Spring概述 官网地址:https://spring.io/ Spring 是最受欢迎的企业级 Java 应用程序开发框架,数以百万的来自世界各地的开发人员使用 Spring 框架来创建性能好、易于测试、可重用的代码。 Spring 框架是一个开源的 Jav…...
CPU寄存器的分类与Intel 8086 的eax,ebx,ecx,edx
目录 一、CPU中的寄存器分类 1.用户可见寄存器 2.控制和状态寄存器 一、CPU中的寄存器分类 大致分为两类: 一类属于用户可见寄存器,对这类寄存器编程,以及通过优化使CPU因使用这类寄存器,而减少对主存的访问次数, 另一类属于控…...
如何快速上手Vue框架?
编译软件:IntelliJ IDEA 2019.2.4 x64 运行环境:Google浏览器 Vue框架版本:Vue.js v2.7.14 目录 一. 框架是什么?二. 怎么写一个Vue程序(以IDEA举例)?三. 什么是声明式渲染?3.1 声明式3.2 渲染…...
Android进阶宝典—App响应时间优化
响应时间,它是用来衡量系统运行效率的一个重要指标。评价一个应用的响应时间,可以从用户感知和系统性能这两个角度来考量。 响应时间的长短,可能影响用户对某个功能、某个应用、乃至某个系统的使用。毕竟如果有选择,没有哪个人会愿…...
100天涨薪4k,从功能测试到自动化测试,我整理的3000字超全学习指南
去年6月份,由于经济压力让我下定决心进阶自动化测试,已经24的我做了3年功能测试,坐标广州薪资定格在8k,可能是生活过的太安逸,觉得8000的工资也够了,但是生活总是多变的,女朋友的突然怀孕&#…...
Pytorch剪枝api测试和结果
Pytorch 官方给出的prune接口 下面是基于prune的接口进行剪枝的方法步骤 1、首先prune接口在 torch.nn.utils.prune中,目前支持的剪枝方法有: RandomUnstructuredL1UnstructuredRandomStructuredLnStructuredCustomFromMask ps:非结构性剪…...
微服务下网关聚合Swagger文档、starter统一配置Swagger
一、starter实现统一配置微服务文档 把Swagger配置中的公共部分抽取出来Swagger与SpringBoot整合中,可能会由于版本问题出现各种问题 1、制作starter 参考: 【SpringBoot】自定义启动器 Starter【保姆级教程】用starter实现Oauth2中资源服务的统一配置用…...
剑指 Offer第二版:机器人的运动范围、正则表达式匹配、表示数值的字符串
剑指 Offer第二版 13. 机器人的运动范围19. 正则表达式匹配20. 表示数值的字符串 13. 机器人的运动范围 题目:地上有一个m行n列的方格,从坐标 [0,0] 到坐标 [m-1,n-1] 。一个机器人从坐标 [0, 0] 的格子开始移动,它每次可以向左、右、上、下移…...
Delaunay三角网生成算法
目录 一、分而治之算法二、三角网生长算法三、逐点插入算法四、约束Delaunay三角网1、方法一1、原始点云2、构网结果 1、方法二1、原始点云2、普通Delaunay3、约束Delaunay Delaunay三角剖分分为直接三角剖分和间接三角剖分。间接三角剖分首先计算为Voronoi图,然后由Voronoi图产…...
hashcode是什么?有什么作用?
文章目录 (1)hashcode()方法的作用(2)equals和hashcode的关系(3)百度百科(4)小白解释 Java中Object有一个方法: public native int hashcode(); (1࿰…...
【人体姿态估计】(一)原理介绍
【人体姿态估计】(一)原理介绍 一、背景 人体姿态估计本质上是一个关键点检测的项目; 关键点检测在生活中的应用十分广泛,包括人脸识别、手势识别,而人体姿态估计则是对身体的关键点进行检测; 本文将介…...
一种新的流:为 Java 加入生成器(Generator)特性
作者:文镭(依来) 前言 这篇文章不是工具推荐,也不是应用案例分享。其主题思想,是介绍一种全新的设计模式。它既拥有抽象的数学美感,仅仅从一个简单接口出发,就能推演出庞大的特性集合,引出许多全新概念。…...
《数据结构C++版》实验一:线性表的顺序存储结构
实验目的 1、实现线性表的顺序存储结构 2、熟悉C++程序的基本结构,掌握程序中的头文件、实现文件和主文件之间的相互关系及各自的作用 3、熟悉顺序表的基本操作方式,掌握顺序表相关操作的具体实现 实验内容 对顺序存储的线性表进行一些基本操作。主要包括: (1)插入:操作…...
日语学习-日语知识点小记-构建基础-JLPT-N4阶段(33):にする
日语学习-日语知识点小记-构建基础-JLPT-N4阶段(33):にする 1、前言(1)情况说明(2)工程师的信仰2、知识点(1) にする1,接续:名词+にする2,接续:疑问词+にする3,(A)は(B)にする。(2)復習:(1)复习句子(2)ために & ように(3)そう(4)にする3、…...
【入坑系列】TiDB 强制索引在不同库下不生效问题
文章目录 背景SQL 优化情况线上SQL运行情况分析怀疑1:执行计划绑定问题?尝试:SHOW WARNINGS 查看警告探索 TiDB 的 USE_INDEX 写法Hint 不生效问题排查解决参考背景 项目中使用 TiDB 数据库,并对 SQL 进行优化了,添加了强制索引。 UAT 环境已经生效,但 PROD 环境强制索…...
Nginx server_name 配置说明
Nginx 是一个高性能的反向代理和负载均衡服务器,其核心配置之一是 server 块中的 server_name 指令。server_name 决定了 Nginx 如何根据客户端请求的 Host 头匹配对应的虚拟主机(Virtual Host)。 1. 简介 Nginx 使用 server_name 指令来确定…...
VTK如何让部分单位不可见
最近遇到一个需求,需要让一个vtkDataSet中的部分单元不可见,查阅了一些资料大概有以下几种方式 1.通过颜色映射表来进行,是最正规的做法 vtkNew<vtkLookupTable> lut; //值为0不显示,主要是最后一个参数,透明度…...
12.找到字符串中所有字母异位词
🧠 题目解析 题目描述: 给定两个字符串 s 和 p,找出 s 中所有 p 的字母异位词的起始索引。 返回的答案以数组形式表示。 字母异位词定义: 若两个字符串包含的字符种类和出现次数完全相同,顺序无所谓,则互为…...
今日科技热点速览
🔥 今日科技热点速览 🎮 任天堂Switch 2 正式发售 任天堂新一代游戏主机 Switch 2 今日正式上线发售,主打更强图形性能与沉浸式体验,支持多模态交互,受到全球玩家热捧 。 🤖 人工智能持续突破 DeepSeek-R1&…...
什么是Ansible Jinja2
理解 Ansible Jinja2 模板 Ansible 是一款功能强大的开源自动化工具,可让您无缝地管理和配置系统。Ansible 的一大亮点是它使用 Jinja2 模板,允许您根据变量数据动态生成文件、配置设置和脚本。本文将向您介绍 Ansible 中的 Jinja2 模板,并通…...
Spring Cloud Gateway 中自定义验证码接口返回 404 的排查与解决
Spring Cloud Gateway 中自定义验证码接口返回 404 的排查与解决 问题背景 在一个基于 Spring Cloud Gateway WebFlux 构建的微服务项目中,新增了一个本地验证码接口 /code,使用函数式路由(RouterFunction)和 Hutool 的 Circle…...
【JVM面试篇】高频八股汇总——类加载和类加载器
目录 1. 讲一下类加载过程? 2. Java创建对象的过程? 3. 对象的生命周期? 4. 类加载器有哪些? 5. 双亲委派模型的作用(好处)? 6. 讲一下类的加载和双亲委派原则? 7. 双亲委派模…...
LUA+Reids实现库存秒杀预扣减 记录流水 以及自己的思考
目录 lua脚本 记录流水 记录流水的作用 流水什么时候删除 我们在做库存扣减的时候,显示基于Lua脚本和Redis实现的预扣减 这样可以在秒杀扣减的时候保证操作的原子性和高效性 lua脚本 // ... 已有代码 ...Overridepublic InventoryResponse decrease(Inventor…...
