Java阶段四04
第4章-第4节
一、知识点
CSRF、token、JWT
二、目标
-
理解什么是CSRF攻击以及如何防范
-
理解什么是token
-
理解什么是JWT
-
理解session验证和JWT验证的区别
-
学会使用JWT
三、内容分析
-
重点
-
理解什么是CSRF攻击以及如何防范
-
理解什么是token
-
理解什么是JWT
-
理解session验证和JWT验证的区别
-
学会使用JWT
-
-
难点
-
理解session验证和JWT验证的区别
-
学会使用JWT
-
四、内容
1、CSRF
1.1 概述
CSRF全称为跨站请求伪造(Cross-site request forgery),是一种网络攻击方式,也被称为 one-click attack 或者 session riding。
1.2 原理
CSRF攻击利用网站对于用户网页浏览器的信任,挟持用户当前已登陆的Web应用程序,去执行并非用户本意的操作。网站是通过cookie
来实现登录功能的,而cookie
只要存在浏览器中,那么浏览器在访问这个cookie
的服务器的时候,就会自动的携带cookie
信息到服务器上去。那么这时候就存在一个漏洞了,如果你访问了一个别有用心或病毒网站,这个网站可以在网页源代码中插入js代码,使用js代码给其他服务器发送请求(比如ICBC的转账请求)。那么因为在发送请求的时候,浏览器会自动的把cookie
发送给对应的服务器,这时候相应的服务器(比如ICBC网站),就不知道这个请求是伪造的,就被欺骗过去了。从而达到在用户不知情的情况下,给某个服务器发送了一个请求(比如转账)。
1.3 解决方案
CSRF攻击的要点就是在向服务器发送请求的时候,相应的cookie
会自动的发送给对应的服务器。造成服务器不知道这个请求是用户发起的还是伪造的。这时候,我们可以在用户每次访问有表单的页面的时候,在网页源代码中加一个随机的字符串叫做csrf_token
,在cookie
中也加入一个相同值的csrf_token
字符串。以后给服务器发送请求的时候,必须在body
中以及cookie
中都携带csrf_token
,服务器只有检测到cookie
中的csrf_token
和body
中的csrf_token
都相同,才认为这个请求是正常的,否则就是伪造的。那么黑客就没办法伪造请求了。
2、JWT
2.1 什么是token
Token在计算机身份认证中是令牌(临时)的意思,在词法分析中是标记的意思。一般作为邀请、登录系统使用。
2.2 什么是JWT
Json web token (JWT), 是为了在网络应用环境间传递声明而执行的一种基于JSON
的开放标准((RFC 7519).定义了一种简洁的,自包含的方法用于通信双方之间以JSON
对象的形式安全的传递信息。因为数字签名的存在,这些信息是可信的,JWT可以使用HMAC
算法或者是RSA
的公私秘钥对进行签名。
2.3 JWT的请求流程
-
用户使用账号和面发出登录请求
-
服务器验证并创建一个jwt
-
服务器返回这个jwt给浏览器
-
浏览器将该jwt串在请求头中向服务器发送请求
-
服务器验证该jwt
-
返回响应的资源给浏览器
2.4 为什么使用JWT
2.4.1 传统Session认证的弊端
在用户首次登录成功后,在服务器存储一份用户登录的信息(session),这份登录信息会在响应时传递给浏览器,告诉其保存为cookie,以便下次请求时发送给我们的应用,这样我们的应用就能识别请求来自哪个用户了,这是传统的基于session认证的过程。
然而,传统的session认证有如下的问题:
-
每个用户的登录信息都会保存到服务器的session中,随着用户的增多,服务器开销会明显增大
-
对于非浏览器的客户端、手机移动端等不适用,因为session依赖于cookie,而移动端经常没有cookie
-
因为session认证本质基于cookie,所以如果cookie被截获,用户很容易收到跨站请求伪造攻击。并且如果浏览器禁用了cookie,这种方式也会失效
-
由于基于Cookie,而cookie无法跨域,所以session的认证也无法跨域,对单点登录不适用
2.4.2 JWT认证的优势
-
JWT Token数据量小,传输速度也很快
-
因为JWT Token是以JSON加密形式保存在客户端的,所以JWT是跨语言的,原则上任何web形式都支持
-
不需要在服务端保存会话信息,也就是说不依赖于cookie和session,所以没有了传统session认证的弊端
-
单点登录友好:使用Session进行身份认证的话,由于cookie无法跨域,难以实现单点登录。但是,使用token进行认证的话, token可以被保存在客户端的任意位置的内存中,不一定是cookie,所以不依赖cookie,不会存在这些问题
-
适合移动端应用:使用Session进行身份认证的话,需要保存一份信息在服务器端,而且这种方式会依赖到Cookie(需要 Cookie 保存 SessionId),所以不适合移动端
身份认证在这种场景下,一旦用户完成了登陆,在接下来的每个请求中包含JWT,可以用来验证用户身份以及对路由,服务和资源的访问权限进行验证。由于它的开销非常小,可以轻松的在不同域名的系统中传递。 信息交换在通信的双方之间使用JWT对数据进行编码是一种非常安全的方式,由于它的信息是经过签名的,可以确保发送者发送的信息是没有经过伪造的。
2.4 JWT结构
JWT由3部分组成:标头(Header)、有效载荷(Payload)和签名(Signature)。在传输的时候,会将JWT的3部分分别进行Base64编码后用.
进行连接形成最终传输的字符串
2.5.1 Header
JWT头是一个描述JWT元数据的JSON对象,alg属性表示签名使用的算法,默认为HMAC SHA256(写为HS256)
2.5.2 Payload
有效载荷部分,是JWT的主体内容部分,也是一个JSON对象,包含需要传递的数据。
默认情况下JWT是未加密的,因为只是采用base64算法,拿到JWT字符串后可以转换回原本的JSON数据,任何人都可以解读其内容,因此不要构建隐私信息字段,比如用户的密码一定不能保存到JWT中,以防止信息泄露。JWT只是适合在网络中传输一些非敏感的信息
2.5.3 Signature
签名部分是对上面两部分数据签名,需要使用base64编码后的header和payload数据,通过指定的算法生成哈希,以确保数据不会被篡改。首先,需要指定一个密钥(secret)。该密钥仅仅为保存在服务器中,并且不能向用户公开。然后,使用header中指定的签名算法(默认情况下为HMAC SHA256)根据以下公式生成签名
3、SpringBoot使用JWT
3.1 添加jwt依赖
<dependency><groupId>com.auth0</groupId><artifactId>java-jwt</artifactId><version>3.4.0</version>
</dependency>
3.2 封装工具类
封装返回值的类
@Data
@AllArgsConstructor
@NoArgsConstructor
public class AjaxResult<T> {private Integer code;private String msg;private T data;
/*** 成功的返回结果** @param msg 成功信息* @param data 返回的值* @param <T> 返回值的泛型* @return 返回AjaxResult对象*/public static <T> AjaxResult<T> success(String msg, T data) {return new AjaxResult<T>(200, msg, data);}
/*** 成功的返回结果** @param data 返回的值* @param <T> 返回值的泛型* @return 返回AjaxResult对象*/public static <T> AjaxResult<T> success(T data) {return new AjaxResult<T>(200, "操作成功", data);}
/*** 失败的返回结果** @param msg 成功信息* @param data 返回的值* @param <T> 返回值的泛型* @return 返回AjaxResult对象*/public static <T> AjaxResult<T> error(String msg, T data) {return new AjaxResult<T>(500, msg, data);}
/*** 失败的返回结果** @param data 返回的值* @param <T> 返回值的泛型* @return 返回AjaxResult对象*/public static <T> AjaxResult<T> error(T data) {return new AjaxResult<T>(500, "操作失败", data);}
/*** 认证失败的返回结果** @param msg 成功信息* @param data 返回的值* @param <T> 返回值的泛型* @return 返回AjaxResult对象*/public static <T> AjaxResult<T> unAuth(String msg, T data) {return new AjaxResult<T>(401, msg, data);}
}
将jwt的验证等功能封装一下方便后续调用
public class JWTUtil {// 加密的秘钥封装一下private static final String SECRET = "secret";// id字段private static final String ID_FIELD = "userID";// token的有效时间 30 天private static final Integer TIME_OUT_DAY = 30;
/*** 创建token** @param user 登陆的用户* @return 返回Token字符串*/public static String createToken(SysUser user) {// 获取日历对象实例Calendar calendar = Calendar.getInstance();// 在当前日期加上 TIME_OUT_DAY 的时间,用于设置过期时间calendar.add(Calendar.DATE, TIME_OUT_DAY);System.out.println(user.getId());// 创建jwtreturn JWT.create()// 可以在token中设置数据,设置一个userId为用户的id// 后续可以直接在token中获取id.withClaim(ID_FIELD, user.getId())// 设置token过期时间.withExpiresAt(calendar.getTime())// Algorithm.HMAC256(SECRET) 使用HMAC256的加密方式// secret 指的是秘钥,在这个秘钥的基础上,进行加密,加大破解的难度这个秘钥爱写什么写什么.sign(Algorithm.HMAC256(SECRET));}
/*** 验证JWT,返回为false的时候表示验证失败** @param token token字符串* @return 返回boolean 表示是否登录成功*/public static boolean verifyToken(String token) {try {// 验证JWT,验证不通过会报错JWT.require(Algorithm.HMAC256(SECRET)).build().verify(token);return true;} catch (Exception e) {return false;}}
/*** 获取用户id,返回值是0表示没有找到id** @param token token 字符串* @return 返回对应的用户id,如果为0则表示没有用户*/public static Long getUserId(String token) {try {// 获取id,没有id则会报错return JWT.require(Algorithm.HMAC256(SECRET)).build().verify(token).getClaim(ID_FIELD).asLong();} catch (Exception e) {// 如果报错就返回null表示没有找到对应的用户return 0L;}}
}
3.3 token创建测试
写一个登录接口进行测试,控制层、持久层等代码不展示
@PostMapping("/login")
public AjaxResult<String> login(User user) {// 添加用户的帐号密码的条件LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();wrapper.eq(User::getUsername, user.getUsername());wrapper.eq(User::getPassword, user.getPassword());// 使用Mybatis-Plus查询用户User loginUser = service.getOne(wrapper);// 只有登录成功才需要jwtif (loginUser == null) {return AjaxResult.unAuth("登录失败", null);}String token = JWTUtil.createToken(loginUser);// 登录成功后把token返回给前端return AjaxResult.success(token);
}
发现这个登录接口可以获得到生成的token,说明我们的token的创建是没有问题,那么验证呢?
要验证接口首先要先把请求拦截下来,所以需要添加拦截器
3.4 添加拦截器
3.4.1 拦截器
拦截请求,验证请求头是否携带了token
/*** 授权拦截器,用来验证用户是否有权利访问接口*/
public class AuthInterceptor implements HandlerInterceptor {/*** 要验证用户是否有权限,那么就要验证token** @param request* @param response* @param handler* @return* @throws Exception*/@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {// 从头部获取我们的tokenString token = request.getHeader("token");// 设置返回值类型response.setContentType("text/plain;charset=utf-8");// 如果token是空的就说明没有token,没有权限if (token == null) {response.getWriter().write("没有token");return false;}boolean b = JWTUtil.verifyToken(token);if (!b) {response.getWriter().write("用户认证失败");return false;}// 统一处理用户id不存在的情况Long userId = JWTUtil.getUserId(token);if (userId == null) {response.getWriter().write("用户不存在或者过期");return false;}return b;}
}
3.4.2 拦截器配置
@Configuration
public class AuthInterceptorConfig implements WebMvcConfigurer {@Overridepublic void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(new AuthInterceptor()).addPathPatterns("/**").excludePathPatterns("/user/login");// 登录接口是不要验证token的}
}
3.5 token验证测试
@GetMapping
public AjaxResult<User> getUserInfo(HttpServletRequest req) {LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();// 获取TokenString token = req.getHeader("token");// 获取用户IdLong id = JWTUtil.getUserId(token);// 根据Id查询User loginUser = service.getById(id);if (loginUser == null) {return AjaxResult.error("用户不存在", null);}return AjaxResult.success(loginUser);
}
3.6 优化返回值
优化返回值,改成json格式的
3.6.1 封装响应工具类ResponseUtil
public class ResponseUtil {/**** @param response 响应对象* @param data 要返回的对象* @throws IOException*/public static void responseToWeb(HttpServletResponse response, Object data) throws IOException {ObjectMapper mapper = new ObjectMapper();// 使用jackson的对象转JSON字符串String resultStr = mapper.writeValueAsString(data);// 设置返回的数据类型和编码格式response.setContentType("text/plain;charset=utf-8");// 通过写出流发送给调用者response.getWriter().write(resultStr);}
}
3.6.2 直接调用修改即可
if (token == null) {ResponseUtil.responseToWeb(response, AjaxResult.unAuth("没有Token", null));return false;
}
4、小结
本章节中,我们学习了CSRF攻击以及如何防范、理解了什么是token、什么是JWT、学些了session验证和JWT验证的区别、同时在SpringBoot中对JWT进行了封装和使用,对开发中的登录流程有了一个更加清晰的认知。
下一节中,我们将会学习Redis技术,了解什么是NoSql、为什么要使用NoSql、什么是Redis、Redis的优势是什么、如何使用Redis。
相关文章:
![](https://i-blog.csdnimg.cn/direct/22532575528c402488d057d9ca7ceec0.png)
Java阶段四04
第4章-第4节 一、知识点 CSRF、token、JWT 二、目标 理解什么是CSRF攻击以及如何防范 理解什么是token 理解什么是JWT 理解session验证和JWT验证的区别 学会使用JWT 三、内容分析 重点 理解什么是CSRF攻击以及如何防范 理解什么是token 理解什么是JWT 理解session验…...
![](https://www.ngui.cc/images/no-images.jpg)
B2C API安全警示:爬虫之外,潜藏更大风险挑战
在数字化时代,B2C(Business-to-Consumer)电子商务模式已成为企业连接消费者、推动业务增长的重要桥梁。而B2C API(应用程序编程接口)作为企业与消费者之间数据交互的桥梁,其安全性更是至关重要。然而&#…...
![](https://i-blog.csdnimg.cn/direct/6b940ca2a067400287ff82f0c4c5e44a.png)
OCR文字识别—基于PP-OCR模型实现ONNX C++推理部署
概述 PaddleOCR 是一款基于 PaddlePaddle 深度学习平台的开源 OCR 工具。PP-OCR是PaddleOCR自研的实用的超轻量OCR系统。它是一个两阶段的OCR系统,其中文本检测算法选用DB,文本识别算法选用CRNN,并在检测和识别模块之间添加文本方向分类器&a…...
![](https://i-blog.csdnimg.cn/direct/c15ccdefcdc1473abada87caae053eee.png#pic_center)
如何播放视频文件
文章目录 1. 概念介绍2. 使用方法2.1 实现步骤2.2 具体细节3. 示例代码4. 内容总结我们在上一章回中介绍了"如何获取文件类型"相关的内容,本章回中将介绍如何播放视频.闲话休提,让我们一起Talk Flutter吧。 1. 概念介绍 播放视频是我们常用的功能,不过Flutter官方…...
![](https://i-blog.csdnimg.cn/direct/710ffefbaba44bca8282970f3b81a4cc.png)
MySQL -- 约束
1. 数据库约束 数据库约束时关系型数据库的一个重要功能,主要的作用是保证数据的有效性,也可以理解为数据的正确性(数据本身是否正确,关联关系是否正确) 人工检查数据的完整性工作量非常大,在数据库中定义一些约束,那么数据在写入数据库的时候,就会帮我们做一些校验.并且约束一…...
![](https://i-blog.csdnimg.cn/direct/fe8369584b54401db775d8a03b40b465.png)
php 使用simplexml_load_string转换xml数据格式失败
本文介绍如何使用php函数解析xml数据为数组。 <?php$a <xml><ToUserName><![CDATA[ww8b77afac71336111]]></ToUserName><FromUserName><![CDATA[sys]]></FromUserName><CreateTime>1736328669</CreateTime><Ms…...
![](https://i-blog.csdnimg.cn/img_convert/6e420fd0e4aa74861ef134af906d005b.png)
net-http-transport 引发的句柄数(协程)泄漏问题
Reference 关于 Golang 中 http.Response.Body 未读取导致连接复用问题的一点研究https://manishrjain.com/must-close-golang-http-responsehttps://www.reddit.com/r/golang/comments/13fphyz/til_go_response_body_must_be_closed_even_if_you/?rdt35002https://medium.co…...
![](https://i-blog.csdnimg.cn/img_convert/bdbfdee6455e441936278d8ef0c1d469.png)
高级软件工程-复习
高级软件工程复习 坐标国科大,下面是老师说的考试重点。 Ruby编程语言的一些特征需要了解要能读得懂Ruby程序Git的基本命令操作知道Rails的MVC工作机理需要清楚,Model, Controller, View各司什么职责明白BDD的User Story需要会写,SMART要求能…...
![](https://www.ngui.cc/images/no-images.jpg)
eslint.config.js和.eslintrc.js有什么区别
eslint.config.js 和 .eslintrc.js 的主要区别在于它们所对应的 ESLint 版本和配置方法: 1. .eslintrc.js: 这是 ESLint v8 及更早版本使用的配置文件格式。 它使用层级式的配置系统。 现在被称为"旧版"配置格式 。 2. eslint.config.js&am…...
![](https://www.ngui.cc/images/no-images.jpg)
如何使用MVC模式设计和实现校园自助点餐系统的微信小程序
随着智慧校园的普及,校园自助点餐系统在提高学生用餐效率、减轻食堂运营压力方面发挥了重要作用。 在开发这类系统时,MVC(Model-View-Controller)模式是一种非常适合的架构,它将系统的业务逻辑、用户界面和数据交互清晰…...
![](https://i-blog.csdnimg.cn/direct/2237ff9a93b342c78a859a63565198ba.png)
继续坚持与共勉
经过期末考试后,又要开始学习啦。 当时一直在刷算法题就很少写博客了,现在要继续坚持写博客,将每天对于题的感悟记录下来。 同时我将会在学习Linux操作系统,对于过去学习的内容进行回顾!! 在此ÿ…...
![](https://www.ngui.cc/images/no-images.jpg)
人机交互 | 期末复习(上)| 补档
文章目录 📚1-HCI Introduction🐇人机交互的定义,分别解释人-机-交互的概念🐇six ”mantras“ of UCD🐇Difference between User-Interface (UI) and User-Experience(UX)📚2-HCI history🐇WIMP🐇WYSIWYG📚3-Understanding User🐇Design Thinking Process的…...
![](https://i-blog.csdnimg.cn/direct/a28104572f534f1fa0e7405c54e3e211.png)
Oracle 表分区简介
目录 一. 前置知识1.1 什么是表分区1.2 表分区的优势1.3 表分区的使用条件 二. 表分区的方法2.1 范围分区(Range Partitioning)2.2 列表分区(List Partitioning)2.3 哈希分区(Hash Partitioning)2.4 复合分…...
![](https://i-blog.csdnimg.cn/direct/9a1c76d4af97452f9d507c66553204cf.png)
多并发发短信处理(头条项目-07)
1 pipeline操作 Redis数据库 Redis 的 C/S 架构: 基于客户端-服务端模型以及请求/响应协议的 TCP服务。客户端向服务端发送⼀个查询请求,并监听Socket返回。通常是以 阻塞模式,等待服务端响应。服务端处理命令,并将结果返回给客…...
![](https://www.ngui.cc/images/no-images.jpg)
网络编程的进程查看连接描述符信息等
一.查看当前进程的socket对应的fd信息 1. lsof lsof(List Open Files)命令可以列出系统中所有打开的文件的信息,包括 socket。 用法 要查看特定进程的 socket 信息,可以使用以下命令: lsof -p <pid> | grep…...
![](https://www.ngui.cc/images/no-images.jpg)
ChatGPT API快速搭建自己的第一个应用—文章摘要(单轮对话应用)
使用ChatGPT API快速搭建自己的第一个应用 1 安装库2 设置与导入3 文章摘要(单轮对话应用)3.1 任务简介:3.2 初始化3.3 点击发送3.4 保存3.5 检查并打印你的结果1 安装库 !pip install gradiogradio 是一个用于快速搭建交互式用户界面的 Python 库,特别适合展示机器学习模…...
![](https://i-blog.csdnimg.cn/img_convert/baf0774baba64cd329b7829a1d920f97.png)
【01】AE特效开发制作特技-Adobe After Effects-AE特效制作快速入门-制作飞机,子弹,爆炸特效以及导出png序列图-优雅草央千澈
【01】AE特效开发制作特技-Adobe After Effects-AE特效制作快速入门-制作飞机,子弹,爆炸特效以及导出png序列图-优雅草央千澈 开发背景 优雅草央千澈所有的合集,系列文章可能是不太适合完全初学者的,因为课程不会非常细致的系统…...
![](https://i-blog.csdnimg.cn/direct/3818b2e9bf3e4fa585d6add1c7202eb9.png)
软件测试预备知识④—NTFS权限管理、磁盘配额与文件共享
在软件测试的实际环境搭建与管理过程中,了解和掌握NTFS权限管理、磁盘配额以及文件共享等知识至关重要。这些功能不仅影响系统的安全性和稳定性,还对测试数据的存储、访问以及多用户协作测试有着深远的影响。 一、NTFS权限管理 1.1 NTFS简介 NTFS&am…...
![](https://i-blog.csdnimg.cn/direct/5ff9cf3729634a2686249308321a8cd2.png)
CI/CD 流水线
CI/CD 流水线 CI 与 CD 的边界CI 持续集成CD(持续交付/持续部署)自动化流程示例: Jenkins 引入到 CI/CD 流程在本地或服务器上安装 Jenkins。配置 Jenkins 环境流程设计CI 阶段:Jenkins 流水线实现CD 阶段:Jenkins 流水…...
![](https://www.ngui.cc/images/no-images.jpg)
【python3】 sqlite格式的db文件获得所有表和数据
【python3】 sqlite格式的db文件获得所有表和数据 1.背景2.代码3.解析1.背景 SQLite 格式的 .db 文件就是一个包含 SQLite 数据库的文件。 SQLite 格式的 .db 文件通常存储的是一个关系型数据库。 SQLite广泛用于应用程序、移动设备、浏览器等场景。它将整个数据库存储在一个文…...
![](https://i-blog.csdnimg.cn/img_convert/6d978ad0454243c3df7fe73859a00c38.png)
【灵码助力安全3】——利用通义灵码辅助智能合约漏洞检测的尝试
前言 随着区块链技术的快速发展,智能合约作为去中心化应用(DApps)的核心组件,其重要性日益凸显。然而,智能合约的安全问题一直是制约区块链技术广泛应用的关键因素之一。由于智能合约代码一旦部署就难以更改…...
![](https://i-blog.csdnimg.cn/img_convert/8d5b7d215a7aefa9b5c1465e33c44cb4.png)
openEuler 22.04使用yum源最快速度部署k8s 1.20集群
本文目的 openEuler的官方源里有kubernetes 1.20,使用yum源安装是最快部署一个k8s集群的办法 硬件环境 主机名系统架构ipmasteropenEuler release 22.03 (LTS-SP2)arm192.168.3.11edgeopenEuler release 22.03 (LTS-SP2)arm192.168.3.12deviceopenEuler release 22.…...
![](https://www.ngui.cc/images/no-images.jpg)
Docker Compose 教程
Docker Compose 是一个 Docker 容器的依赖管理工具。 例如我们一个服务需要依赖到多个 Docker 容器,那么使用 Docker Compose 这个工具就能很方便的帮助我们管理。 Docker Compose 通过配置文件 .yml。 定义了所有容器的依赖关系。 然后我们只需把我们想要的 Docke…...
![](https://i-blog.csdnimg.cn/direct/33d610274f6c44b885a322ee86157fc0.jpeg#pic_center)
opencv的NLM去噪算法
NLM(Non-Local Means)去噪算法是一种基于图像块(patch)相似性的去噪方法。其基本原理是: 图像块相似性:算法首先定义了一个搜索窗口(search window),然后在该窗口内寻找…...
![](https://www.ngui.cc/images/no-images.jpg)
scala基础学习_方法函数
文章目录 方法与函数函数(又称函数值/匿名函数)定义方法注意 单参数函数多参数函数函数作为参数传递 方法将方法转换为函数方法的返回值总结 方法与函数 函数(又称函数值/匿名函数) 定义在任何地方:函数可以定义在类…...
![](https://i-blog.csdnimg.cn/direct/6ba7efe42b62420289a9fcc224c28161.png)
Android车机DIY开发之软件篇(八)单独编译
Android车机DIY开发之软件篇(八)单独编译 1.CarLauncher单独编译 CarLauncher源码位于 packages/apps/Car/Launcher 用Eclipse ADT 谷歌定制版编译而成,.mk .bp编译 Android13目录如下: alientekalientek:~/packages/apps/Car$ ls Calendar …...
![](https://www.ngui.cc/images/no-images.jpg)
【Bug】报错信息:Required request body is missing(包含五种详细解决方案)
大家好,我是摇光~ 遇到“Required request body is missing”错误通常意味着服务器期望在HTTP请求中包含一个请求体(body),但是实际上并没有收到。 例如: 当你在使用网页或应用程序的后台(比如一个网站或手…...
![](https://www.ngui.cc/images/no-images.jpg)
Docker 专栏 —— Dockerfile 指令详解
文章目录 ADD 复制文件COPY 复制文件ARG 设置构建参数CMD 容器启动命令ENTRYPOINT ⼊⼝点ENV 设置环境变量EXPOSE 声明暴露的端⼝FROM 指定基础镜像LABEL 为镜像添加元数据MAINTAINER 指定维护者的信息RUN 执⾏命令USER 设置⽤户VOLUME 指定挂载点WORKDIR 指定⼯作⽬录 ADD 复制…...
![](https://i-blog.csdnimg.cn/direct/5bff7c98516346619a277aafb9dd0fa3.png)
Spring Boot 项目自定义加解密实现配置文件的加密
在Spring Boot项目中, 可以结合Jasypt 快速实现对配置文件中的部分属性进行加密。 完整的介绍参照: Spring Boot Jasypt 实现application.yml 属性加密的快速示例 但是作为一个技术强迫症,总是想着从底层开始实现属性的加解密,…...
![](https://i-blog.csdnimg.cn/direct/2507617e04814969801452122fc2d22a.png)
在ubuntu下对NFS做性能测试
安装NFS 首先,安装服务 sudo apt update sudo apt install nfs-kernel-server然后创建共享文件夹 # 请自定义你自己的共享目录 sudo mkdir -p /exports/nfs4/homes sudo chmod -R 777 /exports/nfs4/homes# 这个可以根据no_root_squash标致选择设置。 # 如果不设…...
![](https://img-blog.csdnimg.cn/img_convert/70821d368a320e304eb3fe26f55faf9c.gif)
建设银行官网网站首页/搜易网托管模式的特点
梅学堂语数英精品学习资源免费领一二年级的小朋友,大部分处于形象思维快速发展,逻辑思维发展相对迟缓的状态。总的来说,孩子们的思维水平是在进步的,但是相对于解题来说他们依然会有所欠缺。例如,对初中生高中生来说&a…...
![](https://img-blog.csdnimg.cn/20200722000827254.png#pic_center)
wordpress文章分类目录进不去/做网站建设优化的公司排名
1.下载JDK(以8.0为例) jdk和jre官方网址:https://www.oracle.com/cn/java/technologies/javase-downloads.html 根据系统下载对应jdk,32位系统对应x86,64位系统对应x64 点击下载转到页面登录账户之后下载得到一个可执行…...
![](/images/no-images.jpg)
wordpress用户登录显示请求失败/google浏览器官方下载
Scala数据交互 Scala使用一种函数式的方式来处理数据交互,包括入参及返回值。 Option: 解决null(空指针)问题Either: 解决返回值不确定(返回两个值的其中一个)问题Try: 解决函数可能会抛出异常问题 Option/Some/None的…...
![](/images/no-images.jpg)
做通路富集分析的网站/cba最新消息
问题描述:客户端连接数据库报错,ORA-12516: TNS: 监听程序无法找到匹配协议栈的可用句柄 解决过程:1。查看当前会话数、processes和sessions值,发现session数和2个参数的值已经非常逼近SQL*Plus: Release 10.2.0.1.0 - Production on 星期一 …...
![](https://images0.cnblogs.com/blog/349217/201312/15160642-f5975482ad8641dab0712d26b7118401.png)
中铁建设门户网登录入口手机端/网店关键词怎么优化
昨天写了篇博客,介绍了一下我对node.js的第一次亲密接触后的感受,以为node.js很小众,出乎我意料很多人感兴趣,并且对博客中的细节问题做了评论,最多的是围绕node.js的异步与单线程展开的,当然还有很多关于n…...
![](/images/no-images.jpg)
网站建设分哪些类别/好的营销网站
开门见山的说:不会。首先,什么是编程能力?算法吗?数据结构吗?操作系统吗?是对语法的熟练程度吗?是源码的阅读量、代码的编写行数吗?搭个网站算是编程能力吗?都不是。编程…...