当前位置: 首页 > news >正文

WebApi配置Swagger、Serilog、NewtonsoftJson、Sqlsugar、依赖注入框架Autofac、MD5加密

文章目录

  • 项目准备
    • 1、创建WebApi项目
    • 配置Swagger、Serilog、NewtonsoftJson
      • NewtonsoftJson
      • Swagger
      • Serilog
    • 使用ORM框架`SqlSugar`
    • 创建Service类库构成MVC框架
    • 使用AutoFac进行依赖注入
  • 创建用户登录接口
      • 添加用户时进行安全防护

项目准备

1、创建WebApi项目

配置Swagger、Serilog、NewtonsoftJson

NewtonsoftJson

引入Microsoft.AspNetCore.Mvc.NewtonsoftJson的包

编写配置代码,在启动类中使用Program

/*Json格式化*/
builder.Services.AddControllers().AddNewtonsoftJson(options =>
{options.SerializerSettings.ContractResolver = new DefaultContractResolver();options.SerializerSettings.DateFormatString = "yyyy-MM-dd HH:mm:ss";
});

Swagger

使用扩展的方式进行swagger注释的配置

using System.Reflection;
using Microsoft.OpenApi.Models;
using noteVersion.utils;namespace noteVersion.ExtTool;public static class SwaggerExt
{/// <summary>/// 添加Swagger扩展/// </summary>public static void AddSwaggerExt(this IServiceCollection services){services.AddSwaggerGen(c =>{/*版本控制*/typeof(ApiVersion).GetEnumNames().ToList().ForEach(version =>{c.SwaggerDoc(version, new OpenApiInfo { Title = "NoteVersion Api", Version = version });});/*添加注释*/var xmlFile = $"{Assembly.GetEntryAssembly().GetName().Name}.xml";var xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile);c.IncludeXmlComments(xmlPath);});}/// <summary>/// 使用Swagger扩展/// </summary>public static void UseSwaggerExt(this WebApplication application){application.UseSwagger();application.UseSwaggerUI(c =>{foreach (var item in typeof(ApiVersion).GetEnumNames()){c.SwaggerEndpoint($"/swagger/{item}/swagger.json", $"WebAread Api {item}版本");}});}
}

在启动类中使用Program

//注册扩展
builder.Services.AddSwaggerExt();
//使用扩展
app.UseSwaggerExt();

在项目的属性文件里配置开启文档生成projrct.csproj

<GenerateDocumentationFile>True</GenerateDocumentationFile>

Serilog

下载Serilog.AspNetCore

编写log扩展(依赖注入方式使用插件,还有配置文件方式等)

using Serilog;
using Serilog.Events;namespace noteVersion.ExtTool;public static class SerilogExt
{public static void AddSerilogExt(this WebApplicationBuilder builder){builder.Services.AddSerilog(cfg =>{cfg.MinimumLevel.Information().WriteTo.File("Logs/log.txt", rollingInterval: RollingInterval.Day, restrictedToMinimumLevel: LogEventLevel.Information).WriteTo.File("Logs/Errors/log.txt", rollingInterval: RollingInterval.Day, restrictedToMinimumLevel: LogEventLevel.Error);});}
}

在Program里注册Serilog

builder.AddSerilogExt();

使用在Controller类里

using Microsoft.AspNetCore.Mvc;namespace noteVersion.Controllers;
/// <summary>
/// 用户
/// </summary>
[ApiController]
[Route("[Controller]/[Action]")]
public class UserController : ControllerBase
{private readonly ILogger<UserController> _logger;private int a = 27;public UserController(ILogger<UserController> logger){_logger = logger;}/// <summary>/// 测试/// </summary>/// <returns></returns>[HttpGet]public async Task<IActionResult> Test(){_logger.LogInformation($"{typeof(UserController).FullName}:{nameof(Test)}\n log测试{a}");return Ok("测试成功");}
}

使用ORM框架SqlSugar

下载SqlSugarCore

编写json连接字符串在appsettings.json

 "SqlSugar": {"ConnectString": "server = 127.0.0.1; Database = test; Uid = root; Pwd = root; AllowLoadLocalInfile = true;"},

创建Helper类库进行sqlsugar配置

由于Sqlsugar官方网站建议不要让SqlClient进行上下文的联动,所以一个块里new一个Sqlclient。

于是我使用传参的方式进行实例化时的配置。

using Microsoft.Extensions.Configuration;
using SqlSugar;namespace WebReadSite.DataAccess;
public class DbContext
{private readonly IConfiguration _configuration;private SqlSugarClient _dbClient;public DbContext(IConfiguration configuration){_configuration = configuration;InitializeDatabase();}private void InitializeDatabase(){string connectionString = _configuration["SqlSugar:ConnectString"];_dbClient = new SqlSugarClient(new ConnectionConfig(){ConnectionString = connectionString,DbType = DbType.MySql,IsAutoCloseConnection = true});}public SqlSugarClient GetDbClient(){return _dbClient;}
}

创建Models类库进行数据实体的配置

using SqlSugar;namespace Models;[SugarTable(tableName: "Users")]
public class User
{[SugarColumn(IsPrimaryKey = true)] public string USERID { get; set; }public string USERNAME { get; set; }public string EMAIL { get; set; }public string PASSWORD { get; set; }public DateTime CREATEAT { get; set; }public DateTime UPDATEAT { get; set; }
}

Controller类中使用Sqlsugar

使用IConfiguration读取Json配置,在方法里使用SqlClient执行插入

using Microsoft.AspNetCore.Mvc;
using Models;
using SqlSugar;
using WebReadSite.DataAccess;namespace noteVersion.Controllers;
/// <summary>
/// 用户
/// </summary>
[ApiController]
[Route("[Controller]/[Action]")]
public class UserController : ControllerBase
{private readonly ILogger<UserController> _logger;IConfiguration configuration = new ConfigurationBuilder().AddJsonFile("appsettings.json", optional: true, reloadOnChange: true).Build();public UserController(ILogger<UserController> logger){_logger = logger;}/// <summary>/// 测试/// </summary>/// <returns></returns>[HttpGet]public async Task<IActionResult> Test(){DbContext dbContext = new DbContext(configuration);SqlSugarClient dbClient = dbContext.GetDbClient();dbClient.Insertable(new User() { USERID = Guid.NewGuid().ToString(), USERNAME = "jack" }).ExecuteCommand();_logger.LogInformation($"{typeof(UserController).FullName}:{nameof(Test)}\n log测试");return Ok("测试成功");}
}

创建Service类库构成MVC框架

创建IServiceService类库

使用AutoFac进行依赖注入

安装Autofac包和Autofac.Extensions.DependencyInjection

创建Autofac扩展

using System.Reflection;
using Autofac;
using Autofac.Extensions.DependencyInjection;namespace noteVersion.ExtTool;public static class AutofacExt
{/// <summary>/// Autofac使用dll注入/// </summary>/// <param name="builder"></param>/// <exception cref="Exception"></exception>public static void AddAutofac(this WebApplicationBuilder builder){var basePath = AppContext.BaseDirectory;var servicesDllFile = Path.Combine(basePath, "noteVersion.Service.dll"); //服务层if (!(File.Exists(servicesDllFile) && File.Exists(servicesDllFile))){throw new Exception("service.dll 丢失,因为项目解耦了,所以需要先F6编译,再F5运行,请检查 bin 文件夹,并拷贝。");}//使用IOC工厂类builder.Host.UseServiceProviderFactory(new AutofacServiceProviderFactory());// 获取 Repository.dll 程序集服务,并注册var assemblysRepository = Assembly.LoadFrom(servicesDllFile);builder.Host.ConfigureContainer<ContainerBuilder>(build =>{build.RegisterAssemblyTypes(assemblysRepository).AsImplementedInterfaces().InstancePerDependency();});} 
}

Program进行注册

builder.AddAutofac();

使用在Controller中

注入了IUserManager类

using Microsoft.AspNetCore.Mvc;
using Models;
using Service;
using IService;
using WebReadSite.DataAccess;namespace noteVersion.Controllers;/// <summary>
/// 用户
/// </summary>
[ApiController]
[Route("[Controller]/[Action]")]
public class UserController : ControllerBase
{private readonly ILogger<UserController> _logger;private readonly IUserManager _userManager;private readonly IConfiguration _configuration = new ConfigurationBuilder().AddJsonFile("appsettings.json", optional: true, reloadOnChange: true).Build();/// <summary>/// 构造函数/// </summary>/// <param name="logger"></param>/// <param name="userManager"></param>public UserController(ILogger<UserController> logger,IUserManager userManager){_logger = logger;_userManager = userManager;}/// <summary>/// 测试/// </summary>/// <returns></returns>[HttpGet]public async Task<IActionResult> Test(){var dbContext = new DbContext(_configuration);var dbClient = dbContext.GetDbClient();await dbClient.Insertable(new User() { USERID = Guid.NewGuid().ToString(), USERNAME = "jack" }).ExecuteCommandAsync();_logger.LogInformation($"{typeof(UserController).FullName}:{nameof(Test)}\n log测试");return Ok("测试成功");}/// <summary>/// 添加用户/// </summary>/// <returns></returns>[HttpGet]public async Task<IActionResult> AddUser(string name, string email, string password){try{var result =await _userManager.CreateUser(name, email, password);return Ok(result);}catch (Exception e){Console.WriteLine(e);return BadRequest(e.Message);}}
}

创建用户登录接口

  1. 用户管理(User Management)
    • 这个模块负责用户账户的创建、修改和删除操作。它通常包括注册新用户、更新用户信息、重置密码等功能。

Service类库下的UserManager

using System.Runtime.InteropServices.JavaScript;
using IService;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;
using Models;
using WebReadSite.DataAccess;namespace Service;public class UserManager : IUserManager
{private readonly ILogger<UserManager> _logger;IConfiguration configuration = new ConfigurationBuilder().AddJsonFile("appsettings.json", optional: true, reloadOnChange: true).Build();public UserManager(ILogger<UserManager> logger){_logger = logger;}public UserManager(){}/// <summary>/// 创建用户/// </summary>public async Task<int> CreateUser(string name, string email, string password){var dbContext = new DbContext(configuration);var dbClient = dbContext.GetDbClient();try{await dbClient.BeginTranAsync();var result = await dbClient.Insertable(new User(){USERID = Guid.NewGuid().ToString(),USERNAME = name, EMAIL = email, PASSWORD = password,CREATEAT = DateTime.Now}).ExecuteCommandAsync();await dbClient.CommitTranAsync();return result;}catch (Exception e){_logger.LogInformation($"{typeof(UserManager).FullName}-{nameof(CreateUser)}:{e.Message}");await dbClient.RollbackTranAsync(); //数据回滚throw new Exception("创建用户失败");}}public void UpdateUser(){try{}catch (Exception e){_logger.LogInformation($"{typeof(UserManager).FullName}-{nameof(CreateUser)}:{e.Message}");throw;}}public void DeleteUser(){try{}catch (Exception e){_logger.LogInformation($"{typeof(UserManager).FullName}-{nameof(CreateUser)}:{e.Message}");throw;}}
}

在Controller中使用(同上上)

 /// <summary>/// 添加用户/// </summary>/// <returns></returns>[HttpGet]public async Task<IActionResult> AddUser(string name, string email, string password){try{var result =await _userManager.CreateUser(name, email, password);return Ok(result);}catch (Exception e){Console.WriteLine(e);return BadRequest(e.Message);}}

添加用户时进行安全防护

使用Post传输且用body传输

/// <summary>/// 添加用户/// </summary>/// <returns></returns>[HttpPost]public async Task<IActionResult> AddUser(UserInfo userInfo){try{var result =await _userManager.CreateUser(userInfo.name, userInfo.email, userInfo.password);return Ok(result);}catch (Exception e){Console.WriteLine(e);return BadRequest(e.Message);}}

*添加MD5加密,之后保存进数据库UserManager*类

 /// <summary>/// 创建用户/// </summary>public async Task<int> CreateUser(string name, string email, string password){var dbContext = new DbContext(configuration);var dbClient = dbContext.GetDbClient();try{await dbClient.BeginTranAsync();var result = await dbClient.Insertable(new User(){USERID = Guid.NewGuid().ToString(),USERNAME = name, EMAIL = email, PASSWORD = GetMD5Encryption(password),CREATEAT = DateTime.Now}).ExecuteCommandAsync();await dbClient.CommitTranAsync();return result;}catch (Exception e){_logger.LogInformation($"{typeof(UserManager).FullName}-{nameof(CreateUser)}:{e.Message}");await dbClient.RollbackTranAsync(); //数据回滚throw new Exception("创建用户失败");}} /// <summary>/// 获取MD5算法字符串/// </summary>/// <param name="passWord"></param>/// <returns></returns>public string GetMD5Encryption(string passWord){// 创建一个 MD5 实例using (MD5 md5Hash = MD5.Create()){// 将输入字符串转换为字节数组,并计算哈希值byte[] data = md5Hash.ComputeHash(Encoding.UTF8.GetBytes(passWord));// 创建一个 StringBuilder 来收集字节并创建字符串StringBuilder sBuilder = new StringBuilder();// 将每个字节的哈希值转换为十六进制并追加到字符串构建器for (int i = 0; i < data.Length; i++){sBuilder.Append(data[i].ToString("x2")); // 使用 "x2" 格式化符将每个字节转换为十六进制}// 返回十六进制字符串return sBuilder.ToString();}}

TODO:用户登录后进行JWT校验,校验通过后进行单点登录,之后进行文件的上传、文件列表的获取

相关文章:

WebApi配置Swagger、Serilog、NewtonsoftJson、Sqlsugar、依赖注入框架Autofac、MD5加密

文章目录 项目准备1、创建WebApi项目配置Swagger、Serilog、NewtonsoftJsonNewtonsoftJsonSwaggerSerilog 使用ORM框架SqlSugar创建Service类库构成MVC框架使用AutoFac进行依赖注入 创建用户登录接口添加用户时进行安全防护 项目准备 1、创建WebApi项目 配置Swagger、Serilog…...

【ffmpeg命令基础】视频选项讲解

文章目录 前言设置输出文件的帧数设置每秒播放的帧数设置输出视频的帧率示例1&#xff1a;更改输出视频的帧率示例2&#xff1a;将图像序列转换为视频 设置输入视频的帧率示例3&#xff1a;处理高帧率视频示例4&#xff1a;处理低帧率视频 同时设置输入和输出帧率示例5&#xf…...

使用uniapp开发小程序(基础篇)

本文章只介绍微信小程序的开发流程&#xff0c;如果需要了解其他平台的开发的流程的话&#xff0c;后续根据情况更新相应的文章,也可以根据uniapp官网的链接了解不同平台的开发流程 HBuilderX使用&#xff1a;https://uniapp.dcloud.net.cn/quickstart-hx.html 开发工具 开始…...

vue3【详解】组合式函数

什么是组合式函数&#xff1f; 利用 Vue 的组合式 API 来封装和复用有状态逻辑的函数&#xff0c;用于实现逻辑复用&#xff0c;类似 react18 中的 hook 函数名称 – 以 use 开头&#xff0c;采用驼峰命名&#xff0c;如 useTitle参数 – 建议使用 toValue() 处理&#xff08;…...

微服务实战系列之玩转Docker(六)

前言 刚进入大暑&#xff0c;“清凉不肯来&#xff0c;烈日不肯暮”&#xff0c;空调开到晚&#xff0c;还是满身汗。——碎碎念 我们知道&#xff0c;仓库可见于不同领域&#xff0c;比如粮食仓库、数据仓库。在容器领域&#xff0c;自然也有镜像仓库&#xff08;registry&…...

Python题解Leetcode Hot100之动态规划

动态规划解题步骤-5部曲 确定dp数组&#xff08;dp table&#xff09;以及下标的含义确定递推公式dp数组如何初始化确定遍历顺序举例推导dp数组 70. 爬楼梯 题目描述 假设你正在爬楼梯。需要 n 阶你才能到达楼顶。每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到…...

你了解GD32 MCU上下电要求吗

你了解GD32 MCU的上下电要求吗&#xff1f;MCU的上下电对于系统的稳定运行非常重要。 以GD32F30X为例&#xff0c;上电/掉电复位波形如如下图所示。 上电过程中&#xff0c;VDD/VDDA电压上电爬坡&#xff0c;当电压高于VPOR&#xff08;上电复位电压&#xff09;MCU开始启动&a…...

二、【Python】入门 - 【PyCharm】安装教程

往期博主文章分享文章&#xff1a; 【机器学习】专栏http://t.csdnimg.cn/sQBvw 目录 第一步&#xff1a;PyCharm下载 第二步&#xff1a;安装&#xff08;点击安装包打开下图页面&#xff09; 第三步&#xff1a;科学使用&#xff0c;请前往下载最新工具及教程&#xff1a…...

2、程序设计语言基础知识

这一章节的内容在我们的软件设计师考试当中&#xff0c;考的题型比较固定&#xff0c;基本都是选择题&#xff0c;分值大概在2~4分左右。 而且考的还多是程序设计语言的一些基本语法&#xff0c;特别是这两年比较火的Python。 所以对于有一定要编程基础的即使本章的内容不学习&…...

ARM/Linux嵌入式面经(十八):TP-Link联洲

文章目录 虚拟内存,页表,copy on write面试题1:面试题2:面试题3:进程和线程的区别红黑树和b+树的应用红黑树的应用B+树的应用视频会议用了哪些协议1. H.323协议2. SIP协议(会话发起协议)3. WebRTC(网页实时通信)4. 其他协议io多路复用(select,poll,epoll)面试题li…...

解读vue3源码-响应式篇2

提示&#xff1a;看到我 请让我滚去学习 文章目录 vue3源码剖析reactivereactive使用proxy代理一个对象1.首先我们会走isObject(target)判断&#xff0c;我们reactive全家桶仅对对象类型有效&#xff08;对象、数组和 Map、Set 这样的集合类型&#xff09;&#xff0c;而对 str…...

【测开能力提升-fastapi框架】fastapi能力提升 - 中间件与CORS

1. 中间件 1.1 介绍&#xff08;ChatGPT抄的&#xff0c;大致可以理解&#xff09; 一种机制&#xff0c;用于在处理请求和响应之前对其进行拦截、处理或修改。中间件可以在应用程序的请求处理管道中插入自定义逻辑&#xff0c;以实现一些通用的功能&#xff0c;如身份验证、…...

centos7安装es及简单使用

为了方便日后查看&#xff0c;简单记录下&#xff01; 【启动es前,需要调整这个配置文件(/opt/elasticsearch-6.3.0/config/elasticsearch.yml)的两处ip地址,同时访问页面地址的ip:9200时,ip地址也对应修改】 【启动kibana前,需要调整这个配置文件(/opt/kibana-6.3.0/config/k…...

2024年自动驾驶SLAM面试题及答案(更新中)

自动驾驶中的SLAM&#xff08;Simultaneous Localization and Mapping&#xff0c;即同步定位与地图构建&#xff09;是关键技术&#xff0c;它能够让车辆在未知环境中进行自主定位和地图建构。秋招来临之际&#xff0c;相信大家都已经在忙碌的准备当中了&#xff0c;尤其是应届…...

HTML零基础自学笔记(上)-7.18

HTML零基础自学笔记&#xff08;上&#xff09; 参考&#xff1a;pink老师一、HTML, Javascript, CSS的关系是什么?二、什么是HTML?1、网页&#xff0c;网站的概念2、THML的基本概念3、THML的骨架标签/基本结构标签 三、HTML标签1、THML标签介绍2、常用标签图像标签&#xff…...

数学建模--图论与最短路径

目录 图论与最短路径问题 最短路径问题定义 常用的最短路径算法 Dijkstra算法 Floyd算法 Bellman-Ford算法 SPFA算法 应用实例 结论 延伸 如何在实际应用中优化Dijkstra算法以提高效率&#xff1f; 数据结构优化&#xff1a; 边的优化&#xff1a; 并行计算&…...

FLINK-checkpoint失败原因及处理方式

在 Flink 或其他分布式数据处理系统中&#xff0c;Checkpoint 失败可能由多种原因引起。以下是一些常见的原因&#xff1a; 资源不足&#xff1a; 如果 TaskManager 的内存或磁盘空间不足&#xff0c;可能无法完成状态的快照&#xff0c;导致 Checkpoint 失败。 网络问题&am…...

Hbase映射为Hive外表

作者&#xff1a;振鹭 Hbase对应Hive外表 (背景&#xff1a;在做数据ETL中&#xff0c;可能原始数据在列式存储Hbase中&#xff0c;这个时候&#xff0c;如果我们想清洗数据&#xff0c;可以考虑把Hbase表映射为Hive的外表&#xff0c;然后使用Hive的HQL来清除处理数据) 1. …...

洛谷P1002(过河卒)题解

题目传送门 思路 直接爆搜会TLE&#xff0c;所以考虑进行DP。 由于卒只可以从左边和上面走&#xff0c;所以走到(i,j)的路程总数为从上面走的路程总数加上从左边走的路程总数。我们用dp[i][j]表示从起点走到(i,j)的路程总数&#xff0c;那么状态转移方程为&#xff1a; dp[…...

微信小程序 async-validator 表单验证 第三方包

async-validator 是一个基于 JavaScript 的表单验证库&#xff0c;支持异步验证规则和自定义验证规则 主流的 UI 组件库 Ant-design 和 Element 中的表单验证都是基于 async-validator 使用 async-validator 可以方便地 构建表单中逻辑&#xff0c;使得错误提示信息更加友好和灵…...

云启出海,智联未来|阿里云网络「企业出海」系列客户沙龙上海站圆满落地

借阿里云中企出海大会的东风&#xff0c;以**「云启出海&#xff0c;智联未来&#xff5c;打造安全可靠的出海云网络引擎」为主题的阿里云企业出海客户沙龙云网络&安全专场于5.28日下午在上海顺利举办&#xff0c;现场吸引了来自携程、小红书、米哈游、哔哩哔哩、波克城市、…...

初学 pytest 记录

安装 pip install pytest用例可以是函数也可以是类中的方法 def test_func():print()class TestAdd: # def __init__(self): 在 pytest 中不可以使用__init__方法 # self.cc 12345 pytest.mark.api def test_str(self):res add(1, 2)assert res 12def test_int(self):r…...

Linux离线(zip方式)安装docker

目录 基础信息操作系统信息docker信息 安装实例安装步骤示例 遇到的问题问题1&#xff1a;修改默认工作路径启动失败问题2 找不到对应组 基础信息 操作系统信息 OS版本&#xff1a;CentOS 7 64位 内核版本&#xff1a;3.10.0 相关命令&#xff1a; uname -rcat /etc/os-rele…...

视觉slam十四讲实践部分记录——ch2、ch3

ch2 一、使用g++编译.cpp为可执行文件并运行(P30) g++ helloSLAM.cpp ./a.out运行 二、使用cmake编译 mkdir build cd build cmake .. makeCMakeCache.txt 文件仍然指向旧的目录。这表明在源代码目录中可能还存在旧的 CMakeCache.txt 文件,或者在构建过程中仍然引用了旧的路…...

SQL慢可能是触发了ring buffer

简介 最近在进行 postgresql 性能排查的时候,发现 PG 在某一个时间并行执行的 SQL 变得特别慢。最后通过监控监观察到并行发起得时间 buffers_alloc 就急速上升,且低水位伴随在整个慢 SQL,一直是 buferIO 的等待事件,此时也没有其他会话的争抢。SQL 虽然不是高效 SQL ,但…...

【JVM面试篇】高频八股汇总——类加载和类加载器

目录 1. 讲一下类加载过程&#xff1f; 2. Java创建对象的过程&#xff1f; 3. 对象的生命周期&#xff1f; 4. 类加载器有哪些&#xff1f; 5. 双亲委派模型的作用&#xff08;好处&#xff09;&#xff1f; 6. 讲一下类的加载和双亲委派原则&#xff1f; 7. 双亲委派模…...

JDK 17 序列化是怎么回事

如何序列化&#xff1f;其实很简单&#xff0c;就是根据每个类型&#xff0c;用工厂类调用。逐个完成。 没什么漂亮的代码&#xff0c;只有有效、稳定的代码。 代码中调用toJson toJson 代码 mapper.writeValueAsString ObjectMapper DefaultSerializerProvider 一堆实…...

二叉树-144.二叉树的前序遍历-力扣(LeetCode)

一、题目解析 对于递归方法的前序遍历十分简单&#xff0c;但对于一位合格的程序猿而言&#xff0c;需要掌握将递归转化为非递归的能力&#xff0c;毕竟递归调用的时候会调用大量的栈帧&#xff0c;存在栈溢出风险。 二、算法原理 递归调用本质是系统建立栈帧&#xff0c;而非…...

中科院1区顶刊|IF14+:多组学MR联合单细胞时空分析,锁定心血管代谢疾病的免疫治疗新靶点

中科院1区顶刊|IF14&#xff1a;多组学MR联合单细胞时空分析&#xff0c;锁定心血管代谢疾病的免疫治疗新靶点 当下&#xff0c;免疫与代谢性疾病的关联研究已成为生命科学领域的前沿热点。随着研究的深入&#xff0c;我们愈发清晰地认识到免疫系统与代谢系统之间存在着极为复…...

基于Java项目的Karate API测试

Karate 实现了可以只编写Feature 文件进行测试,但是对于熟悉Java语言的开发或是测试人员,可以通过编程方式集成 Karate 丰富的自动化和数据断言功能。 本篇快速介绍在Java Maven项目中编写和运行测试的示例。 创建Maven项目 最简单的创建项目的方式就是创建一个目录,里面…...