溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

SpringBoot如何整合Thymeleaf

發布時間:2021-07-06 14:02:31 來源:億速云 閱讀:250 作者:小新 欄目:開發技術

這篇文章給大家分享的是有關SpringBoot如何整合Thymeleaf的內容。小編覺得挺實用的,因此分享給大家做個參考,一起跟隨小編過來看看吧。

1. 問題需求分析

  • 在做樂優商城時,頁面是通過Thymeleaf模板引擎渲染后返回到客戶端。當商品詳情頁數據渲染時,在后臺需要大量的數據查詢,而后渲染得到HTML頁面。在用戶訪問量大的情況下會對數據庫造成壓力,并且請求的響應時間過長,并發能力不高。

如何解決?

  • 一般我們優先會考慮使用緩存技術,比如 Redis 分布式緩存,Guava 本地緩存等。然而 Redis 只適合數據規模比較小的情況,假如數據量比較大,例如商品詳情頁,每個頁面如果10kb,100萬商品,就是10GB空間,對內存占用比較大。此時就給緩存系統帶來極大壓力,如果緩存崩潰,接下來倒霉的就是數據庫了。

  • 所以緩存并不是萬能的,某些場景需要其它技術來解決,比如靜態化技術。

2. 什么是靜態化?

  • 靜態化是指把動態生成的HTML頁面變為靜態內容保存,以后用戶的請求到來,直接訪問靜態頁面,不再經過服務的渲染。

  • 而靜態的HTML頁面可以部署在nginx中,從而大大提高并發能力,減小tomcat壓力。

3. 如何實現靜態化?

目前,靜態化頁面都是通過模板引擎來生成,而后保存到nginx服務器來部署。常用的模板引擎比如:

  • Freemarker

  • Velocity

  • Thymeleaf

樂優項目中使用的是Thymeleaf 模板引擎!

4. Thymeleaf實現靜態化

4.1 概念介紹

Thymeleaf 模板引擎實現頁面靜態化的幾個概念介紹:

  • Context:運行上下文

  • TemplateResolver:模板解析器

  • TemplateEngine:模板引擎

Context:

Thymeleaf 模板中的上下文: 用來保存模型數據,當模板引擎渲染時,可以從Context上下文中獲取數據用于渲染。

當與Spring Boot結合使用時,我們放入Model的數據就會被處理到Context,作為模板渲染的數據使用。

TemplateResolver:

Thymeleaf 模板中的模板解析器:用來讀取模板相關的配置,例如:模板存放的位置信息,模板文件名稱,模板文件的類型等等。

當與SpringBoot結合時,TemplateResolver已經由其創建完成,并且各種配置也都有默認值,比如模板存放位置,其默認值就是:templates。比如模板文件類型,其默認值就是html。

TemplateEngine:

Thymeleaf 模板中的模板引擎:用來解析模板的引擎,需要使用到上下文、模板解析器。分別從兩者中獲取模板中需要的數據,模板文件。然后利用內置的語法規則解析,從而輸出解析后的文件。來看下模板引擎進行處理的函數:

templateEngine.process("模板名", context, writer);
三個參數:
  • 模板名稱

  • 上下文:里面包含模型數據

  • writer:輸出目的地的流

在輸出時,我們可以指定輸出的目的地,如果目的地是Response的流,那就是網絡響應。如果目的地是本地文件,那就實現靜態化了。

而在SpringBoot中已經自動配置了模板引擎,因此不需要關心這個。我們做靜態化,就是把輸出的目的地改成本地文件即可!

4.2 具體實現

GoodsHtmlService

/**
 * @Auther: csp1999
 * @Date: 2020/12/16/19:43
 * @Description: 生成HTML頁面的Service
 */
@Service
public class GoodsHtmlService {
    // themleaf 模板引擎
    @Autowired
    private TemplateEngine templateEngine;
    @Autowired
    private GoodsService goodsService;
    /**
     * 根據spuId 將對應的商品詳情頁面生成HTML靜態頁面
     *
     * @param spuId
     */
    public void createHTML(Long spuId) {
        // 初始化運行上下文: org.thymeleaf.context 包下
        Context context = new Context();
        // 設置數據模板
        // 從goodsService.loadData(spuId) 方法中獲取模板頁面中需要渲染的數據
        context.setVariables(goodsService.loadData(spuId));
        // 獲取輸出流
        // 將需要輸出的html 文件地址設置為服務器中的nginx 目錄下的html 目錄中的item文件夾下(我這里nginx 部署的是win10本地?。?
        File file = new File(
                "M:\\note\\MyProjects\\leyou\\tools\\nginx-1.14.0\\html\\item\\" + spuId + ".html");
        PrintWriter writer = null;
        try {
            writer = new PrintWriter(file);
            // 模板引擎生成靜態html 頁面
            templateEngine.process("item", context, writer);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } finally {
            // 判斷并關閉流
            if (writer != null) {
                writer.close();
            }
        }
    }
    /**
     * 新建線程處理頁面靜態化
     *
     * @param spuId
     */
    public void asyncExcute(Long spuId) {
        ThreadUtils.execute(() -> createHTML(spuId));
        /*ThreadUtils.execute(new Runnable() {
            @Override
            public void run() {
                createHtml(spuId);
            }
        });*/
    }
}

多線程工具類ThreadUtils

/**
 * @Auther: csp1999
 * @Date: 2020/12/16/20:18
 * @Description: 多線程工具類
 */
public class ThreadUtils {
    private static final ExecutorService es = Executors.newFixedThreadPool(10);
    public static void execute(Runnable runnable) {
        es.submit(runnable);
    }
}

GoodsController

在調用GoodsController訪問商品頁面的同時生成緩存的頁面:

/**
 * @Auther: csp1999
 * @Date: 2020/12/16/10:00
 * @Description: 
 */
@Controller
public class GoodsController {
    @Autowired
    private GoodsService goodsService;
    @Autowired
    private GoodsHtmlService goodsHtmlService;
    /**
     * 商品詳情也頁面
     *
     * @param id
     * @param model
     * @return
     */
    @GetMapping("/item/{id}.html")
    public String toItemPage(@PathVariable("id") Long id, Model model) {
        Map<String, Object> map = goodsService.loadData(id);
        model.addAllAttributes(map);
        // 頁面靜態化:調用createHTML(id) 方法生成靜態頁面并保存到服務器的nginx 對應目錄下緩存
        // 通過多線程方式:
        goodsHtmlService.asyncExcute(id);
//        goodsHtmlService.createHTML(id);
        return "/item";
    }
}

注意:生成html 的代碼不能對用戶請求產生影響,所以這里我們使用額外的線程進行異步創建。

5. nginx 中進行訪問配置

# 前端前臺相關配置
server {
    listen       80;
    server_name  www.leyou.com;
    proxy_set_header X-Forwarded-Host $host;
	proxy_set_header X-Forwarded-Server $host;
	proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
	# 如果是以item 開頭的路徑,代理到前臺8084端口
	# eg: www.leyou.com/item/4586.html
	location /item {
		# 先到本地nginx 路徑下的html文件夾 中找頁面,如果有則走該頁面(相當于緩存效果)
		root html;
		if (!-f $request_filename) { # 如果請求的文件不存在,就反向代理,通過請求去訪問該頁面
			proxy_pass http://127.0.0.1:8084;
			break;
		}
	}
	# 代理到前臺9002端口
	location / {
		proxy_pass http://127.0.0.1:9002;
		proxy_connect_timeout 600;
		proxy_read_timeout 600;
	}
}

nginx 代理的流程圖:

SpringBoot如何整合Thymeleaf

6. 訪問頁面測試

第一次訪問頁面:

SpringBoot如何整合Thymeleaf

nginx路徑下的html/item/下生成了該頁面的靜態資源:

SpringBoot如何整合Thymeleaf

第二次訪問該頁面:

SpringBoot如何整合Thymeleaf

感謝各位的閱讀!關于“SpringBoot如何整合Thymeleaf”這篇文章就分享到這里了,希望以上內容可以對大家有一定的幫助,讓大家可以學到更多知識,如果覺得文章不錯,可以把它分享出去讓更多的人看到吧!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

亚洲午夜精品一区二区_中文无码日韩欧免_久久香蕉精品视频_欧美主播一区二区三区美女