.NET 8 Web API 中的身份验证和授权
本次介绍分为3篇文章:
1:.Net 8 Web API CRUD 操作
.Net 8 Web API CRUD 操作-CSDN博客
2:在 .Net 8 API 中实现 Entity Framework 的 Code First 方法
https://blog.csdn.net/hefeng_aspnet/article/details/143229912
3:.NET 8 Web API 中的身份验证和授权
https://blog.csdn.net/hefeng_aspnet/article/details/143231987 
参考文章:
1:Dot Net 8 Web API CRUD 操作
https://medium.com/@codewithankitsahu/net-8-web-api-crud-operations-125bb3083113
2:在 .Net 8 API 中实现 Entity Framework 的 Code First 方法
https://medium.com/@codewithankitsahu/implement-entity-framework-a-code-first-approach-in-net-8-api-80b06d219373
3:.NET 8 Web API 中的身份验证和授权
https://medium.com/@codewithankitsahu/authentication-and-authorization-in-net-8-web-api-94dda49516ee
介绍
在本文中,我们将讨论如何在 .NET 8 Web API 中实现身份验证和授权。这是 .Net 8 系列的延续,所以如果你是新手,请查看我之前的文章。
身份验证和授权代表着根本不同的功能。在本文中,我们将对这两者进行比较和对比,以展示它们如何以互补的方式保护应用程序。
验证
身份验证就是了解用户的身份。
例如
Alice 使用她的用户名和密码登录,服务器使用该密码对 Alice 进行身份验证。
授权
授权就是决定是否允许用户采取行动。
例如
Alice 有权限获取资源,但无权创建资源。

让我们开始在我们的应用程序中实现 Jwt Bearer 令牌。
步骤 1.安装 Microsoft.AspNetCore.Authentication.JwtBearer
安装Microsoft.AspNetCore.Authentication.JwtBearer库以在我们的应用程序中实现 JWT 令牌。
为了这
- 前往 ne 获取包管理器。
- 在浏览选项卡中搜索“Microsoft.AspNetCore.Authentication.JwtBearer”。
- 选择适当的版本,然后单击“安装”按钮。

步骤2.添加Jwt中间件
在我们的应用中添加 Jwt 中间件。为此,请按照以下步骤操作。
- 在 API 解决方案中创建 Helpers 文件夹
- 添加一个名为“JwtMiddleware”的类
- 添加JwtMiddleware构造函数并在构造函数中注入RequestDelegate和AppSettings。
//JwtMiddleware.cs
 using DotNet8WebAPI.Model;
 using Microsoft.Extensions.Options;
namespace DotNet8WebAPI.Helpers
 {
     public class JwtMiddleware
     {
         private readonly RequestDelegate _next;
         private readonly AppSettings _appSettings;
        public JwtMiddleware(RequestDelegate next, IOptions<AppSettings> appSettings)
         {
             _next = next;
             _appSettings = appSettings.Value;
         }
     }
 }
- 实现Invoke方法
- 在invoke方法中,从当前请求中读取授权令牌并转发给attachUserToContext方法进行验证,提取用户信息并附加到当前请求。
//JwtMiddleware.cs
 using DotNet8WebAPI.Model;
 using DotNet8WebAPI.Services;
 using Microsoft.Extensions.Options;
 using Microsoft.IdentityModel.Tokens;
 using System.IdentityModel.Tokens.Jwt;
 using System.Text;
 namespace DotNet8WebAPI.Helpers
 {
 public class JwtMiddleware
 {
 private readonly RequestDelegate _next;
 private readonly AppSettings _appSettings;
 public JwtMiddleware(RequestDelegate next, IOptions<AppSettings> appSettings)
 {
 _next = next;
 _appSettings = appSettings.Value;
 }
 public async Task Invoke(HttpContext context, IUserService userService)
 {
 var token = context.Request.Headers["Authorization"].FirstOrDefault()?.Split(" ").Last();
 if (token != null)
 await attachUserToContext(context, userService, token);
 await _next(context);
 }
 private async Task attachUserToContext(HttpContext context, IUserService userService, string token)
 {
 try
 {
 var tokenHandler = new JwtSecurityTokenHandler();
 var key = Encoding.ASCII.GetBytes(_appSettings.Secret);
 tokenHandler.ValidateToken(token, new TokenValidationParameters
 {
 ValidateIssuerSigningKey = true,
 IssuerSigningKey = new SymmetricSecurityKey(key),
 ValidateIssuer = false,
 ValidateAudience = false,
 // set clock skew to zero so tokens expire exactly at token expiration time (instead of 5 minutes later)
 ClockSkew = TimeSpan.Zero
 }, out SecurityToken validatedToken);
 var jwtToken = (JwtSecurityToken)validatedToken;
 var userId = int.Parse(jwtToken.Claims.First(x => x.Type == "id").Value);
 //Attach user to context on successful JWT validation
 context.Items["User"] = await userService.GetById(userId);
 }
 catch
 {
 //Do nothing if JWT validation fails
 // user is not attached to context so the request won't have access to secure routes
 }
 }
 }
 } 
- 将我们的“JwtMiddleware”添加到我们的应用程序中
- 为此,请转到 Program.cs 并添加它。
app.UseMiddleware<JwtMiddleware>();<JwtMiddleware>();
步骤 3.实现 UserService
实现 UserService。我将帮助注册新用户。
//IUserService.cs
 using DotNet8WebAPI.Model;
 namespace DotNet8WebAPI.Services
 {
 public interface IUserService
 {
 Task<AuthenticateResponse?> Authenticate(AuthenticateRequest model);
 Task<IEnumerable<User>> GetAll();
 Task<User?> GetById(int id);
 Task<User?> AddAndUpdateUser(User userObj);
 }
 } 
//UserService.cs
 using DotNet8WebAPI.Model;
 using Microsoft.EntityFrameworkCore;
 using Microsoft.Extensions.Options;
 using Microsoft.IdentityModel.Tokens;
 using System.IdentityModel.Tokens.Jwt;
 using System.Security.Claims;
 using System.Text;
 namespace DotNet8WebAPI.Services
 {
 public class UserService : IUserService
 {
 private readonly AppSettings _appSettings;
 private readonly OurHeroDbContext db;
 public UserService(IOptions<AppSettings> appSettings, OurHeroDbContext _db)
 {
 _appSettings = appSettings.Value;
 db = _db;
 }
 public async Task<AuthenticateResponse?> Authenticate(AuthenticateRequest model)
 {
 var user = await db.Users.SingleOrDefaultAsync(x => x.Username == model.Username && x.Password == model.Password);
 // return null if user not found
 if (user == null) return null;
 // authentication successful so generate jwt token
 var token = await generateJwtToken(user);
 return new AuthenticateResponse(user, token);
 }
 public async Task<IEnumerable<User>> GetAll()
 {
 return await db.Users.Where(x => x.isActive == true).ToListAsync();
 }
 public async Task<User?> GetById(int id)
 {
 return await db.Users.FirstOrDefaultAsync(x => x.Id == id);
 }
 public async Task<User?> AddAndUpdateUser(User userObj)
 {
 bool isSuccess = false;
 if (userObj.Id > 0)
 {
 var obj = await db.Users.FirstOrDefaultAsync(c => c.Id == userObj.Id);
 if (obj != null)
 {
 // obj.Address = userObj.Address;
 obj.FirstName = userObj.FirstName;
 obj.LastName = userObj.LastName;
 db.Users.Update(obj);
 isSuccess = await db.SaveChangesAsync() > 0;
 }
 }
 else
 {
 await db.Users.AddAsync(userObj);
 isSuccess = await db.SaveChangesAsync() > 0;
 }
 return isSuccess ? userObj: null;
 }
 // helper methods
 private async Task<string> generateJwtToken(User user)
 {
 //Generate token that is valid for 7 days
 var tokenHandler = new JwtSecurityTokenHandler();
 var token = await Task.Run(() =>
 {
 var key = Encoding.ASCII.GetBytes(_appSettings.Secret);
 var tokenDescriptor = new SecurityTokenDescriptor
 {
 Subject = new ClaimsIdentity(new[] { new Claim("id", user.Id.ToString()) }),
 Expires = DateTime.UtcNow.AddDays(7),
 SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(key), SecurityAlgorithms.HmacSha256Signature)
 };
 return tokenHandler.CreateToken(tokenDescriptor);
 });
 return tokenHandler.WriteToken(token);
 }
 }
 }
步骤 4. 添加相应的类模型
在模型文件夹内添加相应的类模型。
//User.cs
 using System.Text.Json.Serialization;
 namespace DotNet8WebAPI.Model
 {
 public class User
 {
 public int Id { get; set; }
 public required string FirstName { get; set; }
 public string LastName { get; set; }
 public required string Username { get; set; }
 [JsonIgnore]
 public string Password { get; set; }
 public bool isActive { get; set; }
 }
 } 
//AuthenticateRequest.cs
 using System.ComponentModel;
 namespace DotNet8WebAPI.Model
 {
 public class AuthenticateRequest
 {
 [DefaultValue("System")]
 public required string Username { get; set; }
 [DefaultValue("System")]
 public required string Password { get; set; }
 }
 } 
//AuthenticateResponse.cs
 namespace DotNet8WebAPI.Model
 {
 public class AuthenticateResponse
 {
 public int Id { get; set; }
 public string FirstName { get; set; }
 public string LastName { get; set; }
 public string Username { get; set; }
 public string Token { get; set; }
 public AuthenticateResponse(User user, string token)
 {
 Id = user.Id;
 FirstName = user.FirstName;
 LastName = user.LastName;
 Username = user.Username;
 Token = token;
 }
 }
 } 
//AppSettings.cs
 namespace DotNet8WebAPI.Model
 {
 public class AppSettings
 {
 public string Secret { get; set; } = string.Empty;
 }
 } 
步骤 5. 转到 OurHeroDbContext 文件
转到 OurHeroDbContext 文件并将用户添加为 DBSet。
public DbSet<User> Users { get; set; }
//OurHeroDbContext.cs
 using DotNet8WebAPI.Model;
 using Microsoft.EntityFrameworkCore;
 namespace DotNet8WebAPI
 {
 public class OurHeroDbContext : DbContext
 {
 public OurHeroDbContext(DbContextOptions<OurHeroDbContext> options) : base(options)
 {
 }
 public DbSet<OurHero> OurHeros { get; set; }
 public DbSet<User> Users { get; set; }
 protected override void OnModelCreating(ModelBuilder modelBuilder)
 {
 modelBuilder.Entity<OurHero>().HasKey(x => x.Id);
 modelBuilder.Entity<OurHero>().HasData(
 new OurHero
 {
 Id = 1,
 FirstName = "System",
 LastName = "",
 isActive = true,
 }
 );
 modelBuilder.Entity<User>().HasData(
 new User
 {
 Id = 1,
 FirstName = "System",
 LastName = "",
 Username = "System",
 Password = "System",
 }
 );
 }
 }
 } 
步骤 6.添加 JWT 密钥
在应用程序设置文件中添加 JWT Secret。
"AppSettings": {
 "Secret": "THIS IS USED TO SIGN AND VERIFY JWT TOKENS, REPLACE IT WITH YOUR OWN SECRET, IT CAN BE ANY STRING"
 }, 
//appsettings.json
 {
 "Logging": {
 "LogLevel": {
 "Default": "Information",
 "Microsoft.AspNetCore": "Warning"
 }
 },
 "AppSettings": {
 "Secret": "THIS IS USED TO SIGN AND VERIFY JWT TOKENS, REPLACE IT WITH YOUR OWN SECRET, IT CAN BE ANY STRING"
 },
 "ConnectionStrings": {
 "OurHeroConnectionString": "Data Source=LAPTOP-4TSM9SDC;Initial Catalog=OurHeroDB; Integrated Security=true;TrustServerCertificate=True;"
 },
 "AllowedHosts": "*"
 } 
步骤 7.注册 AppSettings 和 UserServices
在应用程序中注册AppSettings和UserServices。
转到 Program.cs 文件并注册我们的服务。
//Program.cs
 builder.Services.Configure<AppSettings>(builder.Configuration.GetSection("AppSettings"));
 builder.Services.AddScoped<IUserService, UserService>(); 
步骤 8. 运行以下命令
运行以下命令来添加迁移并更新数据库。
- 运行add-migration [名称]
- 更新数据库
步骤 9.实现 AuthorizeAttribute
实现 AuthorizeAttribute 来保护我们并指向匿名用途。
- 在Helpers文件夹中添加AuthorizeAttribute类。
- 此类与Attribute和IAuthorizationFilter 的关联范围。
- 实现 OnAuthorization 方法。
//AuthorizeAttribute.cs
 using DotNet8WebAPI.Model;
 using Microsoft.AspNetCore.Mvc.Filters;
 using Microsoft.AspNetCore.Mvc;
namespace DotNet8WebAPI.Helpers
 {
     [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
     public class AuthorizeAttribute : Attribute, IAuthorizationFilter
     {
         public void OnAuthorization(AuthorizationFilterContext context)
         {
             var user = (User?)context.HttpContext.Items["User"];
             if (user == null)
             {
                 context.Result = new JsonResult(new { message = "Unauthorized" }) { StatusCode = StatusCodes.Status401Unauthorized };
             }
         }
     }
 }
步骤 10. 应用 AuthorizeAttribute
根据您的需求,在控制器级别或 Action 方法级别应用AuthorizeAttribute 。
using DotNet8WebAPI.Helpers;
 using DotNet8WebAPI.Model;
 using DotNet8WebAPI.Services;
 using Microsoft.AspNetCore.Mvc;
namespace DotNet8WebAPI.Controllers
 {
     [Route("api/[controller]")]
     [ApiController] // Controller level
     [Authorize]
     public class OurHeroController : ControllerBase
     {
         private readonly IOurHeroService _heroService;
         public OurHeroController(IOurHeroService heroService)
         {
             _heroService = heroService;
         }
        //[ApiController]  // Action method level
         [HttpGet]
         public async Task<IActionResult> Get([FromQuery] bool? isActive = null)
         {
             var heros = await _heroService.GetAllHeros(isActive);
             return Ok(heros);
         }
        [HttpGet("{id}")]
         //[Route("{id}")] // /api/OurHero/:id
         public async Task<IActionResult> Get(int id)
         {
             var hero = await _heroService.GetHerosByID(id);
             if (hero == null)
             {
                 return NotFound();
             }
             return Ok(hero);
         }
        [HttpPost]
         public async Task<IActionResult> Post([FromBody] AddUpdateOurHero heroObject)
         {
             var hero = await _heroService.AddOurHero(heroObject);
            if (hero == null)
             {
                 return BadRequest();
             }
            return Ok(new
             {
                 message = "Super Hero Created Successfully!!!",
                 id = hero!.Id
             });
         }
        [HttpPut]
         [Route("{id}")]
         public async Task<IActionResult> Put([FromRoute] int id, [FromBody] AddUpdateOurHero heroObject)
         {
             var hero = await _heroService.UpdateOurHero(id, heroObject);
             if (hero == null)
             {
                 return NotFound();
             }
            return Ok(new
             {
                 message = "Super Hero Updated Successfully!!!",
                 id = hero!.Id
             });
         }
        [HttpDelete]
         [Route("{id}")]
         public async Task<IActionResult> Delete([FromRoute] int id)
         {
             if (!await _heroService.DeleteHerosByID(id))
             {
                 return NotFound();
             }
            return Ok(new
             {
                 message = "Super Hero Deleted Successfully!!!",
                 id = id
             });
         }
     }
 }
//UsersController.cs
 using DotNet8WebAPI.Helpers;
 using DotNet8WebAPI.Model;
 using DotNet8WebAPI.Services;
 using Microsoft.AspNetCore.Mvc;
namespace DotNet8WebAPI.Controllers
 {
     [Route("api/[controller]")] //    /api/Users
     [ApiController]
     public class UsersController : ControllerBase
     {
         private IUserService _userService;
        public UsersController(IUserService userService)
         {
             _userService = userService;
         }
        [HttpPost("authenticate")]
         public async Task<IActionResult> Authenticate(AuthenticateRequest model)
         {
             var response = await _userService.Authenticate(model);
            if (response == null)
                 return BadRequest(new { message = "Username or password is incorrect" });
            return Ok(response);
         }
        // POST api/<CustomerController>
         [HttpPost]
         [Authorize]
         public async Task<IActionResult> Post([FromBody] User userObj)
         {
             userObj.Id = 0;
             return Ok(await _userService.AddAndUpdateUser(userObj));
         }
        // PUT api/<CustomerController>/5
         [HttpPut("{id}")]
         [Authorize]
         public async Task<IActionResult> Put(int id, [FromBody] User userObj)
         {
             return Ok(await _userService.AddAndUpdateUser(userObj));
         }
     }
 }
步骤11.API安全性
现在我们的 API 对于未经身份验证的用户来说是安全的。
但是如果您想使用 Swagger 测试我们的 API,那么我们需要接受 Bearer 令牌。
转到 Program.cs 文件并实现它。
builder.Services.AddSwaggerGen(swagger =>Services.AddSwaggerGen(swagger =>
 {
     //This is to generate the Default UI of Swagger Documentation
     swagger.SwaggerDoc("v1", new OpenApiInfo
     {
         Version = "v1",
         Title = "JWT Token Authentication API",
         Description = ".NET 8 Web API"
     });
     // To Enable authorization using Swagger (JWT)
     swagger.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme()
     {
         Name = "Authorization",
         Type = SecuritySchemeType.ApiKey,
         Scheme = "Bearer",
         BearerFormat = "JWT",
         In = ParameterLocation.Header,
         Description = "JWT Authorization header using the Bearer scheme. \r\n\r\n Enter 'Bearer' [space] and then your token in the text input below.\r\n\r\nExample: \"Bearer 12345abcdef\"",
     });
     swagger.AddSecurityRequirement(new OpenApiSecurityRequirement
                 {
                     {
                           new OpenApiSecurityScheme
                             {
                                 Reference = new OpenApiReference
                                 {
                                     Type = ReferenceType.SecurityScheme,
                                     Id = "Bearer"
                                 }
                             },
                             new string[] {}
                    }
                 });
 });
步骤 12. 运行 Web API
运行 Web API(按 F5)并调用“/api/Users/authenticate” API。

步骤 13.复制 JWT 令牌

- 单击授权按钮,并在值部分提供令牌“ Bearer <token> ”。
- 然后点击授权按钮来验证 Web API。


步骤 14. 调用“/api/OurHero” API
现在,如果您调用“/api/OurHero” API,它将起作用,但如果没有 JWT 令牌,它将抛出401(未授权)错误。
- 使用 JWT 令牌 — 工作正常。

没有 JWT 令牌 — 抛出401错误。

概括
就这样!您已经创建了一个完整的 .NET 8 Web API,用于使用内存数据库和 JWT 身份验证进行 CRUD 操作。您现在可以将此 API 集成到您的前端应用程序中。
相关文章:
 
.NET 8 Web API 中的身份验证和授权
本次介绍分为3篇文章: 1:.Net 8 Web API CRUD 操作.Net 8 Web API CRUD 操作-CSDN博客 2:在 .Net 8 API 中实现 Entity Framework 的 Code First 方法https://blog.csdn.net/hefeng_aspnet/article/details/143229912 3:.NET …...
Vue弹窗用也可以直接调用Js方法了
问题描述 在前端开发中,弹窗开发是一个不可避免的场景。然而,按照正常的逻辑,通过在template模板中先引用组件,然后通过v-if指令控制显隐,进而达到弹窗的效果。然而,这种方法却有一个严重的缺陷࿰…...
【c语言测试】
1. C语言中,逻辑“真”等价于( ) 题目分析: “逻辑真”在C语言中通常指的是非零数。 A. 大于零的数B. 大于零的整数C. 非零的数 (正确答案)D. 非零的整数 正确答案:C 2. 若定义了数组 int a[3][4];,则对…...
 
一种将树莓派打造为游戏机的方法——Lakka
什么是Lakka? Lakka是一款Linux发行版,轻量级的,可将小型计算机转变为一台复古游戏机。 图1-Lakka官网,见参考链接[1] Lakka是RetroArch和libretro生态系统下的官方操作系统,前者RetroArch是模拟器、游戏引擎和媒体播…...
如何在 MySQL 中创建一个完整的数据库备份?
在MySQL数据库中创建一个完整的数据库备份通常不是通过编程语言直接实现的,而是借助MySQL提供的命令行工具mysqldump来完成。 作为Java开发者,我们可以编写脚本来调用这些工具,从而实现自动化备份。 下面我们将详细介绍如何使用Java来调度m…...
京准电钟HR-901GB双GPS北斗卫星时钟服务器
京准电钟HR-901GB双GPS北斗卫星时钟服务器 京准电钟HR-901GB双GPS北斗卫星时钟服务器 作为国家电力系统最重要的设备之一,卫星时间同步装置随着电力行业的发展不断有了新的要求,从单纯的具备时间数据输出能力,发展到装置状态信息上送、对用时设备的对时质量进行监测,确保站点内…...
uniapp使用websocket
后端java websoket中的 onOpen 中。依赖注入为null 引用:https://blog.csdn.net/qq_63431773/article/details/132389555 https://blog.csdn.net/weixin_43961117/article/details/123989515 https://cloud.tencent.com/developer/article/2107954 https://blog.c…...
 
基于Pycharm和Django模型技术的数据迁移
1.配置数据库 在trip_server/settings.py中修改配置: 其格式可访问官网:Settings | Django documentation | Django 1.1 配置数据库 文件地址:trip_server/settings.py 配置前需要创建(NaviCat)个人数据库 "…...
 
乐尚代驾-----Day10(订单三)
hi UU 们!!!我又来跟辛辣!感谢你们的观看,话不多说!~ 司机到达代驾终点,代驾结束了。结束代驾之后, – 获取额外费用(高速费、停车费等) – 计算订单实际里程…...
 
105. 聚光源SpotLight
入门部分给大家介绍过平行光DirectionalLight、点光源PointLight、环境光AmbientLight,下面给大家介绍一个新的光源对象,也就是聚光源SpotLight。 创建聚光源SpotLight 聚光源可以认为是一个沿着特定方会逐渐发散的光源,照射范围在三维空间中构成一个圆…...
系统接口权限拦截器,获取用户信息存储
UserInfo 类 这是一个表示用户信息的 Java 类,使用了 Lombok 注解来简化代码编写。 import lombok.Data; import lombok.EqualsAndHashCode; import lombok.ToString;import java.io.Serializable; import java.util.List;Data ToString EqualsAndHashCode public…...
Chromium HTML5 新的 Input 类型color 对应c++
一、Input 类型: color color 类型用在input字段主要用于选取颜色,如下所示: <!DOCTYPE html> <html> <head> <meta charset"utf-8"> <title>菜鸟教程(runoob.com)</title> </head> <body&…...
问:SQL中的通用函数及用法?
SQL函数是在SQL语句中使用的预定义的计算工具,可以对一列数据进行操作并返回一个单一的结果。这些函数大致可以分为两类:Aggregate函数和Scalar函数。Aggregate函数对一组值执行计算,并返回单个值,如求和、平均值、最大值和最小值…...
 
.NET Core WebApi第6讲:WebApi的前端怎么派人去拿数据?(区别MVC)
一、前端界面小基础 head:引入CSS, 引入JS是写在head里面。 body:眼睛肉眼能看到的用户展示的界面是写在body里面。 二、前端怎么派人去拿数据? 1、MVC:前后端不分离,MVC相比WebApi只是多了一个views的文件夹 &am…...
Chromium HTML5 新的 Input 类型date 对应c++
一、Input 类型: date date 类型允许你从一个日期选择器选择一个日期。 <!DOCTYPE html> <html> <head> <meta charset"utf-8"> <title>test</title> </head> <body><form action"demo-form.php"…...
ZooKeeper的应用场景:深入探讨分布式系统中的多样化应用
Apache ZooKeeper 是一个开源的分布式协调服务,专为确保分布式系统中的高可用性和一致性而设计。在现代分布式应用程序中,协调、同步和管理是实现高效和可靠服务的关键部分,而 ZooKeeper 通过提供这些基础功能而成为许多分布式系统不可或缺的…...
 
【Vue3】第四篇
Vue3学习第四篇 01. 插槽Slots02. 插槽Slots(续集)03. 插槽Slots(再续集)04. 组件生命周期05. 生命周期应用06. 动态组件07. 组件保持存活08. 异步组件09. 依赖注入10. Vue应用 01. 插槽Slots 模板内容:html结构&#…...
 
Chromium HTML5 新的 Input 类型tel对应c++
一、Input 类型: tel <!DOCTYPE html> <html> <head> <meta charset"utf-8"> <title>test</title> </head> <body><form action"demo-form.php">电话号码: <input type"tel" name…...
 
JVM—类加载器、双亲委派机制
目录 什么是类加载器 类加载器的分类 Bootstrap启动类加载器 通过启动类加载器加载用户jar包 Extension扩展类加载器和Application应用程序类加载器 通过扩展类加载器加载用户jar包 双亲委派机制 打破双亲委派机制 自定义类加载器 线程上下文类加载器 Osgi框架的类加…...
笔试题 求空格分割的英文句子中,最大单词长度。
求空格分割的英文句子中,最大单词长度。例如:“this is a word”,最大单词长度为4。要求:不能用 split 函数对字符串进行切分,算法复杂度为o(n) public class MaxWordLength { public static int maxWordLength(String sentence) { if (se…...
 
python打卡day49
知识点回顾: 通道注意力模块复习空间注意力模块CBAM的定义 作业:尝试对今天的模型检查参数数目,并用tensorboard查看训练过程 import torch import torch.nn as nn# 定义通道注意力 class ChannelAttention(nn.Module):def __init__(self,…...
Golang 面试经典题:map 的 key 可以是什么类型?哪些不可以?
Golang 面试经典题:map 的 key 可以是什么类型?哪些不可以? 在 Golang 的面试中,map 类型的使用是一个常见的考点,其中对 key 类型的合法性 是一道常被提及的基础却很容易被忽视的问题。本文将带你深入理解 Golang 中…...
Cesium1.95中高性能加载1500个点
一、基本方式: 图标使用.png比.svg性能要好 <template><div id"cesiumContainer"></div><div class"toolbar"><button id"resetButton">重新生成点</button><span id"countDisplay&qu…...
 
Docker 运行 Kafka 带 SASL 认证教程
Docker 运行 Kafka 带 SASL 认证教程 Docker 运行 Kafka 带 SASL 认证教程一、说明二、环境准备三、编写 Docker Compose 和 jaas文件docker-compose.yml代码说明:server_jaas.conf 四、启动服务五、验证服务六、连接kafka服务七、总结 Docker 运行 Kafka 带 SASL 认…...
 
如何将联系人从 iPhone 转移到 Android
从 iPhone 换到 Android 手机时,你可能需要保留重要的数据,例如通讯录。好在,将通讯录从 iPhone 转移到 Android 手机非常简单,你可以从本文中学习 6 种可靠的方法,确保随时保持连接,不错过任何信息。 第 1…...
【RockeMQ】第2节|RocketMQ快速实战以及核⼼概念详解(二)
升级Dledger高可用集群 一、主从架构的不足与Dledger的定位 主从架构缺陷 数据备份依赖Slave节点,但无自动故障转移能力,Master宕机后需人工切换,期间消息可能无法读取。Slave仅存储数据,无法主动升级为Master响应请求ÿ…...
 
IT供电系统绝缘监测及故障定位解决方案
随着新能源的快速发展,光伏电站、储能系统及充电设备已广泛应用于现代能源网络。在光伏领域,IT供电系统凭借其持续供电性好、安全性高等优势成为光伏首选,但在长期运行中,例如老化、潮湿、隐裂、机械损伤等问题会影响光伏板绝缘层…...
 
华为云Flexus+DeepSeek征文|DeepSeek-V3/R1 商用服务开通全流程与本地部署搭建
华为云FlexusDeepSeek征文|DeepSeek-V3/R1 商用服务开通全流程与本地部署搭建 前言 如今大模型其性能出色,华为云 ModelArts Studio_MaaS大模型即服务平台华为云内置了大模型,能助力我们轻松驾驭 DeepSeek-V3/R1,本文中将分享如何…...
 
STM32HAL库USART源代码解析及应用
STM32HAL库USART源代码解析 前言STM32CubeIDE配置串口USART和UART的选择使用模式参数设置GPIO配置DMA配置中断配置硬件流控制使能生成代码解析和使用方法串口初始化__UART_HandleTypeDef结构体浅析HAL库代码实际使用方法使用轮询方式发送使用轮询方式接收使用中断方式发送使用中…...
多模态图像修复系统:基于深度学习的图片修复实现
多模态图像修复系统:基于深度学习的图片修复实现 1. 系统概述 本系统使用多模态大模型(Stable Diffusion Inpainting)实现图像修复功能,结合文本描述和图片输入,对指定区域进行内容修复。系统包含完整的数据处理、模型训练、推理部署流程。 import torch import numpy …...
