zoukankan      html  css  js  c++  java
  • 【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官方介绍:传送门,到最后,看都看完了,如果对你有帮助,请点个赞吧。

  • 相关阅读:
    springboot注解@NotNull,@NotBlank,@Valid自动判定空值
    idea打包java可执行jar包
    Spring Boot 默认支持的并发量
    SpringBoot+MyBatis+MySQL读写分离
    Spring+MyBatis实现数据库读写分离方案
    分布式数据库中间件、产品——sharding-jdbc、mycat、drds
    数据库分库分表、读写分离的原理实现,使用场景
    Mono 3.2.3 Socket功能迎来一稳定的版本
    .NET代码树执行时间计时器
    .net好好地利用Conditional属性
  • 原文地址:https://www.cnblogs.com/lomtom/p/12635945.html
Copyright © 2011-2022 走看看