【springmvc thymeleaf】springmvc整合thymeleaf


概述

Thymeleaf提供了一組Spring集成,使您可以將其用作Spring MVC應用程序中JSP的全功能替代品。

這些集成將使您能夠:

  • @Controller像使用JSP一樣,將Spring MVC 對象中的映射方法轉發到Thymeleaf管理的模板。
  • 在模板中使用Spring表達式語言(Spring EL)代替OGNL。
  • 在與表單支持Bean和結果綁定完全集成的模板中創建表單,包括使用屬性編輯器,轉換服務和驗證錯誤處理。
  • 顯示Spring管理的消息文件中的國際化消息(通過常規MessageSource對象)。
  • 使用Spring自己的資源解析機制解析您的模板。

thymeleaf自己也做了spring的集成,所以我們並不需要做太多的配置,就可以達到我們想要的結果。thymeleaf提供了兩種集成方法:①、注解配置,也就是java代碼,②、xml文件配配置,本文主要介紹第二種xml配置。

你能get到的知識點:

1、springmvc整合thymeleaf
2、spring提供的三種model的使用
3、解決html前端thymeleaf不生效問題(見問題1)
4、解決html前端顯示亂碼問題(見問題2)

@

springmvc整合thymeleaf

一:加入依賴

在springmvc里面,除了要加入thymeleaf的主依賴之外,還需要thymeleaf-spring4,否則會報org.thymeleaf.spring4.view.ThymeleafViewResolver,找不到thymeleaf解析器,所以thymeleaf-spring4也是必不可少的。

Thymeleaf具有針對Spring Framework 3.x和4.x的集成,由兩個獨立的庫分別稱為thymeleaf-spring3和提供thymeleaf-spring4。這些庫打包在單獨的.jar文件(thymeleaf-spring3-{version}.jar和thymeleaf-spring4-{version}.jar)中,需要添加到類路徑中,以便在應用程序中使用Thymeleaf的Spring集成

        <!--        thymeleaf-->
        <dependency>
            <groupId>org.thymeleaf</groupId>
            <artifactId>thymeleaf-spring4</artifactId>
            <version>3.0.11.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.thymeleaf</groupId>
            <artifactId>thymeleaf</artifactId>
            <version>3.0.11.RELEASE</version>
        </dependency>

二:設置thymeleaf解析器

在springmvc配置文件中配置thymeleaf解析器,官方文檔中Thymeleaf提供了上述兩個接口的實現:

org.thymeleaf.spring4.view.ThymeleafView
org.thymeleaf.spring4.view.ThymeleafViewResolver

不過現在都已經被org.thymeleaf.spring4.view.ThymeleafViewResolver所代替,至於以上配置是否還能夠生效,就要靠你來試試了。

 <!-- thymeleaf 模板解析器 -->
    <bean id="templateResolver" class="org.thymeleaf.spring4.templateresolver.SpringResourceTemplateResolver">
        <property name="prefix" value="/" />
        <property name="suffix" value=".html" />
        <property name="templateMode" value="HTML" />
        <property name="cacheable" value="false" />
        <property name="characterEncoding" value="UTF-8"/>
    </bean>

    <bean id="templateEngine" class="org.thymeleaf.spring4.SpringTemplateEngine">
        <property name="templateResolver" ref="templateResolver" />
    </bean>

    <!--    視圖解析器-->
    <bean id="viewResolver" class="org.thymeleaf.spring4.view.ThymeleafViewResolver">
        <property name="templateEngine" ref="templateEngine" />
        <property name="characterEncoding" value="UTF-8"/>
    </bean>

ViewResolvers是負責獲取特定操作和語言環境的View對象的對象。通常,控制器要求ViewResolvers轉發到具有特定名稱的視圖(由controller方法返回的String),然后應用程序中的所有視圖解析器將按有序鏈執行,直到其中一個能夠解析該視圖為止。如果返回了View對象,並且將控件傳遞給該對象以呈現HTML。

注:值得注意的是,如果自己設置了spring的視圖解析器,需要將其注釋掉,否則thymeleaf解析器可能不會生效,我就是因為這個調試了好久,最后才發現這個問題。

    <!--    配置視圖解析器 prefix:前綴, suffix:后綴   使用thymeleaf需要將其注釋掉-->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/"/>
        <property name="suffix" value=".html"/>
    </bean>

三:編寫控制器

需要從控制層傳數據到視圖時,我們就會使用model,常用的三種model就是:Model、ModelMap、ModelAndView。使用這三種model時,spring框架自動創建實例並作為controller的入參,用戶無需自己創建

1、使用Model

    /**
     * 在Model里存入一個用戶信息
     * @return hello頁面
     */
    @GetMapping("returnModelAndView")
    public String returnModelAndView(Model model){
        model.addAttribute("userInfo",new UserInfo("lomtom","123",new Address("湖南","邵陽")));
        return "hello";
    }

Model是一個接口,
Model源碼:

public interface Model {
    Model addAttribute(String var1, Object var2);

    Model addAttribute(Object var1);

    Model addAllAttributes(Collection<?> var1);

    Model addAllAttributes(Map<String, ?> var1);

    Model mergeAttributes(Map<String, ?> var1);

    boolean containsAttribute(String var1);

    Map<String, Object> asMap();
}

2、使用ModelMap

ModelMap繼承LinkedHashMap
ModelMap源碼:

public class ModelMap extends LinkedHashMap<String, Object> {
    public ModelMap() {
    }

    public ModelMap(String attributeName, Object attributeValue) {
        this.addAttribute(attributeName, attributeValue);
    }

    public ModelMap(Object attributeValue) {
        this.addAttribute(attributeValue);
    }

    public ModelMap addAttribute(String attributeName, Object attributeValue) {
        Assert.notNull(attributeName, "Model attribute name must not be null");
        this.put(attributeName, attributeValue);
        return this;
    }

    public ModelMap addAttribute(Object attributeValue) {
        Assert.notNull(attributeValue, "Model object must not be null");
        return attributeValue instanceof Collection && ((Collection)attributeValue).isEmpty() ? this : this.addAttribute(Conventions.getVariableName(attributeValue), attributeValue);
    }

    public ModelMap addAllAttributes(Collection<?> attributeValues) {
        if (attributeValues != null) {
            Iterator var2 = attributeValues.iterator();

            while(var2.hasNext()) {
                Object attributeValue = var2.next();
                this.addAttribute(attributeValue);
            }
        }

        return this;
    }

    public ModelMap addAllAttributes(Map<String, ?> attributes) {
        if (attributes != null) {
            this.putAll(attributes);
        }

        return this;
    }

    public ModelMap mergeAttributes(Map<String, ?> attributes) {
        if (attributes != null) {
            Iterator var2 = attributes.entrySet().iterator();

            while(var2.hasNext()) {
                Entry<String, ?> entry = (Entry)var2.next();
                String key = (String)entry.getKey();
                if (!this.containsKey(key)) {
                    this.put(key, entry.getValue());
                }
            }
        }

        return this;
    }

    public boolean containsAttribute(String attributeName) {
        return this.containsKey(attributeName);
    }
}

3、使用ModelAndView

    /**
     * 在ModelAndView里存入一個用戶信息
     * @return ModelAndView 
     */
    @GetMapping("returnModelAndView")
    public ModelAndView returnModelAndView(ModelAndView modelAndView){
        modelAndView.setViewName("hello");
        modelAndView.addObject("userInfo",new UserInfo("lomtom","123",new Address("湖南","邵陽")));
        return modelAndView;
    }

ModelAndView顧名思義就是模型和試圖的結合。
ModelAndView源碼:

public class ModelAndView {
    private Object view;
    private ModelMap model;
    private HttpStatus status;
    private boolean cleared = false;

	......
}

四:編寫html

首先,寫一個鏈接,請求returnModelAndView請求。

<a href="returnModelAndView">ModelAndView</a>

然后,寫hello.html頁面用於驗證

<h2>你好啊,你成功了</h2>
<p th:text="${userInfo.userName}+'來自'+${userInfo.address.province}+${userInfo.address.city}"></p>

五:結果

六:記錄我遇到的問題

問題1:配置好一切后,thymeleaf無法解析,所有關於thymeleaf的顯示都無法生效。
解決:由於我配置了spring的視圖解析,所以導致thymeleaf的試圖解析無法生效,所以去掉spring的視圖解析。

thmelaf介紹Springmvc的視圖解析:
快速瀏覽其屬性足以了解其配置方式:

  • viewClass建立View實例的類。對於JSP解析器,這是必需的,但是當我們與Thymeleaf合作時,根本不需要。
  • prefix與suffixThymeleaf的TemplateResolver對象中相同名稱的屬性的工作方式相似。
  • order 確定在鏈中查詢ViewResolver的順序。
  • viewNames 允許使用此ViewResolver解析視圖名稱(帶通配符)。

問題2:前端顯示亂碼,具體表現為后台傳入的不亂碼,但是html中原本存在的亂碼。
解決:在試圖解析器和模板解析器中加入參數:<property name="characterEncoding" value="UTF-8"/>

作者有話

我寫的可能並不怎么詳細,詳細配置請查看thymeleaf官方介紹:傳送門,到最后,看都看完了,如果對你有幫助,請點個贊吧。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM