Django 模板分割及多语言支持案例【需求文档】-->【实现方案】
Django 模板分割及多语言支持案例
这个案例旨在提供一个清晰的示范,展示如何将复杂的页面分解为多个可复用的模板组件,使代码更加模块化和易于管理。希望这篇案例文章对你有所帮助。
概述
在 Django 项目开发中,使用模板分割和多语言支持能有效提升代码的可维护性和用户体验。本案例通过一个简单的博客项目,展示如何将 Django 模板拆分为多个文件,并实现多语言支持。
需求文档
-
背景
在开发Django项目时,将模板分割成多个文件并实现多语言支持是提高代码可维护性和用户体验的重要方法。本项目旨在展示如何使用Django模板进行模块化开发和多语言支持。通过一个简单的博客项目,我们将实现页面分割、文章列表显示及商品信息展示,并根据语言切换进行动态更新。 -
功能需求
2.1 基础模板
功能:存储页面的基础配置,提供页面结构和通用样式。
文件名:base.html
详细描述:
包含HTML头部信息。
提供通用的样式定义。
定义内容插入块 {% block content %},供其他页面继承和填充内容。
2.2 主页模板
功能:显示主页内容,包含语言切换选项和文章列表。
文件名:home.html
详细描述:
继承自 base.html。
定义页面标题块 {% block title %}。
显示当前语言。
提供语言切换下拉菜单。
插入文章列表模板 {% include “article_list.html” %}。
2.3 文章列表模板
功能:循环显示文章列表,根据当前语言显示相应的文章标题和概括。
文件名:article_list.html
详细描述:
使用 {% for %} 循环显示所有文章。
根据当前语言显示中文或英文文章标题及概括。
插入相应语言的商品列表模板 {% include “products_list_cn.html” %} 或 {% include “products_list_en.html” %}。
2.4 中文商品列表模板
功能:显示文章中的商品列表,最多显示5个商品。
文件名:products_list_cn.html
详细描述:
根据是否存在商品标题,动态插入商品部分模板 {% include “products_part_1_cn.html” %} 至 {% include “products_part_5_cn.html” %}。
2.5 商品部分模板
功能:显示具体的商品信息。
文件名:products_part_1_cn.html 至 products_part_5_cn.html
详细描述:
显示商品标题、概括和图片。
根据商品信息动态生成页面内容。
- 界面展示
3.1 主页
当前语言:显示当前选择的语言。
语言切换:提供语言选择下拉菜单,用户可切换语言。
文章列表:根据选择的语言显示对应的文章标题和概括。
商品列表:根据文章显示对应的商品列表和详细信息。
3.2 文章与商品展示
文章标题:根据语言显示中文或英文标题。
文章概括:显示文章的简短概括,并根据语言切换。
商品信息:根据语言动态显示商品标题、概括和图片。
- 业务逻辑
4.1 模板继承
home.html 继承自 base.html,提供页面的基础结构和通用样式。
使用 {% block title %} 和 {% block content %} 定义可插入内容。
4.2 语言切换
在 home.html 中提供语言切换下拉菜单,并通过 JavaScript 实现页面语言切换。
根据选择的语言参数 current_language 动态加载文章和商品内容。
4.3 文章与商品显示
使用 {% for article in articles %} 循环遍历所有文章。
根据 current_language 判断显示中文或英文的文章标题和概括。
根据文章中的商品信息,动态加载相应的商品部分模板。
- 总结
通过本需求文档,我们详细描述了Django项目中模板分割与多语言支持的实现方法。项目包含基础模板、主页模板、文章列表模板和商品部分模板,并通过语言切换动态加载对应内容,提升了代码的可维护性和用户体验。
具体实现
基础模板:base.html
基础模板 base.html 用于存储页面的基础配置,并可被其他页面继承和调用。它包含了 HTML 头部信息和页面主体结构:
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8" /><meta name="viewport" content="width=device-width, initial-scale=1.0" /><title>{% block title %}主页{% endblock %}</title><!-- Google Fonts --><link href="https://fonts.googleapis.com/css2?family=Roboto:wght@300;400;500;700&display=swap" rel="stylesheet" /><!-- Tailwind CSS CDN --><script src="https://cdn.tailwindcss.com"></script><style>body {font-family: 'Roboto', sans-serif;}.hover-arrow::after {content: '>';color: #a0aec0;right: 0px;position: absolute;font-weight: bold;font-size: 24px;width: 25px;height: 36px;top: 25px;}</style>
</head>
<body class="bg-gray-900 text-white"><div class="max-w-3xl mx-auto py-8 px-4">{% block content %}{% endblock %}</div>
</body>
</html>
主页模板:home.html
主页模板 home.html 继承自 base.html,并包含页面标题、语言切换选项和文章列表:
{% extends "base.html" %}{% block title %}主页{% endblock %}{% block content %}<div class="mb-4"><span class="text-white text-xl font-bold">当前语言: {{ current_language }}</span></div><div class="mb-4"><label for="language-select" class="text-white text-xl">选择语言: </label><select id="language-select" onchange="changeLanguage(this)"><option value="cn" {% if current_language == 'cn' %}selected{% endif %}>简体中文</option><option value="en" {% if current_language == 'en' %}selected{% endif %}>English</option></select></div>{% include "article_list.html" %}<script>function changeLanguage(select) {const lang = select.value;const url = new URL(window.location.href);url.searchParams.set('lang', lang);window.location.href = url.toString();}</script>
{% endblock %}
文章列表模板:article_list.html
article_list.html 用于循环显示文章列表,根据当前语言显示相应的标题和文章概括,并插入商品列表模板:
{% for article in articles %}
<br>{% if article.title_en and current_language == 'en' %} <div class="flex items-center mb-6"><div class="w-8 h-8 bg-orange-500 rounded-full flex items-center justify-center"><span class="text-white text-xl font-bold">Hot</span></div><div class="ml-3"><h1 class="text-lg font-bold"><a href="/article/{{ article.id }}/?lang={{ current_language }}" class="text-blue-400 hover:underline">{{ article.title_en }}</a></h1></div>
</div>
<p class="text-gray-400 mb-6 leading-relaxed"> {% with summary=article.summary_en|default_if_none:""|slice:":80" %}{{ summary|ljust:80 }}{% endwith %}
</p>
{% include "products_list_en.html" %}
{% endif %}{% if article.title_cn and current_language == 'cn' %} <div class="flex items-center mb-6"><div class="w-8 h-8 bg-orange-500 rounded-full flex items-center justify-center"><span class="text-white text-xl font-bold">新</span></div><div class="ml-3"><h1 class="text-lg font-bold"><a href="/article/{{ article.id }}/?lang={{ current_language }}" class="text-blue-400 hover:underline">{{ article.title_cn }}</a></h1></div>
</div>
<p class="text-gray-400 mb-6 leading-relaxed"> {% with summary=article.summary_cn|default_if_none:""|slice:":80" %}{{ summary|ljust:80 }}{% endwith %}
</p>
{% include "products_list_cn.html" %}
{% endif %}{% endfor %}
商品列表模板:products_list_cn.html
products_list_cn.html 用于显示中文商品列表。根据该篇文章是否插入商品,最多5个,最少0个 来进行显示:
<div class="space-y-4">{% if article.product_1_title_cn %}{% include "products_part_1_cn.html" %}{% endif %}{% if article.product_2_title_cn %}{% include "products_part_2_cn.html" %}{% endif %}{% if article.product_3_title_cn %}{% include "products_part_3_cn.html" %}{% endif %}{% if article.product_4_title_cn %}{% include "products_part_4_cn.html" %}{% endif %}{% if article.product_5_title_cn %}{% include "products_part_5_cn.html" %}{% endif %}
</div>
商品部分模板:products_part_1_cn.html
products_part_1_cn.html 用于显示文章中的第一个商品:
<a href="{{ article.product_1_link_cn }}" class="block"><div class="relative bg-gray-800 p-4 rounded-lg hover:bg-gray-700 cursor-pointer hover-arrow transition-all"><h2 class="text-lg font-bold mb-1">{{ article.product_1_title_cn }}</h2><p class="text-gray-400 text-sm" style="padding-right: 120px;"> {% with summary=article.product_1_summary_cn|default_if_none:""|slice:":80" %}{{ summary|ljust:80 }}{% endwith %}</p>{% if article.image_1 %}<div class="absolute top-2 right-12 w-16 h-16" {% if article.tag_choice_1 == 'circle_image' %} style="border-radius: 50%; overflow: hidden;" {% elif article.tag_choice_1 == 'square_image' %} style="border-radius: 0;" {% elif article.tag_choice_1 == 'triangle_image' %} style="clip-path: polygon(50% 0%, 0% 100%, 100% 100%);" {% elif article.tag_choice_1 == 'pentagon_image' %} style="clip-path: polygon(50% 0%, 100% 38%, 82% 100%, 18% 100%, 0% 38%);" {% elif article.tag_choice_1 == 'hexagon_image' %} style="clip-path: polygon(25% 0%, 75% 0%, 100% 50%, 75% 100%, 25% 100%, 0% 50%);" {% else %} style="display: none;" {% endif %}><img src="{{ article.image_1 }}" alt="Article Image" class="w-full h-full object-cover"></div>{% endif %}</div>
</a>
商品部分模板:products_part_2_cn.html - products_part_5_cn.html
商品部分模板的配置方式类似于 products_part_1_cn.html。对于每个商品部分,都需要创建相应的模板文件 products_part_2_cn.html 到 products_part_5_cn.html,并按照上述方式进行配置。
这样一来,通过基础模板、主页模板、文章列表模板和商品部分模板的组合,可以实现页面的模块化开发和多语言支持,提高代码的可维护性和用户体验。
英文商品列表模板:products_list_en.html
products_list_en.html 用于显示英文商品列表。根据该篇文章是否插入商品,最多5个,最少0个来进行显示:
<div class="space-y-4">{% if article.product_1_title_en %}{% include "products_part_1_en.html" %}{% endif %}{% if article.product_2_title_en %}{% include "products_part_2_en.html" %}{% endif %}{% if article.product_3_title_en %}{% include "products_part_3_en.html" %}{% endif %}{% if article.product_4_title_en %}{% include "products_part_4_en.html" %}{% endif %}{% if article.product_5_title_en %}{% include "products_part_5_en.html" %}{% endif %}
</div>
英文商品部分模板:products_part_1_en.html
products_part_1_en.html 用于显示文章中的第一个英文商品:
<a href="{{ article.product_1_link_en }}" class="block"><div class="relative bg-gray-800 p-4 rounded-lg hover:bg-gray-700 cursor-pointer hover-arrow transition-all"><h2 class="text-lg font-bold mb-1">{{ article.product_1_title_en }}</h2><p class="text-gray-400 text-sm" style="padding-right: 120px;"> {% with summary=article.product_1_summary_en|default_if_none:""|slice:":80" %}{{ summary|ljust:80 }}{% endwith %}</p>{% if article.image_1 %}<div class="absolute top-2 right-12 w-16 h-16" {% if article.tag_choice_1 == 'circle_image' %} style="border-radius: 50%; overflow: hidden;" {% elif article.tag_choice_1 == 'square_image' %} style="border-radius: 0;" {% elif article.tag_choice_1 == 'triangle_image' %} style="clip-path: polygon(50% 0%, 0% 100%, 100% 100%);" {% elif article.tag_choice_1 == 'pentagon_image' %} style="clip-path: polygon(50% 0%, 100% 38%, 82% 100%, 18% 100%, 0% 38%);" {% elif article.tag_choice_1 == 'hexagon_image' %} style="clip-path: polygon(25% 0%, 75% 0%, 100% 50%, 75% 100%, 25% 100%, 0% 50%);" {% else %} style="display: none;" {% endif %}><img src="{{ article.image_1 }}" alt="Article Image" class="w-full h-full object-cover"></div>{% endif %}</div>
</a>
英文商品部分模板:products_part_2_en.html - products_part_5_en.html
英文商品部分模板的配置方式与 products_part_1_en.html 类似。对于每个商品部分,都需要创建相应的模板文件 products_part_2_en.html 到 products_part_5_en.html,并按照上述方式进行配置。
通过这些模板的组合和使用,可以学习如何在 Django 项目中使用模板继承与分割,以及如何实现多语言支持,从而提升项目的可维护性和用户体验。
为什么会使用这种自定义的方式?
虽然Django自带的翻译机制(i18n)是一个非常强大的工具,适用于大多数情况下的多语言支持,但在特定的需求和场景下,本文所采用的方法却有其不可替代的优势。以下是这些特定场景和需求的详细分析:
- 即时数据展示和内容管理
优点:
直接展示数据库内容:通过条件判断直接展示数据库中的多语言内容,无需在翻译文件之间进行中转,这可以确保数据的实时性和一致性。
便于内容管理:在一些需要频繁更新的项目中,如新闻网站或电子商务平台,内容管理人员可以直接在数据库中更新不同语言的内容,无需等待翻译文件的生成和编译。
- 灵活的模板定制
优点:
模板自定义:本文方法允许对不同语言的模板进行高度定制,例如,中文和英文模板可以有完全不同的布局和样式。这在一些文化差异较大的项目中尤为重要。
高度灵活:开发者可以针对不同语言版本进行不同的样式和内容调整,而不必受限于统一的翻译文件结构。这种灵活性在需要针对不同市场进行本地化优化时非常有用。
- 快速开发和原型设计
优点:
快速实现:不需要配置和管理翻译文件,开发者可以快速实现多语言支持,适用于项目初期的快速原型设计和验证。
低学习曲线:对于刚接触Django的开发者来说,不需要额外学习i18n的相关知识即可实现多语言支持,降低了开发难度和时间成本。
- 特定业务逻辑需求
优点:
复杂业务逻辑处理:在某些特定的业务需求下,需要在展示内容时进行复杂的逻辑判断和处理。例如,不同语言版本可能需要展示不同的广告或促销信息,这种情况下,通过模板条件判断可以更灵活地实现业务需求。
可扩展性:本文方法可以针对特定业务需求进行扩展,如在不同语言版本中显示不同的商品列表和内容,满足更加个性化的需求。
- 无需额外配置和依赖
优点:
简化配置:不需要依赖Django的中间件和配置,减少了系统依赖和配置复杂度,适用于一些简单的项目和开发环境。
减少出错可能:由于无需生成和编译翻译文件,减少了在这一步骤中可能出现的错误和不一致问题。
总结
虽然Django自带的翻译机制是处理多语言支持的最佳实践,但在特定需求和场景下,本文的方法提供了无法替代的灵活性和便捷性。这种方法在处理实时数据、定制化模板、快速开发和特定业务需求上具有明显优势,适用于一些需要快速实现、频繁更新和高度定制的项目。
相关文章:
Django 模板分割及多语言支持案例【需求文档】-->【实现方案】
Django 模板分割及多语言支持案例 这个案例旨在提供一个清晰的示范,展示如何将复杂的页面分解为多个可复用的模板组件,使代码更加模块化和易于管理。希望这篇案例文章对你有所帮助。 概述 在 Django 项目开发中,使用模板分割和多语言支持能…...
C中设计不允许继承的类的实现方法是什么?
在C中,设计不允许继承的类可以通过多种方法实现。以下是详细的方法说明及示例: ### 方法一:将构造函数和析构函数设为私有 这种方法的核心思想是通过将构造函数和析构函数设为私有,使得子类无法调用这些函数,从而无法…...
面对小白的C语言学习方法
这是第20篇文章,不来弄一些技术的,弄一些最近的学习心得,怎么更有效地自学C语言 书籍 书籍可以很有效的告知我们专有函数,使用方法还有一些思考方式,缺点是实操差点意思,还是不太能解决实际问题ÿ…...
使用libgif库解码全过程(C语言)-包括扩展块的处理
我看到的所有例程,都把扩展部分的处理跳过了,而我的动画是有透明度的,这就导致解码后的图像在有透明色的像素部分,呈现了很多的黑点,或者闪白的情况出现。经过调试,终于成功。 文件格式 先了解一下GIF的文…...
blazor实现ASP.NET网站用户批量注册方法
ASP.NET网站用户批量注册是许多使用blazor系统开发遇到的问题,为了解决这个问题,我们提出比较完善的解决方法,通过代码实现了一个批量用户注册功能,用于解析一份用户名列表,并通过后台服务注册用户,同时对成功和失败的注册进行记录和反馈。以下是实现功能的详细工作原理描…...
SpringCloud 入门(4)—— 网关
上一篇:SpringCloud 入门(3)—— Nacos配置中心-CSDN博客 Spring Cloud Gateway 作为 Spring Cloud 生态系统的一部分,主要在微服务架构中充当 API 网关的角色。它提供了统一的入口点来处理所有的 HTTP 请求,并将这些请…...
什么是WebAssembly?怎么使用?
一、简述 WebAssembly,也称为Wasm,是基于堆栈的虚拟机的二进制指令格式。它被设计为一个可移植的目标,用于编译C、C和Rust等高级编程语言,允许代码以接近本机速度在web浏览器中运行。WebAssembly于2015年由包括谷歌、微软、Mozill…...
v3s点RGB屏 40pin 800x480,不一样的点屏,不通过chosen。
一、背景、目的、简介。 一般来说,通过uboot将屏幕参数传给kernel,是通过修改设备树。 uboot和kernel都需要屏幕点亮。uboot侧重于显示一张图片。而kernel则多是动画。 在这里,我先是找到了一个裸机点屏的代码。将其编译成静态库后&#x…...
某科技局国产服务器PVE虚拟化技术文档
环境介绍 硬件配置 服务器品牌:黄河 型号:Huanghe 2280 V2 Cpu型号:kunpeng-920 磁盘信息 :480SSD * 2 ,4T*4 网卡:板载四口千兆 如下表 四台服务器同等型号配置,均做单节点虚拟化,数据保护采用底层r…...
中科岩创边坡自动化监测解决方案
行业现状 由于边坡不稳定性因素,可能会造成斜坡上的岩土体沿着某个面不均匀向下向外滑动,形成滑坡;陡峭山坡上岩土体在重力作用下,发生陡然倾落运动,造成崩塌;在沟谷或山坡上产生的夹带大量泥沙、石块等固体…...
GPT-O3:简单介绍
GPT-O3:人工智能领域的重大突破 近日,OpenAI发布了其最新的AI模型GPT-O3,这一模型在AGI评估中取得了惊人的成绩,展现出强大的能力和潜力。GPT-O3的出现标志着人工智能领域的重大进步,预计将在2025年实现更大的突破。 …...
cudnn版本gpu架构
nvcc --help 可以看 --gpu-architecture 写到的支持的架构 NVIDIA 的 GPU 架构是按代次发布的,以下是这些架构的对应说明: NVIDIA Hopper: 这是 NVIDIA 于 2022 年推出的架构之一,面向高性能计算(HPC)和人工智能&…...
数据库安全-redisCouchdb
1.redis未授权访问 默认端口:6379 1.1 Redis沙盒逃逸漏洞RCE-CVE-2022-0543 介绍:Redis 是一套开源的使用 ANSI C编写、支持网络、可基于内存亦可持久化的日志型、键值存储数据库,并提供多种语言的API。Redis 如果在没有开启认证的情况下,…...
ubuntu22.04安装PaddleX3
PaddleOCR 安装过程可以参考PaddleX本地安装教程 我的电脑环境配置: ubuntu22.04 cuda11.8(之前安装的是12.4没有匹配的paddle-gpu;这里改成11.8) 一、安装基础环境 1、 conda create -n ppx1 python3.10 2、 conda activate ppx1 3、…...
Flutter 实现全局悬浮按钮学习
Flutter 代码如何实现了一个全局悬浮按钮,当点击按钮时,会显示一个可以拖动并且通过长按可以移除的悬浮控件。 前置知识点学习 Offset Offset 是 Flutter 中的一个类,用于表示二维平面中的位置或位移。它通常用于描述坐标系中的一个点&…...
14-C语言多文件编程
一、各种变量 在学习多文件编程之前,先要了解清楚各种变量的作用范围以及生命周期。 1.普通变量 1.1普通局部变量 定义形式:在复合语句{}里面定义的变量为普通局部变量;作用范围:在复合语句{}里面有效;生命周期&am…...
基于Springboot的在线问卷调查系统【附源码】
基于Springboot的在线问卷调查系统 效果如下: 系统主页面 问卷列表页面 个人中心页面 系统登陆页面 管理员主页面 问卷管理页面 研究背景 随着互联网技术的飞速发展,传统的问卷调查方式因其时间和地点的限制,难以高效地收集到足够的数据。…...
Redis热点数据管理全解析:从MySQL同步到高效缓存的完整解决方案
1. 引言 1.1 背景介绍:MySQL与Redis在高性能场景下的结合 在现代互联网应用中,MySQL作为关系型数据库,承担了大量业务数据的存储任务。然而,随着业务的增长,海量数据的查询性能成为一个瓶颈。为了应对高并发和低延迟…...
【图书介绍】】几本Linux C\C++编程图书
Linux C\C编程,是IT领域比较稳定的职业发展方向,本文介绍几本Linux开发方面的图书。 《Linux C与C一线开发实践(第2版)》 《Linux C与C一线开发实践(第2版)(Linux技术丛书)》(朱文…...
MFC/C++学习系列之简单记录7
MFC/C学习系列之简单记录7 前言句柄的介绍句柄的使用AFX开头的函数都是干什么用的?总结 前言 在MFC的使用中发现了句柄,今天来详细学习一下MFC中如何使用句柄吧! 句柄的介绍 句柄的使用是资源管理和传递的关键机制,通过句柄将系…...
大数据学习栈记——Neo4j的安装与使用
本文介绍图数据库Neofj的安装与使用,操作系统:Ubuntu24.04,Neofj版本:2025.04.0。 Apt安装 Neofj可以进行官网安装:Neo4j Deployment Center - Graph Database & Analytics 我这里安装是添加软件源的方法 最新版…...
云计算——弹性云计算器(ECS)
弹性云服务器:ECS 概述 云计算重构了ICT系统,云计算平台厂商推出使得厂家能够主要关注应用管理而非平台管理的云平台,包含如下主要概念。 ECS(Elastic Cloud Server):即弹性云服务器,是云计算…...
Golang 面试经典题:map 的 key 可以是什么类型?哪些不可以?
Golang 面试经典题:map 的 key 可以是什么类型?哪些不可以? 在 Golang 的面试中,map 类型的使用是一个常见的考点,其中对 key 类型的合法性 是一道常被提及的基础却很容易被忽视的问题。本文将带你深入理解 Golang 中…...
day52 ResNet18 CBAM
在深度学习的旅程中,我们不断探索如何提升模型的性能。今天,我将分享我在 ResNet18 模型中插入 CBAM(Convolutional Block Attention Module)模块,并采用分阶段微调策略的实践过程。通过这个过程,我不仅提升…...
高频面试之3Zookeeper
高频面试之3Zookeeper 文章目录 高频面试之3Zookeeper3.1 常用命令3.2 选举机制3.3 Zookeeper符合法则中哪两个?3.4 Zookeeper脑裂3.5 Zookeeper用来干嘛了 3.1 常用命令 ls、get、create、delete、deleteall3.2 选举机制 半数机制(过半机制࿰…...
土地利用/土地覆盖遥感解译与基于CLUE模型未来变化情景预测;从基础到高级,涵盖ArcGIS数据处理、ENVI遥感解译与CLUE模型情景模拟等
🔍 土地利用/土地覆盖数据是生态、环境和气象等诸多领域模型的关键输入参数。通过遥感影像解译技术,可以精准获取历史或当前任何一个区域的土地利用/土地覆盖情况。这些数据不仅能够用于评估区域生态环境的变化趋势,还能有效评价重大生态工程…...
汇编常见指令
汇编常见指令 一、数据传送指令 指令功能示例说明MOV数据传送MOV EAX, 10将立即数 10 送入 EAXMOV [EBX], EAX将 EAX 值存入 EBX 指向的内存LEA加载有效地址LEA EAX, [EBX4]将 EBX4 的地址存入 EAX(不访问内存)XCHG交换数据XCHG EAX, EBX交换 EAX 和 EB…...
OPENCV形态学基础之二腐蚀
一.腐蚀的原理 (图1) 数学表达式:dst(x,y) erode(src(x,y)) min(x,y)src(xx,yy) 腐蚀也是图像形态学的基本功能之一,腐蚀跟膨胀属于反向操作,膨胀是把图像图像变大,而腐蚀就是把图像变小。腐蚀后的图像变小变暗淡。 腐蚀…...
Java毕业设计:WML信息查询与后端信息发布系统开发
JAVAWML信息查询与后端信息发布系统实现 一、系统概述 本系统基于Java和WML(无线标记语言)技术开发,实现了移动设备上的信息查询与后端信息发布功能。系统采用B/S架构,服务器端使用Java Servlet处理请求,数据库采用MySQL存储信息࿰…...
Netty从入门到进阶(二)
二、Netty入门 1. 概述 1.1 Netty是什么 Netty is an asynchronous event-driven network application framework for rapid development of maintainable high performance protocol servers & clients. Netty是一个异步的、基于事件驱动的网络应用框架,用于…...
