[硬核] Bootstrap Blazor Table 综合演示例子
知识点:
1.导入导出
2.分页功能
3.增删改查
4.批量删除
5.批量编辑(审核)
6.列排序与列搜索
7.顶部搜索实现所有列搜索
8.高级搜索实现多条件搜索
9.顶部与刷新与视图列
10.实现文本类型明细行
11.列的统计
12.隐藏列,时间日期列格式化
13.新窗口打开
14.随机数据
15.自由编辑
16.清空数据
17.模板下载
截图



基础工程
注入FreeSqlDataService服务,支持全数据导出
更新包
<PackageReference Include="BootstrapBlazor" Version="7.2.3-beta03" />
<PackageReference Include="Densen.FreeSql.Extensions.BootstrapBlazor" Version="7.*" />
Program.cs 添加代码
using Densen.DataAcces.FreeSql;
builder.Services.AddSingleton(typeof(FreeSqlDataService<>));
builder.Services.ConfigureJsonLocalizationOptions(op =>
{
    // 忽略文化信息丢失日志
    op.IgnoreLocalizerMissing = true;
});
Index.razor添加一个 TabItem
Tab 顺便改为懒加载
<Tab IsLazyLoadTabItem="true">
    ...
    <TabItem Text="综合演示">
        <ImpExpIII />
    </TabItem>
</Tab>
添加打印预览 Pages\_Host.cshtml
< / body > 前加一句
    <script>
        function printDiv() {
            window.print();
        }
    </script>
数据实体类 Data\SalesChannels.cs
查看代码
```
using BootstrapBlazor.Components;
using DocumentFormat.OpenXml.Wordprocessing;
using FreeSql.DataAnnotations;
using Magicodes.ExporterAndImporter.Excel;
using OfficeOpenXml.Table;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
namespace b14table.Data;
[ExcelImporter(IsLabelingError = true)]
[ExcelExporter(Name = "导入商品中间表", TableStyle = TableStyles.Light10, AutoFitAllColumn = true)]
[AutoGenerateClass(Searchable = true, Filterable = true, Sortable = true, ShowTips = true)]
public class SalesChannels
{
[AutoGenerateColumn(Ignore = true)]
[Column(IsIdentity = true)]
[DisplayName("序号")]
public int ID { get; set; }
[AutoGenerateColumn(ComponentType = typeof(ColorPicker), Width = 30)]
[DisplayName("级别")]
public string? Background { get; set; }
[AutoGenerateColumn(FormatString = "yyyy-MM-dd")]
[DisplayName("日期")]
public DateTime Date { get; set; }
[Required(ErrorMessage = "{0}不能为空")]
[DisplayName("名称")]
public string? Name { get; set; }
[DisplayName("项目数量")]
public int Projects { get; set; }
[DisplayName("交单数量")]
public int Orders { get; set; }
[DisplayName("结单数量")]
public int Checkouts { get; set; }
// 编辑界面无法显示小数, 以后再思考
[DisplayName("结单率")]
[AutoGenerateColumn(Readonly = true)]
public string? CheckoutRates { get => GetCheckoutRates(Checkouts, Orders); set => checkoutRates = value; }
string? checkoutRates;
[DisplayName("合格数量")]
public int Qualifieds { get; set; }
[DisplayName("合格率")]
[AutoGenerateColumn(Readonly = true)]
public string? QualifiedRates { get => GetQualifiedRates(Qualifieds, Checkouts); set => qualifiedRates = value; }
string? qualifiedRates;
[DisplayName("总价值")]
public int Total { get; set; }
[DisplayName("应收款")]
public int Receivables { get; set; }
[DisplayName("已收款")]
public int Received { get; set; }
[AutoGenerateColumn(FormatString = "HH:mm:ss")]
[DisplayName("修改日期")]
public DateTime ModifiedDate { get; set; } = DateTime.Now;
[AutoGenerateColumn(TextEllipsis = true, Visible = false, ShowTips = true, ComponentType = typeof(Textarea))]
[DisplayName("备注")]
public string? Remark { get; set; }
[AutoGenerateColumn(Visible = false, ComponentType = typeof(BootstrapInput<decimal>), Width = 80)]
[DisplayName("Test1")]
public decimal Test1 { get; set; }
private string GetCheckoutRates(int checkouts, int orders) => orders > 0 ? (checkouts /(double) orders).ToString("P2") : "0%";
private string GetQualifiedRates(int qualifieds, int checkouts) => checkouts > 0 ? (qualifieds / (double)checkouts).ToString("P2") : "0%";
}
</details>
### 页面 `Pages\ImpExpIII.razor`
<details>
<summary>查看代码</summary>
@page "/impexpiii"
@using b14table.Data
@using static Blazor100.Service.ImportExportsService
综合演示
<SearchTemplate>
    <GroupBox Title="搜索">
        <div class="row g-3 form-inline">
            <div class="col-12 col-sm-6">
                <BootstrapInput @bind-Value="@context.Name" maxlength="50" ShowLabel="true" />
            </div>
            <div class="col-12 col-sm-6">
                <BootstrapInput @bind-Value="@context.Date" maxlength="500" ShowLabel="true" />
            </div>
        </div>
    </GroupBox>
</SearchTemplate>
<DetailRowTemplate>
    <div>备注: @context.Remark </div>
</DetailRowTemplate>
<TableFooter Context="context1">
    <TableFooterCell Text="当前页小计:" colspan="4" />
    <TableFooterCell Text="总价值" colspan="3" />
    <TableFooterCell Aggregate="@Aggregate" Field="@nameof(SalesChannels.Total)" />
    <TableFooterCell Text="应收款" colspan="3" />
    <TableFooterCell Aggregate="@Aggregate" Field="@nameof(SalesChannels.Receivables)" />
    <TableFooterCell Text="已收款" colspan="3" />
    <TableFooterCell Aggregate="@Aggregate" Field="@nameof(SalesChannels.Received)" />
</TableFooter>
<TableToolbarTemplate>
    <TableToolbarButton TItem="SalesChannels" Color="Color.Primary" Text="自由编辑" OnClick="@IsExcelToggle" />
    <TableToolbarButton TItem="SalesChannels" Color="Color.Warning" Text="随机数据" IsAsync OnClick="@GetDatasAsync" />
    <TableToolbarButton TItem="SalesChannels" Color="Color.Secondary" Text="导入" IsAsync OnClick="@ImportExcel" />
    <TableToolbarButton TItem="SalesChannels" Color="Color.Danger" Text="清空" IsAsync OnClick="EmptyAll" />
    <TableToolbarButton TItem="SalesChannels" Color="Color.Success" Text="模板" IsAsync OnClick="Export模板Async" />
    <TableToolbarButton TItem="SalesChannels" Color="Color.Success" Text="打印" IsAsync OnClickCallback="@PrintPreview" />
    <TableToolbarButton TItem="SalesChannels" Color="Color.Secondary" Text="新窗口打开" IsAsync OnClick="@新窗口打开" />
    <TableToolbarButton TItem="SalesChannels" Color="Color.Secondary" Text="批量审批" IsAsync OnClickCallback="@批量审批" />
</TableToolbarTemplate>
<ExportButtonDropdownTemplate>
    <h6 class="dropdown-header">当前页数据</h6>
    <div class="dropdown-item" @onclick="_=>ExportExcelAsync(list1.Rows)">
        <i class="fas fa-file-excel"></i>
        <span>Excel</span>
    </div>
    <div class="dropdown-item" @onclick="_=>ExportWordAsync(list1.Rows)">
        <i class="fas fa-file-word"></i>
        <span>Word</span>
    </div>
    <div class="dropdown-item" @onclick="_=>ExportHtmlAsync(list1.Rows)">
        <i class="fa-brands fa-html5"></i>
        <span>Html</span>
    </div>
    <div class="dropdown-item" @onclick="_=>ExportPDFAsync(list1.Rows)">
        <i class="fas fa-file-pdf"></i>
        <span>PDF</span>
    </div>
    <div class="dropdown-divider"></div>
    <h6 class="dropdown-header">全部数据</h6>
    <div class="dropdown-item" @onclick="_=>ExportExcelAsync(DataService.GetAllItems())">
        <i class="fas fa-file-excel"></i>
        <span>Excel</span>
    </div>
    <div class="dropdown-item" @onclick="_=>ExportWordAsync(DataService.GetAllItems())">
        <i class="fas fa-file-word"></i>
        <span>Word</span>
    </div>
    <div class="dropdown-item" @onclick="_=>ExportHtmlAsync(DataService.GetAllItems())">
        <i class="fa-brands fa-html5"></i>
        <span>Html</span>
    </div>
    <div class="dropdown-item" @onclick="_=>ExportPDFAsync(DataService.GetAllItems())">
        <i class="fas fa-file-pdf"></i>
        <span>PDF</span>
    </div>
</ExportButtonDropdownTemplate>
```
页面代码 Pages\ImpExpIII.razor
查看代码
```
using AmeBlazor.Components;
using b14table.Data;
using Blazor100.Service;
using BootstrapBlazor.Components;
using Densen.DataAcces.FreeSql;
using DocumentFormat.OpenXml.Spreadsheet;
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.Forms;
using Microsoft.JSInterop;
using System.Diagnostics.CodeAnalysis;
using static Blazor100.Service.ImportExportsService;
namespace b14table.Pages
{
public partial class ImpExpIII
{
    [Inject]
    IWebHostEnvironment? HostEnvironment { get; set; }
    [Inject]
    [NotNull]
    NavigationManager? NavigationManager { get; set; }
    [Inject]
    [NotNull]
    ImportExportsService? ImportExportsService { get; set; }
    [Inject]
    [NotNull]
    ToastService? ToastService { get; set; }
    [Inject]
    [NotNull]
    FreeSqlDataService<SalesChannels>? DataService { get; set; }
    [NotNull]
    Table<SalesChannels>? list1 { get; set; }
    [Parameter] public int Footercolspan1 { get; set; } = 3;
    [Parameter] public int Footercolspan2 { get; set; } = 2;
    [Parameter] public int Footercolspan3 { get; set; }
    [Parameter] public int FootercolspanTotal { get; set; } = 2;
    [Parameter] public string? FooterText { get; set; } = "合计:";
    [Parameter] public string? FooterText2 { get; set; }
    [Parameter] public string? FooterText3 { get; set; }
    [Parameter] public string? FooterTotal { get; set; }
    /// <summary>
    /// 获得/设置 IJSRuntime 实例
    /// </summary>
    [Inject]
    [NotNull]
    protected IJSRuntime? JsRuntime { get; set; }
    [Parameter] public string? 新窗口打开Url { get; set; } = "https://localhost:7292/";
    // 由于使用了FreeSql ORM 数据服务,可以直接取对象
    [Inject]
    [NotNull]
    IFreeSql? fsql { get; set; }
    [Inject] ToastService? toastService { get; set; }
    [Inject] SwalService? SwalService { get; set; }
    public bool IsExcel { get; set; }
    public bool DoubleClickToEdit { get; set; } = true;
    protected string UploadPath = "";
    protected string? uploadstatus;
    long maxFileSize = 1024 * 1024 * 15;
    string? tempfilename;
    private AggregateType Aggregate { get; set; }
    protected async Task GetDatasAsync()
    {
        var datas = GetDemoDatas();
        await fsql.Insert<SalesChannels>().AppendData(datas).ExecuteAffrowsAsync();
        await list1!.QueryAsync();
    }
    protected override async void OnAfterRender(bool firstRender)
    {
        if (firstRender)
        {
            UploadPath = Path.Combine(HostEnvironment!.WebRootPath, "uploads");
            if (!Directory.Exists(UploadPath)) Directory.CreateDirectory(UploadPath);
            await list1!.QueryAsync();
        }
    }
    protected override async Task OnAfterRenderAsync(bool firstRender)
    {
        if (firstRender)
        {
            //懒的人,直接初始化一些数据用用
            var res = fsql.Select<SalesChannels>().Count();
            if (res == 0)
            {
                var datas = GetDemoDatas();
                await fsql.Insert<SalesChannels>().AppendData(datas).ExecuteAffrowsAsync();
                await list1!.QueryAsync();
            }
        }
    }
    public List<SalesChannels> GetDemoDatas()
    {
        var list = new List<SalesChannels>();
        for (int i = 0; i < 100; i++)
        {
            try
            {
                var total = Random.Shared.Next(100, 3000);
                list.Add(new SalesChannels()
                {
                    ID = i,
                    Name = "渠道" + i,
                    Date = DateTime.Now,
                    Projects = Random.Shared.Next(10, 55),
                    Orders = Random.Shared.Next(3, 10),
                    Qualifieds = i,
                    Total = total,
                    Receivables = total - i,
                    Received = i,
                    Remark= $"{i} 明细行内嵌套另外一个 Table 组件,由于每行都要关联子表数据,出于性能的考虑,此功能采用 懒加载 模式,即点击展开按钮后,再对嵌套 Table 进行数据填充,通过 ShowDetailRow 回调委托可以控制每一行是否显示明细行,本例中通过 Complete 属性来控制是否显示明细行,可通过翻页来测试本功能"
                });
            }
            catch (Exception e)
            {
                System.Console.WriteLine(e.Message);
            }
        }
        return list;
    }
    private Task IsExcelToggle()
    {
        IsExcel = !IsExcel;
        DoubleClickToEdit = !IsExcel;
        StateHasChanged();
        return Task.CompletedTask;
    }
    public async Task<bool> Export模板Async()
    {
        await Export();
        return true;
    }
    private async Task<bool> ExportExcelAsync(IEnumerable<SalesChannels> items) => await ExportAutoAsync(items, ExportType.Excel);
    private async Task<bool> ExportPDFAsync(IEnumerable<SalesChannels> items) => await ExportAutoAsync(items, ExportType.Pdf);
    private async Task<bool> ExportWordAsync(IEnumerable<SalesChannels> items) => await ExportAutoAsync(items, ExportType.Word);
    private async Task<bool> ExportHtmlAsync(IEnumerable<SalesChannels> items) => await ExportAutoAsync(items, ExportType.Html);
    private async Task<bool> ExportAutoAsync(IEnumerable<SalesChannels> items, ExportType exportType = ExportType.Excel)
    {
        if (items == null || !items.Any())
        {
            await ToastService.Error("提示", "无数据可导出");
            return false;
        }
        var option = new ToastOption()
        {
            Category = ToastCategory.Information,
            Title = "提示",
            Content = $"导出正在执行,请稍等片刻...",
            IsAutoHide = false
        };
        // 弹出 Toast
        await ToastService.Show(option);
        await Task.Delay(100);
        // 开启后台进程进行数据处理
        await Export(items?.ToList(), exportType);
        // 关闭 option 相关联的弹窗
        option.Close();
        // 弹窗告知下载完毕
        await ToastService.Show(new ToastOption()
        {
            Category = ToastCategory.Success,
            Title = "提示",
            Content = $"导出成功,请检查数据",
            IsAutoHide = false
        });
        return true;
    }
    private async Task Export(List<SalesChannels>? items = null, ExportType exportType = ExportType.Excel)
    {
        try
        {
            if (items == null || !items.Any())
            {
                ToastService?.Error($"导出", $"{exportType}出错,无数据可导出");
                return;
            }
            var fileName = items == null ? "模板" : typeof(SalesChannels).Name;
            var fullName = Path.Combine(UploadPath, fileName);
            fullName = await ImportExportsService.Export(fullName, items, exportType);
            fileName = (new System.IO.FileInfo(fullName)).Name;
            ToastService?.Success("提示", fileName + "已生成");
            //下载后清除文件
            NavigationManager.NavigateTo($"uploads/{fileName}", true);
            _ = Task.Run(() =>
            {
                Thread.Sleep(50000);
                System.IO.File.Delete(fullName);
            });
        }
        catch (Exception e)
        {
            ToastService?.Error($"导出", $"{exportType}出错,请检查. {e.Message}");
        }
    }
    public async Task<bool> EmptyAll()
    {
        fsql.Delete<SalesChannels>().Where(a => 1 == 1).ExecuteAffrows();
        await ToastService!.Show(new ToastOption()
        {
            Category = ToastCategory.Success,
            Title = "提示",
            Content = "已清空数据",
        });
        await list1!.QueryAsync();
        return true;
    }
    private async Task ImportExcel()
    {
        if (string.IsNullOrEmpty(tempfilename))
        {
            ToastService?.Error("提示", "请正确选择文件上传");
            return;
        }
        var option = new ToastOption()
        {
            Category = ToastCategory.Information,
            Title = "提示",
            Content = "导入文件中,请稍等片刻...",
            IsAutoHide = false
        };
        // 弹出 Toast
        await ToastService!.Show(option);
        await Task.Delay(100);
        // 开启后台进程进行数据处理
        var isSuccess = await MockImportExcel();
        // 关闭 option 相关联的弹窗
        option.Close();
        // 弹窗告知下载完毕
        await ToastService.Show(new ToastOption()
        {
            Category = isSuccess ? ToastCategory.Success : ToastCategory.Error,
            Title = "提示",
            Content = isSuccess ? "操作成功,请检查数据" : "出现错误,请重试导入或者上传",
            IsAutoHide = false
        });
        await list1!.QueryAsync();
    }
    private async Task<bool> MockImportExcel()
    {
        var items_temp = await ImportExportsService!.ImportFormExcel<SalesChannels>(tempfilename!);
        if (items_temp.items == null)
        {
            ToastService?.Error("提示", "文件导入失败: " + items_temp.error);
            return false;
        }
        //items = SmartCombine(items_temp, items).ToList(); 新数据和老数据合并处理,略100字
        await fsql.Insert<SalesChannels>().AppendData(items_temp!.items.ToList()).ExecuteAffrowsAsync();
        return true;
    }
    protected async Task OnChange(InputFileChangeEventArgs e)
    {
        if (e.File == null) return;
        tempfilename = Path.Combine(UploadPath, e.File.Name);
        await using FileStream fs = new(tempfilename, FileMode.Create);
        using var stream = e.File.OpenReadStream(maxFileSize);
        await stream.CopyToAsync(fs);
        //正式工程此处是回调,简化版必须InvokeAsync一下,自由发挥
        _ = Task.Run(async () => await InvokeAsync(async () => await ImportExcel()));
    }
    /// <summary>
    /// 导出数据方法
    /// </summary>
    /// <param name="Items"></param>
    /// <param name="opt"></param>
    /// <returns></returns>
    protected async Task<bool> ExportAsync(IEnumerable<SalesChannels> Items, QueryPageOptions opt)
    {
        var ret = await ExportExcelAsync(Items);
        return ret;
    }
    public Task PrintPreview(IEnumerable<SalesChannels> item)
    {
        //实际工程自己完善js打印
        JsRuntime.InvokeVoidAsync("printDiv");
        return Task.CompletedTask;
    }
    private Task 新窗口打开()
    {
        if (string.IsNullOrEmpty(新窗口打开Url))
        {
            ToastService?.Error("提示", "Url为空!");
            return Task.CompletedTask;
        }
        JsRuntime.NavigateToNewTab(新窗口打开Url);
        return Task.CompletedTask;
    }
    public async Task 批量审批(IEnumerable<SalesChannels> items)
    {
        items.ToList().ForEach(a =>
        {
            a.Checkouts = a.Orders;
            a.Receivables = 0;
            a.Received = a.Total;
            a.ModifiedDate = DateTime.Now;
        });
        var res = await fsql.Update<SalesChannels>().SetSource(items).ExecuteAffrowsAsync();
        await SwalService!.Show(new SwalOption()
        {
            Title = res == 0 ? "提示: 操作失败" : "提示: 操作成功"
        });
       if (res != 0) await list1!.QueryAsync();
    }
}
}
</details>
### 预览
.gif")
### 源代码
https://github.com/densen2014/Blazor100/tree/master/b04table
https://gitee.com/densen2014/Blazor100/tree/master/b04table
[硬核] Bootstrap Blazor Table 综合演示例子的更多相关文章
- Bootstrap Blazor Table 组件(二)
		
原文链接:https://www.cnblogs.com/ysmc/p/16128206.html 很多小伙伴在使用 Bootstrap Blazor Table组件的时候,都会有这样的一个需求: 我 ...
 - Bootstrap Blazor Table 组件(四)自定义列生成
		
原文链接:https://www.cnblogs.com/ysmc/p/16223154.html Bootstrap Blazor 官方链接:https://www.blazor.zone/tabl ...
 - Bootstrap Blazor Table 组件(三)智能生成
		
原文链接:https://www.cnblogs.com/ysmc/p/16201153.html Bootstrap Blazor 官网地址:https://www.blazor.zone 有了解过 ...
 - Bootstrap Blazor 组件介绍 Table (一)自动生成列功能介绍
		
Bootstrap Blazor 是一套企业级 UI 组件库,适配移动端支持各种主流浏览器,已经在多个交付项目中使用.通过本套组件可以大大缩短开发周期,节约开发成本.目前已经开发.封装了 70 多个组 ...
 - Bootstrap Blazor 组件介绍 Table (二)自定义模板列功能介绍
		
Bootstrap Blazor 是一套企业级 UI 组件库,适配移动端支持各种主流浏览器,已经在多个交付项目中使用.通过本套组件可以大大缩短开发周期,节约开发成本.目前已经开发.封装了 70 多个组 ...
 - Bootstrap Blazor 组件介绍 Table (三)列数据格式功能介绍
		
Bootstrap Blazor 是一套企业级 UI 组件库,适配移动端支持各种主流浏览器,已经在多个交付项目中使用.通过本套组件可以大大缩短开发周期,节约开发成本.目前已经开发.封装了 70 多个组 ...
 - bootstrap table 服务器端分页例子分享
		
这篇文章主要介绍了bootstrap table 服务器端分页例子分享,需要的朋友可以参考下 1,前台引入所需的js 可以从官网上下载 复制代码代码如下: function getTab(){var ...
 - Bootstrap Blazor 开源UI库介绍-Table 虚拟滚动行
		
今天我们来介绍一下 Bootstrap Blazor 中 Table 组件的虚拟滚动行,什么是虚拟滚动呢,我查到的解释是:只渲染可视区域的列表项,非可见区域的 完全不渲染,在滚动条滚动时动态更新列表项 ...
 - 重磅硬核 | 一文聊透对象在 JVM 中的内存布局,以及内存对齐和压缩指针的原理及应用
		
欢迎关注公众号:bin的技术小屋 大家好,我是bin,又到了每周我们见面的时刻了,我的公众号在1月10号那天发布了第一篇文章<从内核角度看IO模型的演变>,在这篇文章中我们通过图解的方式以 ...
 - [转]bootstrap的table插件动态加载表头
		
原文地址:https://blog.csdn.net/abubu123/article/details/78060321 bootstrap的table属性已经很熟悉了,最近遇到一个问题,犹豫每个列表 ...
 
随机推荐
- 从0搭建vue3组件库:自动化发布、管理版本号、生成 changelog、tag
			
今天看到一篇文章中提到了一个好用的工具release-it.刚好可以用在我正在开发的vue3组件库.纸上得来终觉浅,绝知此事要躬行,说干就干,下面就介绍如何将release-it应用到实际项目中,让组 ...
 - 驱动开发:内核监控Register注册表回调
			
在笔者前一篇文章<驱动开发:内核枚举Registry注册表回调>中实现了对注册表的枚举,本章将实现对注册表的监控,不同于32位系统在64位系统中,微软为我们提供了两个针对注册表的专用内核监 ...
 - SQL--Row_Number() over()的使用
			
1.语法 --over里面有两个参数 --partition by 用于分割区域 此参数可选 --order by 用于排序 此参数必有 row_number() over(partition by ...
 - html中可以写php代码,但是文件后缀名需要是.php而不是.html。否则php程序不会被解析执行。
			
html中可以写php代码,但是文件后缀名需要是.php而不是.html.否则php程序不会被解析执行. <div class="goods_title"><?p ...
 - mysql是如何实现mvcc的
			
mvcc的概念 mvcc即多版本并发控制,是一种并发控制的策略,能让数据库在高并发下做到安全高效的读写,提升数据库的并发性能; 是一种用来解决并发下读写冲突的无锁解决方案,为事务分配单向增长时间戳,为 ...
 - JUC学习笔记——共享模型之内存
			
JUC学习笔记--共享模型之内存 在本系列内容中我们会对JUC做一个系统的学习,本片将会介绍JUC的内存部分 我们会分为以下几部分进行介绍: Java内存模型 可见性 模式之两阶段终止 模式之Balk ...
 - 如何在 .NET MAUI 中加载 json 文件?
			
引言: 按core传统方式添加 AddJsonFile("appsettings.json") 在windows平台和ssr工作正常,但是在 ios 和 android 无法用这种 ...
 - HTTPS - 揭秘 TLS 1.2 协议完整握手过程--此文为转发文,一定要结合wirshark工具看,很清楚
			
winshark 筛选条件为:tls and ip.src==xxx 本文通过对一次 TLS 握手过程的数据抓包分析做为切入点,希望能进一步的帮助大家理解 HTTPS 原理. HTTPS 是建立在 S ...
 - 支持 equals 相等的对象(可重复对象)作为 WeakHashMap 的 Key
			
原文地址 代码地址 问题 长链接场景下通常有一个类似 Map<String, Set<Long>> 的结构,用来查找一个逻辑组内的哪些用户,String 类型的 Entry.k ...
 - 【云原生 · Kubernetes】apiserver高可用
			
个人名片: 因为云计算成为了监控工程师 个人博客:念舒_C.ying CSDN主页️:念舒_C.ying 7.1 高可用选型 ipvs+keepalived nginx+keepalived hap ...