freemarker生成pdf,同時pdf插入頁腳,以及數據量大時批量處理

最近公司有個需求,就是想根據一個模板生成一個pdf文檔,當即我就想到了freemarker這個遠古老東西,畢竟freemarker在模板渲染方面還是非常有優勢的。

準備依賴:

        <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-freemarker</artifactId></dependency><dependency><groupId>com.itextpdf</groupId><artifactId>html2pdf</artifactId><version>3.0.5</version></dependency><!--pdf 支持中文(默認不支持)--><dependency><groupId>com.itextpdf</groupId><artifactId>itext-asian</artifactId><version>5.2.0</version></dependency><dependency><groupId>com.itextpdf</groupId><artifactId>itextpdf</artifactId><version>5.5.13</version></dependency>

我這里不想選freemarker版本,直接用spring集成的省事。
配置一下freemarker的配置

import freemarker.template.Configuration;
import freemarker.template.TemplateExceptionHandler;
import org.springframework.context.annotation.Bean;
import org.springframework.core.io.ClassPathResource;
import org.springframework.stereotype.Component;import java.io.IOException;@Component
@org.springframework.context.annotation.Configuration
public class FreemarkerConfig {// 我這里為了省事,不想創建那么多的Configuration,而且創建Configuration太多不好@Bean(name = "cfg")public Configuration freemarkerConfigurer() throws IOException {// 選擇版本,不同版本對不同的模板語法或者模板轉換也會有差異,如果你css 樣式比較新,建議選高版本準沒錯Configuration cfg = new Configuration(Configuration.VERSION_2_3_22);// 選擇你存放模板的位置final ClassPathResource classPathResource = new ClassPathResource("templates");cfg.setDirectoryForTemplateLoading(classPathResource.getFile());cfg.setDefaultEncoding("UTF-8");// 模板異常處理cfg.setTemplateExceptionHandler(TemplateExceptionHandler.RETHROW_HANDLER);return cfg;}
}

然后我們準備下我們的ftl模板【freemarker的模板文件】----pdf.ftl
freemarker框架類似于beetlthymeleafjspVelocity等模板引擎
JSP就不用說了吧,基本上開發Java的基本上都會了解開發過

<!doctype html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport"content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0"><meta http-equiv="X-UA-Compatible" content="ie=edge"><title>Document</title>
</head>
<style>.logo {width: 320px;height: 80px;}.user-info {padding: 10px 10px;background: RGB(221, 235, 247);}.label {width: 150px;padding: 0 20px 0 0;text-align: left;}.time {width: 100px;margin-right: 10px;text-align: center;}.label, .time {display: inline-block;}.range-time {margin: 20px 0;}.table-data {width: 100%;}table{border-collapse: collapse;}.header > th {text-align: left;height: 50px;}.divider-line {margin: 20px 0;height: 3px;background: #000;}.desc {padding: 15px 10px;}.date {width: 100px;}.fee {width: 50px;}.name {width: 140px;}.name, .fee, .date {padding: 0 10px;}.download-date {text-align: right;}.bottom-footer-tip {width: 100%;margin-top: 300px;font-size: 12px;transform: scale(.9);}
</style>
<body><div class="download-date">Download on 2022/2/2</div>
<div class="range-time"><span class="time">${startTime}</span><span>to</span><span class="time">${endTime}</span>
</div><table class="table-data"><tr class="header"><th>Date</th><th>Name</th><th>desc</th><th>fee</th></tr><tr class="divider-line"><th></th><th></th><th></th><th></th></tr><#list list as item><tr><td class="date">${item.date}</td><td class="name">${item.name}</td><td class="desc"><div>${item.desc}</div></td><td class="fee">${item.fee}</td></tr></#list><tr class="divider-line"><th></th><th></th><th></th><th></th></tr>
</table>
</body>
</html>

這里ftl的語法,我就不多做解釋了,我這里附上freemarker的官方文檔,感興趣的自己去學習一下。

然后準備下我們的代碼處理邏輯

首先是PDF實體數據

import lombok.Data;import java.util.List;@Data
public class PDFData {private String logo;private String name;private String address;private String startTime;private String endTime;private List<TableData> list;
}

然后是關聯(table)數據


import lombok.Data;@Data
public class TableData {private String date;private String desc;private String name;private String fee;
}

然后我們處理我們處理邏輯的代碼

import com.alibaba.fastjson.JSONObject;
import com.example.web.pojo.TableData;
import com.example.web.pojo.PDFData;
import com.itextpdf.html2pdf.ConverterProperties;
import com.itextpdf.html2pdf.HtmlConverter;
import com.itextpdf.html2pdf.resolver.font.DefaultFontProvider;
import com.itextpdf.kernel.colors.DeviceRgb;
import com.itextpdf.kernel.font.PdfFontFactory;
import com.itextpdf.kernel.geom.PageSize;
import com.itextpdf.kernel.pdf.PdfDocument;
import com.itextpdf.kernel.pdf.PdfPage;
import com.itextpdf.kernel.pdf.PdfReader;
import com.itextpdf.kernel.pdf.PdfWriter;
import com.itextpdf.layout.Document;
import com.itextpdf.layout.element.Paragraph;
import com.itextpdf.layout.font.FontProvider;
import com.itextpdf.layout.property.TextAlignment;
import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateException;
import freemarker.template.TemplateExceptionHandler;
import org.springframework.stereotype.Component;import javax.annotation.Resource;
import java.io.*;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;@Component
public class FreemarkerExecution {// 準備下字體文件private static String FONT = "./src/main/resources/templates/AlibabaPuHuiTi-3-65-Medium.ttf";// 后續轉pdf時的配置private static ConverterProperties converterProperties = new ConverterProperties();private static String base64LogoData = null;{FontProvider dfp = new DefaultFontProvider();//添加字體庫dfp.addFont(FONT);//設置解析屬性converterProperties.setFontProvider(dfp);converterProperties.setCharset("utf-8");try {// 有一個logo處理,因為一般服務器渲染的話一般建議將部分圖片處理成base64然后放進來,或者大家看看其他的方式base64LogoData = imgToBase64(new FileInputStream("./src/main/resources/templates/logo.png"));} catch (FileNotFoundException e) {e.printStackTrace();}}@Resource(name = "cfg")private Configuration configuration;// 普通處理邏輯public void converterHTML() {// 這個會將處理后的html語法輸出至 命令行窗口,可以手動創建一個html文件,然后把結果復制進去直接打開查看try (Writer out = new OutputStreamWriter(System.out)) {// 獲取數據final PDFData pdfData = getData();Template temp = configuration.getTemplate("pdf.ftl");// 直接寫出文件temp.process(pdfData, out);} catch (IOException e) {e.printStackTrace();} finally {}}private void writeToPDF(Template template, Map<String, Object> dataModel) {try {final File file = new File("D:/pdf/test.html");template.process(dataModel, new OutputStreamWriter(new FileOutputStream(file)));final File pdfFile = new File("D:/pdf/test.pdf");HtmlConverter.convertToPdf(file, pdfFile, converterProperties);PdfReader reader = new PdfReader(new File("D:/pdf/test.pdf"));PdfWriter writer = new PdfWriter(new FileOutputStream("D:/pdf/test_1.pdf"));PdfDocument pdfDocument = new PdfDocument(reader, writer);// 頁大小final PageSize pageSize = pdfDocument.getDefaultPageSize();// 頁數final int numberOfPages = pdfDocument.getNumberOfPages();for (int i = 1; i <= numberOfPages; i++) {PdfPage page = pdfDocument.getPage(i);final PdfDocument pdfDoc = page.getDocument();final Document document = new Document(pdfDoc);final Paragraph paragraph = new Paragraph("Page" + i).setFont(PdfFontFactory.createFont(FONT)).setFontColor(new DeviceRgb(0, 0, 0)).setFixedPosition(i, 0, 10, pageSize.getWidth()).setFontSize(10).setTextAlignment(TextAlignment.CENTER);document.add(paragraph);}pdfDocument.close();reader.close();writer.close();} catch (Exception e) {e.printStackTrace();}}private PDFData getData() throws FileNotFoundException {PDFData data = new PDFData();data.setName("重生之我是蔡徐坤");data.setAddress("蔡徐坤蔡徐坤喜歡唱跳rap籃球");data.setStartTime("01-Feb-22");data.setEndTime("28-Feb-22");data.setLogo("data:image/png;base64," + base64LogoData);final LocalDateTime nowTime = LocalDateTime.now();final List<TableData> arr = new ArrayList<>();for (int i = 0; i < 10; i++) {final TableData tableData = new TableData();tableData .setDesc(i % 2 == 0 ? "交會毫不我交會毫不我噠噠噠噠噠噠多多多多多多多交會毫不我電話電話大" : "交會毫不我交會毫不我噠噠噠噠噠噠多多多多多多多交會毫不我電話電話大交會毫不我交會毫不我噠噠噠噠噠噠多多多多多多多交會毫不我電話電話大交會毫不我交會毫不我噠噠噠噠噠噠多多多多多多多交會毫不我電話電話大交會毫不我交會毫不我噠噠噠噠噠噠多多多多多多多交會毫不我電話電話大交會毫不我交會毫不我噠噠噠噠噠噠多多多多多多多交會毫不我電話電話大交會毫不我交會毫不我噠噠噠噠噠噠多多多多多多多交會毫不我電話電話大交會毫不我交會毫不我噠噠噠噠噠噠多多多多多多多交會毫不我電話電話大交會毫不我交會毫不我噠噠噠噠噠噠多多多多多多多交會毫不我電話電話大交會毫不我交會毫不我噠噠噠噠噠噠多多多多多多多交會毫不我電話電話大交會毫不我交會毫不我噠噠噠噠噠噠多多多多多多多交會毫不我電話電話大交會毫不我交會毫不我噠噠噠噠噠噠多多多多多多多交會毫不我電話電話大交會毫不我交會毫不我噠噠噠噠噠噠多多多多多多多交會毫不我電話電話大交會毫不我交會毫不我噠噠噠噠噠噠多多多多多多多交會毫不我電話電話大");tableData .setName("蔡徐坤" + i);tableData .setFee(1000 + i + "");tableData .setDate(nowTime.plusDays(-i).format(DateTimeFormatter.ofPattern("YYYY/MM/dd")));arr.add(tableData);}data.setList(arr);return data;}private String imgToBase64(InputStream inputStream) {byte[] data = null;try {data = new byte[inputStream.available()];inputStream.read(data);inputStream.close();} catch (IOException e) {e.printStackTrace();}return Base64.getEncoder().encodeToString(data);}
}

這里會又有一個問題出現,就是我們一般處理PDF的時候,數據不可能一次性處理到內存中,因為我們服務器內存等問題,假如我們有100w數據,肯定不能一次性查出來,由此我們就需要批量處理,這里我們可以將模板拆分開,重復的數據放一個模板文件,然后后續進行模板的組裝。

首先,我將一個ftl模板文件拆成了三個 👉 header.ftl,content.ftl,footer.ftl,然后再由一個主的核心ftl模板來組裝這幾個模板。
思路:準備上述模板文件,然后渲染模板后繼續解析成ftl模板文件,然后讀取選然后的ftl模板文件,然后轉成html,最后通過html文件處理成pdf文件。

這里content.ftl是批量的數據,因為不能一次讀取大量數據,所以這里content.ftl要單獨處理一下。

Main.ftl
<!doctype html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport"content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0"><meta http-equiv="X-UA-Compatible" content="ie=edge"><title>Document</title>
</head>
<style>.logo {width: 320px;height: 80px;}.user-info {padding: 10px 10px;background: RGB(221, 235, 247);}.label {width: 150px;padding: 0 20px 0 0;text-align: left;}.time {width: 100px;margin-right: 10px;text-align: center;}.label, .time {display: inline-block;}.range-time {margin: 20px 0;}.table-data {width: 100%;}table {border-collapse: collapse;}.header > th {text-align: left;height: 50px;}.divider-line {margin: 20px 0;height: 3px;background: #000;}.desc {padding: 15px 10px;}.date {width: 100px;}.name {width: 50px;}.fee{width: 140px;}.fee, .name , .date {padding: 0 10px;}.download-date {text-align: right;}.bottom-footer-tip {width: 100%;margin-top: 300px;font-size: 12px;transform: scale(.9);}
</style>
<body>${headerPath}
<table class="table-data"><tr class="header"><th>Date</th><th>Desc</th><th>Name</th><th>Fee</th></tr><tr class="divider-line"><th></th><th></th><th></th><th></th></tr><#list contentPathList as content>${content}</#list><tr class="divider-line"><th></th><th></th><th></th><th></th></tr>
</table>
${footerPath}<#--<#include "header.ftl">-->
<#--<#include "content.ftl">-->
<#--<#include "footer.ftl">--></body>
</html>
header.ftl
<img src="${logo}" class="logo">
<div class="download-date">Download on 2022/2/2</div>
<div class="user-info"><div><div class="label">User:</div><span>${name}</span></div><div><div class="label">Address:</div><span>${address}</span></div>
</div><div class="range-time"><span class="time">${startTime}</span><span>to</span><span class="time">${endTime}</span>
</div>
content.ftl
<#list list as item><tr><td class="date">${item.date}</td><td class="desc"><div>${item.desc}</div></td><td class="fee">${item.fee}</td><td class="name">${item.name}</td></tr></#list>
footer.ftl
<#list list as item><tr><td class="date">${item.date}</td><td class="desc"><div>${item.desc}</div></td><td class="fee">${item.fee}</td><td class="name">${item.name}</td></tr></#list>
核心處理邏輯
    void allTemplatesWriteToPDF() {// 所有子模板final List<String> ftlNameList = new ArrayList<>();try {// 讀取對應的模板文件final Template template = getTemplate("content.ftl");final Template headerTemplate = getTemplate("header.ftl");final Template footerTemplate = getTemplate("footer.ftl");final PDFData data = getData();// 先處理頭部和尾部headerTemplate.process(data, new FileWriter("D:/pdf/content/header.ftl"));footerTemplate.process(data, new FileWriter("D:/pdf/content/footer.ftl"));// mock 模擬數據庫查詢10次for (int i = 0; i < 10; i++) {// 組裝10條數據,算上10次循環一共100條數據final PDFData pdfData = getData();String fileName = "D:/pdf/content/content" + i + ".ftl";final FileWriter writer = new FileWriter(fileName);// 存儲最后框架模板的數據,這里是存儲了freemarker include 語法連接所有的需要組裝的數據模板名稱ftlNameList.add("<#include \"" + fileName.substring(fileName.lastIndexOf("/") + 1, fileName.lastIndexOf(".")) + ".ftl \"/>");// 生成對應的模板文檔template.process(pdfData, writer);writer.flush();writer.close();}// 獲取所有子模板final Configuration cdf = new Configuration(Configuration.VERSION_2_3_22);cdf.setDirectoryForTemplateLoading(new File("D:/pdf/content"));cdf.setDefaultEncoding("UTF-8");cdf.setTemplateExceptionHandler(TemplateExceptionHandler.RETHROW_HANDLER);final Template mainTemplate = getTemplate("main.ftl");final HashMap<Object, Object> map = new HashMap<>();map.put("headerPath", "<#include \"" + "header.ftl\"/>");map.put("contentPathList", ftlNameList);map.put("footerPath", "<#include \"" + "footer.ftl\"/>");mainTemplate.process(map, new FileWriter("D:/pdf/content/main.ftl"));final Template cdfTemplate = cdf.getTemplate("main.ftl");cdfTemplate.process(null, new FileWriter("D:/pdf/content/main.html"));final File pdfFile = new File("D:/pdf/test_new.pdf");HtmlConverter.convertToPdf(new File("D:/pdf/content/main.html"), pdfFile, converterProperties);PdfReader reader = new PdfReader(pdfFile);PdfWriter writer = new PdfWriter(new FileOutputStream("D:/pdf/test_new_1.pdf"));PdfDocument pdfDocument = new PdfDocument(reader, writer);// 頁大小final PageSize pageSize = pdfDocument.getDefaultPageSize();// 頁數final int numberOfPages = pdfDocument.getNumberOfPages();// 這里是處理頁腳數據for (int i = 1; i <= numberOfPages; i++) {PdfPage page = pdfDocument.getPage(i);final PdfDocument pdfDoc = page.getDocument();final Document document = new Document(pdfDoc);final Paragraph paragraph = new Paragraph("Page" + i).setFont(PdfFontFactory.createFont(FONT)).setFontColor(new DeviceRgb(0, 0, 0)).setFixedPosition(i, 0, 10, pageSize.getWidth()).setFontSize(10).setTextAlignment(TextAlignment.CENTER);document.add(paragraph);}pdfDocument.close();reader.close();writer.close();} catch (IOException | TemplateException e) {e.printStackTrace();}}private Template getTemplate(String name) throws IOException {return configuration.getTemplate(name);}

在這里插入圖片描述

在這里插入圖片描述

OK,大概就這樣,剩下的大家自己去玩吧, 解散!!!

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

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

相關文章

【IDEA】maven如何進行文件導入,配置并打包

一&#xff0c;介紹、安裝 1、maven介紹 maven是一個Java世界中&#xff0c;構建工具。 核心功能&#xff1a; (1) 管理依賴&#xff1a; 管理文件運行的順序邏輯依賴關系。對配置文件&#xff0c;進行構建和編譯。其也是在調用jdk&#xff0c;來進行編譯打包工作。 (2) 打…

JavaScript中的原型和原型鏈

一、原型&#xff1a;每個函數都有prototype屬性&#xff0c;稱之為原型&#xff0c;這個屬性也是個對象所以也稱之為原型對象。 1.原型可以放一些屬性和方法&#xff0c;供實例對象使用。 <body><script>const arr new Array(1,3,5,7,6)document.getElementByI…

Go語言--延遲調用defer、獲取命令行參數、局部變量以及全局變量

延遲調用defer 關鍵字 defer 用于延遲一個函數或者方法(或者當前所創建的匿名函數)的執行。注意&#xff0c;defer語句只能出現在函數或方法的內部。 defer 語句經常被用于處理成對的操作&#xff0c;如打開、關閉、連接、斷開連接、加鎖、釋放鎖。通過defer 機制&#xff0…

NASA——quarius(水瓶座) L3 網格化 1 度年土壤濕度,第 5 版

Aquarius L3 Gridded 1-Degree Annual Soil Moisture V005 水瓶座 L3 網格化 1 度年土壤濕度&#xff0c;第 5 版 簡介 該數據集包含美國國家航空航天局&#xff08;NASA&#xff09;科學應用衛星&#xff08;SAC-D&#xff09;上的寶瓶座被動微波輻射計得出的第 3 級網格化…

SLAM 精度評估

SLAM 精度的評估有兩個最重要的指標&#xff0c;即絕對軌跡誤差&#xff08;ATE&#xff09;和相對位姿誤差&#xff08;RPE&#xff09;的 均方根誤差&#xff08;RMSE&#xff09;: 絕對軌跡誤差:直接計算相機位姿的真實值與 SLAM 系統的估計值之間的差值&#xff0c;首先將…

交換機基本原理

文章目錄 前言一、交換機的轉發行為二、交換機的轉發原理1.MAC地址表2.交換機初始狀態3.學習MAC地址4.ARP協議5.交換機轉發數據幀6.目標主機回復 三、華為交換機基本命令1.VRP視圖分層2.命令行補全3.命令行幫助4.配置設備名稱5.命令等級6.用戶界面7.配置console認證8.配置用戶界…

python-Django項目:圖書后臺管理系統

具體操作&#xff1a;請參考 Django項目&#xff1a;圖書后臺管理系統

基于深度學習的圖像補全

基于深度學習的圖像補全是一項利用深度學習技術來填補圖像中缺失區域的研究領域。這項技術可以有效地恢復損壞或不完整的圖像&#xff0c;使其變得完整和自然&#xff0c;廣泛應用于圖像修復、圖像編輯、視頻恢復和增強現實等領域。以下是關于這一領域的系統介紹&#xff1a; …

運維鍋總詳解計算機緩存

本文從OSI模型中的每一層緩存介紹、常見開源中間件緩存舉例、TCP/IP協議棧中的緩存機制、操作系統中的緩存、訪問緩存數據的時間范圍統計等方面對計算機中的緩存進行詳細介紹。希望對您有所幫助&#xff01; 一、OSI模型中的每一層緩存 1. 物理層&#xff08;Physical Layer&…

Unity--異步加載場景

Unity–異步加載場景 異步加載場景其實和異步加載資源是一樣的,只是加載的內容比較特殊而已. 也可以將場景視為特殊資源. 1.SceneManager.LoadScene 加載場景的方式,在Unity 中加載場景是通過SceneManager.LoadScene("場景名稱"); 來實現加載場景,這和UE4中的Open…

如何在Java中實現批量數據處理

如何在Java中實現批量數據處理 大家好&#xff0c;我是免費搭建查券返利機器人省錢賺傭金就用微賺淘客系統3.0的小編&#xff0c;也是冬天不穿秋褲&#xff0c;天冷也要風度的程序猿&#xff01; 1. 引言 在大數據時代&#xff0c;處理大量數據是許多應用程序中必不可少的需…

自動化立體倉庫出入庫能力及堆垛機節拍

導語 大家好&#xff0c;我是社長&#xff0c;老K。專注分享智能制造和智能倉儲物流等內容。 新書《智能物流系統構成與技術實踐》人俱樂部 完整版文件和更多學習資料&#xff0c;請球友到知識星球【智能倉儲物流技術研習社】自行下載 自動化立體倉庫的出入庫能力、堆垛機節拍以…

安全協議:SSL/TLS與Java實現

在當今的互聯網環境中&#xff0c;數據安全至關重要。SSL&#xff08;Secure Sockets Layer&#xff09;和其繼任者TLS&#xff08;Transport Layer Security&#xff09;是確保數據在網絡中安全傳輸的關鍵技術。本文將詳細介紹SSL/TLS協議的工作原理&#xff0c;并通過Java代碼…

掌握電路交換與分組交換:計算機網絡的核心技術

計算機網絡是現代信息社會的基石&#xff0c;而交換技術是實現網絡通信的核心。本文將詳細介紹兩種典型的交換方式&#xff1a;電路交換和分組交換&#xff0c;幫助基礎小白快速掌握這兩種技術的基本概念和區別。 什么是電路交換&#xff1f; 電路交換&#xff08;Circuit Swi…

Java中的服務化架構設計與實現

Java中的服務化架構設計與實現 大家好&#xff0c;我是免費搭建查券返利機器人省錢賺傭金就用微賺淘客系統3.0的小編&#xff0c;也是冬天不穿秋褲&#xff0c;天冷也要風度的程序猿&#xff01; 1. 引言 隨著軟件系統規模的不斷擴大和業務需求的增加&#xff0c;傳統的單體…

CentOS7開啟sshd失敗解決方法

Could not load host key: /etc/ssh/ssh_host_rsa_key Could not load host key: /etc/ssh/ssh_host_ecdsa_key Could not load host key: /etc/ssh/ssh_host_ed25519_key sshd: no hostkeys available – exiting. 1、檢查主機密鑰文件是否存在 ls -l /etc/ssh/ssh_host_*2、…

Centos系統遷移

目前&#xff0c;CentOS 全系列版本已經于l六月底正式停止維護&#xff0c;這意味著 CentOS 時代徹底終結&#xff0c;也意味著部署在 CentOS 7 上的業務系統將面臨前所未有的安全挑戰。 本文推薦由紅帽衍生出來的且可以做到真正無縫替代的linux版本Open Euler 注&#xff1a…

【前端】面試八股文——輸入URL到頁面展示的過程

【前端】面試八股文——輸入URL到頁面展示的過程 1. DNS解析 當用戶在瀏覽器中輸入URL并按下回車時&#xff0c;首先需要將域名轉換為IP地址&#xff0c;這個過程稱為DNS&#xff08;域名系統&#xff09;解析。具體步驟如下&#xff1a; 瀏覽器緩存&#xff1a;瀏覽器首先檢…

科普文:Linux服務器性能調優概敘

概敘 Java web應用性能分析之服務端慢和優化概敘_cpu飆高java-CSDN博客 Java web應用性能分析之【CPU飆升分析概述】_web頁面性能分析cpu占滿是因為死循環,還是循環過多-CSDN博客 在我們的軟件服務中&#xff0c;軟件部署的服務器&#xff0c;一般都是linux服務器&#xff0c…