SpringBoot+Thymeleaf实现html文件引入(类似include功能)

 
 

由于对高大上的前端处理不太熟悉,想直接通过MVC的方式进行内容传递,因此选用了Thymeleaf模版处理向前端传值的问题。 但是觉得很多PHP框架所实现的include模版的方式很不错,能够很好的实现头文件、导航、页尾等和主要内容的解耦,因此想通过使用Thymeleaf模版的同时,也能实现类似于include的功能。


思路和背景

觉得如果有精力,最好还是RESTFul的结构,然后前端采用angularjs之类的方式来处理可能更合理,由于不太懂前端,所以只是自己yy一下

言归正传,环境主要是采用了spring boot框架,外加Thymeleaf进行构建的。主要的思路就是通过使用Thymeleaf的"th:utext()"方式,在后端处理中,将预留的头文件、导航等通过ModelMap映射到实际的网页中。


实际操作

1. 背景

首先配置一个可以运行的Spring boot+Thymeleaf项目,具体教程很多,就不啰嗦了。

然后采用了默认的目录配置,大致如下: resource   static ——(默认的静态文件目录)   templates ——(默认的Thymeleaf模版目录)   application.properties

2. 基本处理

之后的在模版文件中需要include到其它内容的部分采用th:utext()函数把相关部分标注出来,并且在controller中把相关内容加载到ModelMap中,大概是这个样子的 模版文件部分:

<header class="am-topbar admin-header" th:utext="${headerContent}">
  <div class="am-topbar-brand">
    <strong>创澳商务</strong> <small>交易者系统</small>
  </div>  
</header>

后台处理部分:

@RequestMapping("/background")
    private String backgroud(ModelMap map){
        map.addAttribute("headerContent", "hello word!");
        return "background";
    }

3. 所见即所得的方式

因为经常可能需要修改模版文件(html)使得达到预期的效果,而Thymeleaf等框架最大的一个特典就是前端的设计和后端的实现可以得以分离 (因为直接使用的是html的文件,即使不需要服务器也能通过浏览器直接浏览设计好的模版文件),所以我们就希望能够引入的也是html文件,这也符合include功能的基本构思。所以在项目中引入了Jsoup包来解决遍历dom文件的问题。当然这个完全过程完全可以略过,直接用个txt或者json啥的

当然也可以选择其它广泛使用的dom遍历工具,只是在这里想安利一下这个jsoup这个包。jsoup的选择器语法和JQuery等前端工具的语法基本一致,对于习惯了JQuery的人真是一个福音……
具体配置如下:
加入maven依赖

      <dependency>
          <groupId>org.jsoup</groupId>
          <artifactId>jsoup</artifactId>
          <version>1.9.2</version>
      </dependency>

采用selector获取element,得到内容

map.addAttribute("headerContent", doc.select("header").toString());
map.addAttribute("sideBarContent", doc.select("#admin-offcanvas").first().toString());

通过这么操作之后,就实现了可以通过html直接设计页面,之后通过后台程序include到前端页面了。

4. include头部引用

对于一般的导航部分(如div)等,只要进行进行了以上处理就ok了,但是既然是想实现include类似的功能,分离head中的各种引用就自然是必须的了。不然每次如果改了需要引用的css或者js都要重新每个文件都要修改,想想都头疼。

但是问题在于,在通过使用ModelMap引用头部link的时候,下面这种处理是得不到解析的。那么我们的css和js的引用自然就乱套了。

th:href="@{/css/main.css}"

解决的方案应该很多,我在处理的时候,主要是通过利用框架自身的特点,将所有的css文件都放在了static文件夹里面(spring boot默认存放的静态资源的地方),然后直接通过写死href值的方式来解决这一问题的(href="css/main.css")。

当然我觉得应该可能还有更好的方案,也请大家指教一下~

5. static下面css文件可能不一致的问题

虽然我们解决了link和script等引入文件路径的问题,但是将href写死又引入了新一个问题,我们没有办法直接使用static下面的css文件,因为html文件都处于templates下面,而且如果我们想在templates下面新建跟多文件夹,虽然通过服务器能够正常引入到正确的css文件,但是不能直接通过浏览器进行页面的设计和编辑,也就是违反了我们之前提到的前端的设计和后端的实现分离的特点。

为了进一步解决这个问题,虽然可以简单的就在templates文件夹下面拷贝一份css文件(如果想新建更多子文件夹的,那每个文件夹下面都需要拷贝一份css文件),但是显然这个方案一点都不够优雅,而且可能会由于忘记同步css文件造成服务器显示和设计显示不一致的问题。

那么为了要优雅,不要污,我采用了一种新的方案,就是html文件中直接写入到static文件夹下css的href,而再服务器引入的时候,通过将static等前缀进行删除,来得到新的href的方式,保证了使用同一份css的同时,也可以分离前端的设计和后端的实现。而且由于路径中都含有static这个特征,直接使用substring功能真是爽翻了。具体实现如下:

   public void getNavigation(Integer naviType,ModelMap map){               
       String fileUrl = templateUrl;
       switch(naviType){
           case 1:
               //admin navigatioin
               fileUrl = fileUrl + "header_admin.html";
               break;
           case 2:
               //user navigation
               fileUrl = fileUrl + "header_trader.html";
               break;
           default:
               fileUrl = fileUrl + "header_trader.html";
               break;
       }       
       try {
           InputStream input = this.getClass().getResourceAsStream(fileUrl);
           Document doc = Jsoup.parse(input,"UTF-8","http://www.mychuangao.com/");
           map.addAttribute("headerContent", doc.select("header").toString());
           map.addAttribute("sideBarContent", doc.select("#admin-offcanvas").first().toString());
           map.addAttribute("footerContent", changeAttrAddress(doc.select("footer"),"script","src"));
           map.addAttribute("headContent", changeAttrAddress(doc.select("head"),"link","href"));
       } catch (IOException e) {
           logger.error("error when using jsoup");
           logger.error(e.getMessage());
           map.addAttribute("headContent", "");
           map.addAttribute("headerContent", "");
           map.addAttribute("sideBarContent", "");
           map.addAttribute("footerContent", "");
       }
   }
   
   private String changeAttrAddress(Elements parentNode,String dealingNodeName,String attrName){
       Elements elements = parentNode.select(dealingNodeName);
       for(Element elment : elements){
           String orignalAddress = elment.attr(attrName);
           if(orignalAddress.isEmpty()){
               continue;
           }
           orignalAddress = delInnerPath(orignalAddress);
           elment.attr(attrName,orignalAddress);
       }
       return parentNode.toString();
   }
   
   private String delInnerPath(String address){
       String keyWord = "static";
       if(address.contains(keyWord)==false){
           return address;
       }
       int position = address.indexOf(keyWord) + keyWord.length() + 1;
       return address.substring(position);
   }

注意点

  1. 注意要使用th:utext()函数,而非th:text()函数,原因你懂的~
  2. 处理路径时,如果使用了获取绝对路径的方式,可能会造成访问权限问题,在web项目中要慎重
  3. 大家可以根据自己的需求更改spring boot和Thymeleaf的文件目录,具体可以参考修改spring boot默认目录


作者:朱端的一坨
链接:https://www.jianshu.com/p/acee38389266
來源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
## springboot整合thymeleaf ### 1. 导入起步依赖 ```xml org.springframework.boot spring-boot-starter-thymeleaf ``` ### 2. 更改引入版本 ```xml 3.0.2.RELEASE 2.1.1 ``` > 1. springboot自带的thymeleaf依赖为2.1.3版本,使用thymeleaf-layout-dialect版本为2以下版本。 > 2. 使用3或3以上的thymeleaf时,需要thymeleaf-layout-dialect的版本为2或以上。 > 3. 锁定thymeleaf版本时不能使用thymeleaf.version标签,会和springboot内部的依赖标签冲突。应当使用springboot-thymeleaf.version标签来锁定版本。 ### 3. 配置文件配置 ```properties spring.thymeleaf.prefix=classpath:/templates/ spring.thymeleaf.check-template-location=true spring.thymeleaf.suffix=.html spring.thymeleaf.encoding=UTF-8 spring.thymeleaf.content-type=text/html spring.thymeleaf.mode=HTML spring.thymeleaf.cache=false ``` > spring.thymeleaf.cache为缓存,需要热部署时,需要设置为false ## 语法 ### 1. 替换标签体内容 ```html 显示欢迎 显示欢迎 ``` ### 2. 替换属性 ```html 显示欢迎 ``` ### 3. 在表达式中访问属性域 ```html 访问属性域 访问请求域 方式一 访问请求域 方式二 访问Session域 访Session域 方式一 访问Application域 方式一 ``` ### 4. 解析url地址 ```html 解析URL地址,获取ContextPath的值 @{}是把ContextPath的值附加到指定的地址前 @{}是把ContextPath的值附加到指定的地址前 ``` ### 5. 直接执行表达式 ```html 直接执行表达式 无转义效果 : [[${attrRequestScope}]] 有转义效果 : [(${attrRequestScope})] ``` ### 6. 分支与迭代 #### 1. if 判断 ```html if判断字符串是否为空 attrRequestScope不为空显示 ~~~attrRequestScope为空显示~~~~ ``` #### 2. 测试循环 ```html 测试循环 ``` > 1. 使用th:each进行集合数据迭代 > 2. th:each="声明变量:${集合}" > 3. th:each 用在哪个标签上,哪个标签就会出现多次 ### 7. 引入外部代码 1. 要被引入的代码 include/part.html ```html 被包含的内容1111 被包含的内容2222 被包含的内容3333 ``` 2. 需要引入的页面 ```html ``` 3. 渲染后的页面源码 ```html 被包含的内容1111 被包含的内容2222 被包含的内容3333 ``` > 1. " :: "左边的值拼前后缀后必须能够找到要包含的文件。 > 2. " :: " 右边的值是代码片段的名字 ,就是th:fragment的值。 > 3. insert将代码原样引入。 > 4. replace使用被引入的代码和属性替换原有的。 > 5. include使用被引入的代码div内部的代码。
Spring Boot是一个开源的Java开发框架,用于快速构建基于Spring的应用程序。Thymeleaf是一个Java的服务器端模板引擎,可以与Spring Boot框架很好地集成。 要实现HTML页面之间的跳转,可以使用Thymeleaf的语法结合Spring Boot的控制器来完成。 首先,需要在pom.xml文件中添加Thymeleaf的依赖: ```xml <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> </dependency> ``` 接下来,在Spring Boot的控制器中添加一个处理请求的方法,该方法返回要跳转的HTML页面的名称: ```java @Controller public class MyController { @RequestMapping("/hello") public String hello() { return "hello"; // 这里返回的是要跳转的HTML页面的名称,不需要后缀名 } } ``` 然后,在resources/templates目录下创建名为hello.htmlHTML页面,用于展示hello页面的内容: ```html <!DOCTYPE html> <html lang="en" xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8"> <title>Hello</title> </head> <body> <h1>Hello, Thymeleaf!</h1> </body> </html> ``` 最后,启动Spring Boot应用程序,在浏览器中访问http://localhost:8080/hello,即可看到跳转到hello.html页面,并显示"Hello, Thymeleaf!"的信息。 以上就是使用Spring Boot和Thymeleaf实现HTML页面跳转的简单示例。通过Thymeleaf的语法和Spring Boot的控制器,我们可以方便地实现页面之间的跳转和数据的渲染。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值