springboot集成JWT實現token權限認證

vue+springboot登錄與注冊功能的實現

注:對于JWT的學習,首先要完成注冊和登錄的功能,本篇博客是基于上述博客的進階學習,代碼頁也是在原有的基礎上進行擴展

①在pom.xml添加依賴

<!-- JWT -->
<dependency><groupId>com.auth0</groupId><artifactId>java-jwt</artifactId><version>4.3.0</version>
</dependency>

②在common文件夾下定義一個JwtInterceptor攔截器java文件

Jwtlnterceptor:?

package com.example.springboot.common;import cn.hutool.core.util.StrUtil;
import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.JWTDecodeException;
import com.auth0.jwt.exceptions.JWTVerificationException;
import com.example.springboot.entity.User;
import com.example.springboot.exception.ServiceException;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import com.example.springboot.mapper.UserMapper;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;public class JwtInterceptor implements HandlerInterceptor {@Resourceprivate UserMapper userMapper;@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {String token = request.getHeader("token");if (StrUtil.isBlank(token)) {token = request.getParameter("token");}// 如果不是映射到方法直接通過
//        if (handler instanceof HandlerMethod) {
//            AuthAccess annotation = ((HandlerMethod) handler).getMethodAnnotation(AuthAccess.class);
//            if (annotation != null) {
//                return true;
//            }
//        }// 執行認證if (StrUtil.isBlank(token)) {throw new ServiceException("401", "請登錄");}// 獲取 token 中的 user idString userId;try {userId = JWT.decode(token).getAudience().get(0);} catch (JWTDecodeException j) {throw new ServiceException("401", "請登錄");}// 根據token中的userid查詢數據庫User user = userMapper.selectbyid(Integer.valueOf(userId));if (user == null) {throw new ServiceException("401", "請登錄");}// 用戶密碼加簽驗證 tokenJWTVerifier jwtVerifier = JWT.require(Algorithm.HMAC256(user.getPassword())).build();try {jwtVerifier.verify(token); // 驗證token} catch (JWTVerificationException e) {throw new ServiceException("401", "請登錄");}return true;}
}

③修改自定義異常

GlobalExeception:

package com.example.springboot.exception;import com.example.springboot.common.Result;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;@ControllerAdvice
public class GlobalExeception {@ExceptionHandler(ServiceException.class)@ResponseBodypublic Result serviceException(ServiceException e){return Result.error(e.getCode(),e.getMessage());}
}

ServiceException:

package com.example.springboot.exception;import lombok.Getter;@Getter
public class ServiceException extends RuntimeException{private final String code;public ServiceException(String msg){super(msg);this.code="500";}public ServiceException(String code,String msg){super(msg);this.code=code;}
}

?④配置攔截器 InterceptorConfig

InterceptorConfig:?

package com.example.springboot.common;import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;@Configuration
public class InterceptorConfig extends WebMvcConfigurationSupport {@Overrideprotected void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(jwtInterceptor()).addPathPatterns("/**").excludePathPatterns("/login");super.addInterceptors(registry);}@Beanpublic JwtInterceptor jwtInterceptor() {return new JwtInterceptor();}}

?⑤新建一個工具類TokenUtils

?TokenUtils:

package com.example.springboot.utils;import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.auth0.jwt.JWT;
import com.auth0.jwt.algorithms.Algorithm;
import com.example.springboot.entity.User;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import com.example.springboot.mapper.UserMapper;
import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.Date;@Component
public class TokenUtils {private static UserMapper staticUserMapper;@ResourceUserMapper userMapper;@PostConstructpublic void setUserService() {staticUserMapper = userMapper;}/*** 生成token** @return*/public static String createToken(String userId, String sign) {return JWT.create().withAudience(userId) // 將 user id 保存到 token 里面,作為載荷.withExpiresAt(DateUtil.offsetHour(new Date(), 2)) // 2小時后token過期.sign(Algorithm.HMAC256(sign)); // 以 password 作為 token 的密鑰}/*** 獲取當前登錄的用戶信息** @return user對象*/public static User getCurrentUser() {try {HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();String token = request.getHeader("token");if (StrUtil.isNotBlank(token)) {String userId = JWT.decode(token).getAudience().get(0);return staticUserMapper.selectbyid(Integer.valueOf(userId));}} catch (Exception e) {return null;}return null;}
}

修改UserService和User:

UserService:

package com.example.springboot.service;import com.example.springboot.entity.User;
import com.example.springboot.exception.ServiceException;
import com.example.springboot.mapper.UserMapper;
import com.example.springboot.utils.TokenUtils;
import jdk.nashorn.internal.parser.Token;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.RequestBody;import java.util.List;@Service
public class UserService {@AutowiredUserMapper userMapper;public void insertUser(User user){userMapper.insert(user);}public void updateUser(User user) {userMapper.updateUser(user);}public void deleteUser(Integer id) {userMapper.deleteUser(id);}public void batchdeleteUser(List<Integer> ids) {for(Integer id : ids){userMapper.deleteUser(id);}}public List<User> selectall() {return userMapper.selectall();}public User selectbyid(Integer id) {return userMapper.selectbyid(id);}public List<User> selectbyname(String name) {return userMapper.selectbyname(name);}public List<User> selectbymore(String username, String name) {return userMapper.selectbymore(username,name);}public List<User> selectbymo(String username, String name) {return userMapper.selectbymo(username,name);}public User login(User user) {User dbuser=userMapper.selectbyUsername(user.getUsername());if(dbuser == null){throw new ServiceException("賬號不存在");}if(!user.getPassword().equals(dbuser.getPassword())){throw new ServiceException("賬號或者密碼錯誤");}String token=TokenUtils.createToken(dbuser.getId().toString(),dbuser.getPassword());dbuser.setToken(token);return dbuser;}public User register(User user) {User dbuser=userMapper.selectbyUsername(user.getUsername());if(dbuser != null){throw new ServiceException("用戶名已存在");}userMapper.insert(user);return user;}
}

User:

package com.example.springboot.entity;import lombok.AllArgsConstructor;
import lombok.Data;@Data
public class User {private Integer id;private String username;private String password;private String name;private String phone;private String email;private String address;private String avatar;private String token;
}

登錄試下,在預覽發現token:

請求的數據會存在應用程序的本地存儲中:?

⑥在vue中修改request.js

import axios from 'axios'
import router from "@/router";// 創建可一個新的axios對象
const request = axios.create({baseURL: 'http://localhost:9090',   // 后端的接口地址  ip:porttimeout: 30000
})// request 攔截器
// 可以自請求發送前對請求做一些處理
// 比如統一加token,對請求參數統一加密
request.interceptors.request.use(config => {config.headers['Content-Type'] = 'application/json;charset=utf-8';let user=JSON.parse(localStorage.getItem("honey-user")||'{}')// let user = localStorage.getItem("user") ? JSON.parse(localStorage.getItem("user")) : nullconfig.headers['token'] = user.token  // 設置請求頭return config
}, error => {console.error('request error: ' + error) // for debugreturn Promise.reject(error)
});// response 攔截器
// 可以在接口響應后統一處理結果
request.interceptors.response.use(response => {let res = response.data;// 兼容服務端返回的字符串數據if (typeof res === 'string') {res = res ? JSON.parse(res) : res}if(res.code === '401'){router.push('/login')}return res;},error => {console.error('response error: ' + error) // for debugreturn Promise.reject(error)}
)export default request

管理系統代碼要做如下修改:退出登錄的時候要清除數據

<template><div><el-container><!--    側邊欄  --><el-aside :width="asideWidth" style="min-height: 100vh; background-color: #001529"><div style="height: 60px; color: white; display: flex; align-items: center; justify-content: center"><img src="@/assets/logo1.png" alt="" style="width: 40px; height: 40px"><span class="logo-title" v-show="!isCollapse">honey2024</span></div><el-menu :collapse="isCollapse" :collapse-transition="false" router background-color="#001529" text-color="rgba(255, 255, 255, 0.65)" active-text-color="#fff" style="border: none" :default-active="$route.path"><el-menu-item index="/"><i class="el-icon-menu"></i><span slot="title">系統首頁</span></el-menu-item><el-menu-item index="/1"><i class="el-icon-house"></i><span slot="title">系統首頁</span></el-menu-item><el-menu-item index="/2"><i class="el-icon-house"></i><span slot="title">系統首頁</span></el-menu-item><el-submenu index="3"><template slot="title"><i class="el-icon-menu"></i><span>信息管理</span></template><el-menu-item>用戶信息</el-menu-item><el-menu-item>管理員信息</el-menu-item><el-menu-item index="/">系統首頁</el-menu-item></el-submenu></el-menu></el-aside><el-container><!--        頭部區域--><el-header><i :class="collapseIcon" style="font-size: 26px" @click="handleCollapse"></i><el-breadcrumb separator-class="el-icon-arrow-right" style="margin-left: 20px"><el-breadcrumb-item :to="{ path: '/' }">首頁</el-breadcrumb-item><el-breadcrumb-item :to="{ path: '/user' }">用戶管理</el-breadcrumb-item></el-breadcrumb><div style="flex: 1; width: 0; display: flex; align-items: center; justify-content: flex-end"><i class="el-icon-quanping" style="font-size: 26px" @click="handleFull"></i><el-dropdown placement="bottom"><div style="display: flex; align-items: center; cursor: default"><img src="@/assets/logo1.png" alt="" style="width: 40px; height: 40px; margin: 0 5px"><span>管理員</span></div><el-dropdown-menu slot="dropdown"><el-dropdown-item>個人信息</el-dropdown-item><el-dropdown-item>修改密碼</el-dropdown-item><el-dropdown-item @click.native="logout">退出登錄</el-dropdown-item></el-dropdown-menu></el-dropdown></div></el-header><!--        主體區域--><el-main><div style="box-shadow: 0 0 10px rgba(0,0,0,.1); padding: 10px 20px; border-radius: 5px; margin-bottom: 10px">早安,騷年,祝你開心每一天!</div><div style="display: flex;"><el-card style="width: 50%;margin-right: 10px;"><div slot="header" class="clearfix"><span>青哥哥帶你做畢設2024</span></div><div>2024畢設正式開始了!青哥哥帶你手把手敲出來!<div style="margin-top: 20px"><div style="margin: 10px 0"><strong>主題色</strong></div><el-button type="primary">按鈕</el-button><el-button type="success">按鈕</el-button><el-button type="warning">按鈕</el-button><el-button type="danger">按鈕</el-button><el-button type="info">按鈕</el-button></div></div></el-card><el-card style="width: 50%;"><div slot="header" class="clearfix"><span>渲染用戶的數據</span></div><div><el-table :data="users"><el-table-column label="ID" prop="id"/><el-table-column label="用戶名" prop="username"/><el-table-column label="姓名" prop="name"/><el-table-column label="地址" prop="address"/></el-table></div></el-card></div></el-main></el-container></el-container></div>
</template><script>
import axios from "axios";
import request from '@/utils/request'export default {name: 'HomeView',data() {return {isCollapse: false,  // 不收縮asideWidth: '200px',collapseIcon: 'el-icon-s-fold',users: []}},mounted() {// axios.get('http://localhost:9090/user/selectall').then(res=>{//   console.log(res.data);//   this.users=res.data.data// })request.get('/user/selectall').then(res => {this.users = res.data})},methods: {logout() {localStorage.removeItem("honey-user")this.$router.push('/login')},handleFull() {document.documentElement.requestFullscreen()},handleCollapse() {this.isCollapse = !this.isCollapsethis.asideWidth = this.isCollapse ? '64px' : '200px'this.collapseIcon = this.isCollapse ? 'el-icon-s-unfold' : 'el-icon-s-fold'}}
}
</script><style>
.el-menu--inline {background-color: #000c17 !important;
}.el-menu--inline .el-menu-item {background-color: #000c17 !important;padding-left: 49px !important;
}.el-menu-item:hover, .el-submenu__title:hover {color: #fff !important;
}.el-submenu__title:hover i {color: #fff !important;
}.el-menu-item:hover i {color: #fff !important;
}.el-menu-item.is-active {background-color: #1890ff !important;border-radius: 5px !important;width: calc(100% - 8px);margin-left: 4px;
}.el-menu-item.is-active i, .el-menu-item.is-active .el-tooltip {margin-left: -4px;
}.el-menu-item {height: 40px !important;line-height: 40px !important;
}.el-submenu__title {height: 40px !important;line-height: 40px !important;
}.el-submenu .el-menu-item {min-width: 0 !important;
}.el-menu--inline .el-menu-item.is-active {padding-left: 45px !important;
}/*.el-submenu__icon-arrow {*/
/*  margin-top: -5px;*/
/*}*/.el-aside {transition: width .3s;box-shadow: 2px 0 6px rgba(0, 21, 41, .35);
}.logo-title {margin-left: 5px;font-size: 20px;transition: all .3s; /* 0.3s */
}.el-header {box-shadow: 2px 0 6px rgba(0, 21, 41, .35);display: flex;align-items: center;
}
</style>

此時還有個小問題:在注冊頁注冊的時候,會顯示登錄失敗

?⑦新建自定義注解(作用:在攔截器需要放行的地方放行)

AuthAuccess:

import java.lang.annotation.*;@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface AuthAccess {
}

Jwtlnterceptor:

package com.example.springboot.common;
import org.springframework.web.method.HandlerMethod;
import cn.hutool.core.util.StrUtil;
import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.JWTDecodeException;
import com.auth0.jwt.exceptions.JWTVerificationException;
import com.example.springboot.entity.User;
import com.example.springboot.exception.ServiceException;
import org.springframework.web.servlet.HandlerInterceptor;
import com.example.springboot.mapper.UserMapper;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;public class JwtInterceptor implements HandlerInterceptor {@Resourceprivate UserMapper userMapper;@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {String token = request.getHeader("token");if (StrUtil.isBlank(token)) {token = request.getParameter("token");}// 如果不是映射到方法直接通過if (handler instanceof HandlerMethod) {AuthAccess annotation = ((HandlerMethod) handler).getMethodAnnotation(AuthAccess.class);if (annotation != null) {return true;}}// 執行認證if (StrUtil.isBlank(token)) {throw new ServiceException("401", "請登錄");}// 獲取 token 中的 user idString userId;try {userId = JWT.decode(token).getAudience().get(0);} catch (JWTDecodeException j) {throw new ServiceException("401", "請登錄");}// 根據token中的userid查詢數據庫User user = userMapper.selectbyid(Integer.valueOf(userId));if (user == null) {throw new ServiceException("401", "請登錄");}// 用戶密碼加簽驗證 tokenJWTVerifier jwtVerifier = JWT.require(Algorithm.HMAC256(user.getPassword())).build();try {jwtVerifier.verify(token); // 驗證token} catch (JWTVerificationException e) {throw new ServiceException("401", "請登錄");}return true;}
}

?WebController:引用自定義注解地方就表示放行

package com.example.springboot.controller;import cn.hutool.core.util.StrUtil;
import com.example.springboot.common.AuthAccess;
import com.example.springboot.common.Result;
import com.example.springboot.entity.User;
import com.example.springboot.exception.ServiceException;
import com.example.springboot.service.UserService;
import org.springframework.web.bind.annotation.*;import javax.annotation.Resource;@RestController
public class WebController {@ResourceUserService userService;@AuthAccess@GetMapping("/")public Result hello(){return Result.success("success");}@PostMapping("/login")public Result login(@RequestBody User user){if(StrUtil.isBlank(user.getUsername())||StrUtil.isBlank(user.getPassword())){return Result.error("數據輸入錯誤");}user=userService.login(user);return Result.success(user);}@AuthAccess@PostMapping("/register")public Result register(@RequestBody User user){if(StrUtil.isBlank(user.getUsername())||StrUtil.isBlank(user.getPassword())){throw new ServiceException("輸入不合法");}if(user.getUsername().length()>10||user.getPassword().length()>20){throw new ServiceException("長度過長");}user=userService.register(user);return Result.success(user);}
}

如果不使用自定義注解的方法,也可以直接修改InterceptorConfig:

package com.example.springboot.common;import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;@Configuration
public class InterceptorConfig extends WebMvcConfigurationSupport {@Overrideprotected void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(jwtInterceptor()).addPathPatterns("/**").excludePathPatterns("/login","/register");super.addInterceptors(registry);}@Beanpublic JwtInterceptor jwtInterceptor() {return new JwtInterceptor();}}

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/696566.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/696566.shtml
英文地址,請注明出處:http://en.pswp.cn/news/696566.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Linux篇:Shell命令以及運行原理 和 權限

一. Shell命令及原理 Linux操作系統狹義上是Linux內核&#xff0c;廣義上是指Linux內核Linux外殼(Shell)和對應的配套程序 Linux外殼&#xff1a;Linux 外殼是用戶與內核之間的接口&#xff0c;用戶通過外殼與操作系統進行交互和操作。在 Linux 系統中&#xff0c;用戶可以選…

C語言——static的三大用法

被稱為面試愛考愛問題的它到底有何奧義 它難度不大并且非常常用&#xff0c;話不多說&#xff0c;直接開始 一、局部靜態變量 定義 在函數內部使用static修飾的變量被稱為局部靜態變量&#xff0c;與普通的局部變量不同&#xff0c;局部靜態變量在使用后不會被銷毀&#xff…

pycharm 遠程運行報錯 Failed to prepare environment

什么也沒動的情況下&#xff0c;遠程連接后運行是沒問題的&#xff0c;突然在運行時就運行不了了&#xff0c;解決方案 清理緩存&#xff1a; 有時候 PyCharm 的內部緩存可能出現問題&#xff0c;可以嘗試清除緩存&#xff08;File > Invalidate Caches / Restart&#xff0…

mysql優化指南之原理篇

之前碰到一個線上問題&#xff0c;在接手一個同事的項目后&#xff0c;因為工期比較趕&#xff0c;我還沒來得及了解業務背景和大致實現&#xff0c;只是了解了上線發布的順序和驗證方式就進行了上線&#xff0c;在上線進行金絲雀的時候系統還沒發生什么異常&#xff0c;于是我…

【面試題】談談MySQL的事務

事務是啥 MySQL的事務就是把多個sql語句操作打包在一起執行&#xff0c;要么全部執行&#xff0c;要么一個都別執行。這種操作稱為“原子性”&#xff0c;是事務最核心的特征。當某個sql操作出錯時&#xff0c;就會進行“回滾/rollback”操作&#xff0c;即把執行過的操作逆向…

MySQL數據庫進階第二篇(索引,SQL性能分析,使用規則)

文章目錄 一、索引概述二、索引結構三、結構 - B-Tree四、結構 - BTree五、結構 - Hash六、索引分類七、索引語法1.案例代碼 八、SQL性能分析1.查看SQl執行頻率2.慢查詢日志3.PROFILES詳情4.EXPLAIN執行計劃 九、 索引使用規則十、SQL 提示十一、覆蓋索引十二、前綴索引十三、單…

滾動加載react-infinite-scroll-component

react-infinite-scroll-component 當請求數據量過大時&#xff0c;接口返回數據時間會很長&#xff0c;數據回顯時間長&#xff0c;Dom 的渲染會有很大的性能壓力。 antd的List組件中有提到一個滾動加載的組件庫react-infinite-scroll-component 實現滾動加載 Antd&#xff1…

考研高數(高階導數的計算)

1.歸納法 常見高階導數 2.泰勒展開式 3.萊布尼茲公式 4.用導數定義證明導函數在某一點連續的例題

【kubernetes】二進制部署k8s集群之cni網絡插件flannel和calico工作原理(中)

↑↑↑↑接上一篇繼續部署↑↑↑↑ 目錄 一、k8s集群的三種接口 二、k8s的三種網絡模式 1、pod內容器之間的通信 2、同一個node節點中pod之間通信 3、不同的node節點的pod之間通信 Overlay Network VXLAN 三、flannel網絡插件 1、flannel插件模式之UDP模式&#xff0…

java對象所占內存大小輸出

如何計算java對象所占內存大小&#xff0c;可以使用下述三種方法。 使用jdk8自帶API 使用下面語句打印對象所占內存大小&#xff1a;需要保證jdk版本是jdk8。System.out.println(ObjectSizeCalculator.getObjectSize(3L)); 借助org.apache.lucene工具類 引入maven坐標 <…

2024/2/22

P8680 [藍橋杯 2019 省 B] 特別數的和 題目描述 小明對數位中含有 2、0、1、9 的數字很感興趣&#xff08;不包括前導 00&#xff09;&#xff0c;在 1 到 40 中這樣的數包括 1、2、9、10 至 32、39 和 40&#xff0c;共28 個&#xff0c;他們的和是574。 請問&#xff0c;在…

【2024軟件測試面試必會技能】

Unittest(5)&#xff1a;unittest_忽略用例 忽略用例 在執行測試腳本的時候&#xff0c;可能會有某幾條用例本次不想執行&#xff0c;但又不想刪也 不想注釋&#xff0c;unittest通過忽略部分測試用例不執行的方式&#xff0c;分無條件忽略和有條 件忽略,通過裝飾器實現所描述…

Vue3+vite搭建基礎架構(11)--- 菜單欄功能和Tab頁功能實現

Vue3vite搭建基礎架構&#xff08;11&#xff09;--- 菜單欄功能和Tab頁功能實現 說明刪除項目中不需要的文件userStore全局屬性代碼菜單欄代碼Tab頁代碼解決瀏覽器輸入地址時不會打開tab頁問題和切換tab頁時參數丟失問題 說明 這里記錄下自己在Vue3vite的項目使用less來寫樣式…

低代碼開發——企業轉型的萬金油

在數字化時代&#xff0c;企業面臨著日新月異的市場環境和激烈的競爭壓力。為了在這場變革中脫穎而出&#xff0c;企業需要不斷優化業務流程、提升創新能力&#xff0c;以及實現敏捷響應。在這個過程中&#xff0c;低代碼開發作為一種創新性的技術手段&#xff0c;正成為企業轉…

統信UOS_麒麟KYLINOS上監控網絡:探索Smokeping的強大功能

原文鏈接&#xff1a;統信UOS|麒麟KYLINOS上監控網絡&#xff1a;探索Smokeping的強大功能 在當今的網絡環境中&#xff0c;無論是個人用戶還是企業用戶&#xff0c;都非常重視網絡的穩定性和連通性。特別是在進行遠程工作、在線會議、云計算等活動時&#xff0c;網絡質量直接影…

程序員必備技能----刪庫跑路大總結

刪庫跑路大總結&#xff0c;各個都是大殺器&#xff0c;破壞性太大&#xff0c;輕易不要嘗試。 刪除linux根目錄&#xff0c;用戶目錄&#xff0c;其實還可以增加一個刪除/etc。刪除&#xff08;清除&#xff09;數據庫。刪除redis緩存和持久化文件。刪除mongodb庫。git push …

說一說Eclipse的項目類型和常用項目的區別

Eclipse在新建項目的時候有很多類型&#xff0c;包括Java project、Web project等等&#xff0c;如下&#xff1a; 那么這些項目類型有什么區別呢&#xff1f;我們在創建項目的時候應該如何選擇&#xff0c;了解清楚這一點還是非常重要的&#xff0c;但記住一個出發點&#xff…

2.22 day3、4 QT

完善對話框&#xff0c;點擊登錄對話框&#xff0c;如果賬號和密碼匹配&#xff0c;則彈出信息對話框&#xff0c;給出提示"登錄成功”&#xff0c;提供一個Ok按鈕&#xff0c;用戶點擊Ok后&#xff0c;關閉登錄界面&#xff0c;跳轉到其他界面 如果賬號和密碼不匹配&…

讀書筆記:《看電影學金融》

大空頭 禁止做空可以延緩資產價格下降的過程&#xff0c;但是人為保護的高股價最終還是不能持續的。做空引入的空頭買家&#xff0c;可以增加市場的流動性。住房價格指數期貨使房地產的投資屬性與住宅屬性分離&#xff0c;降低因炒房而空置的房屋&#xff0c;降低房價。收益互…