网页右边,向下滑有目录索引,可以根据标题跳转到你想看的内容

如果右边没有就找找左边

FreeMarker改为vue freemarker vue模板_spring

一、环境搭建

  1. 创建工程,引入依赖
<parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.12.RELEASE</version>
    </parent>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-freemarker</artifactId>
        </dependency>
        <dependency>
            <groupId>com.squareup.okhttp3</groupId>
            <artifactId>okhttp</artifactId>
            <version>4.3.1</version>
        </dependency>
        <dependency>
            <groupId>commons-io</groupId>
            <artifactId>commons-io</artifactId>
            <version>2.11.0</version>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.12</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
        </dependency>
    </dependencies>
  1. 配置文件
server:
  port: 8088 #服务端口
spring:
  application:
    name: test‐freemarker #指定服务名
  freemarker:
    cache: false #关闭模板缓存,方便测试
    settings:
      template_update_delay: 0 #检查模板更新延迟时间,设置为0表示立即检查,如果时间大于0会有缓存不方便 进行模板测试
  1. 日志文件
<?xml version="1.0" encoding="UTF-8"?>

<configuration>
    <!--定义日志文件的存储地址,使用绝对路径-->
    <property name="LOG_HOME" value="d:/logs"/>

    <!-- Console 输出设置 -->
    <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符-->
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
            <charset>utf8</charset>
        </encoder>
    </appender>

    <!-- 按照每天生成日志文件 -->
    <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!--日志文件输出的文件名-->
            <fileNamePattern>${LOG_HOME}/xc.%d{yyyy-MM-dd}.log</fileNamePattern>
        </rollingPolicy>
        <encoder>
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
        </encoder>
    </appender>

    <!-- 异步输出 -->
    <appender name="ASYNC" class="ch.qos.logback.classic.AsyncAppender">
        <!-- 不丢失日志.默认的,如果队列的80%已满,则会丢弃TRACT、DEBUG、INFO级别的日志 -->
        <discardingThreshold>0</discardingThreshold>
        <!-- 更改默认的队列的深度,该值会影响性能.默认值为256 -->
        <queueSize>512</queueSize>
        <!-- 添加附加的appender,最多只能添加一个 -->
        <appender-ref ref="FILE"/>
    </appender>


    <logger name="org.apache.ibatis.cache.decorators.LoggingCache" level="DEBUG" additivity="false">
        <appender-ref ref="CONSOLE"/>
    </logger>
    <logger name="org.springframework.boot" level="DEBUG"/>
    <root level="info">
        <!--<appender-ref ref="ASYNC"/>-->
        <appender-ref ref="FILE"/>
        <appender-ref ref="CONSOLE"/>
    </root>
</configuration>
  1. 启动类
  1. 实体类
package com.yzpnb.freemarker_test.model;

import lombok.Data;
import lombok.ToString;

import java.util.Date;
import java.util.List;

@Data
@ToString
@AllArgsConstructor
public class Student {
    private String name;
    private int age;
    private Date birthday;
    private Float money;//钱包
    private List<Student> friends;//朋友列表
    private Student bestFriend;//最好的朋友
}
  1. freemarker模板文件(resources下创建templates文件夹,文件夹下创建test1.ftl模板文件)
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>HelloWorld!</title>
</head>
<body>
Hello ${name}!
</body>
</html>
  1. controller
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.client.RestTemplate;

import java.util.Map;

@RequestMapping("/freemarker")
@Controller
public class FreemarkerController {
//    @Autowired
//    private RestTemplate restTemplate;

    @RequestMapping("/test1")
    public String freemarker(Map<String,Object> map){
        map.put("name","yzpnb");
        return "test1";
    }
}
  1. 启动工程测试

二、核心指令

Freemarker静态化依赖数据模型和模板,下边定义数据模型,下边方法形参map即为freemarker静态化所需要的数据模型,在map中填充数据


@RequestMapping("/test1")
    public String freemarker(Map<String,Object> map){
        //创建两个学生实例
        Student stu1 = new Student("小明",18,new Date(),1000.86f,null,null);
        ArrayList<Student> friends = new ArrayList<>();
        friends.add(stu1);
        Student stu2 = new Student("小红",19,new Date(),200.1f,friends,stu1);

        //创建一个集合,添加两个学生,用于测试集合数据
        ArrayList<Student> students = new ArrayList<>();
        students.add(stu1);
        students.add(stu2);
        //创建map,添加两个学生,用于测试map数据
        HashMap<String, Student> stringStudentHashMap = new HashMap<>();
        stringStudentHashMap.put("stu1",stu1);
        stringStudentHashMap.put("stu2",stu2);
        //将上面创建的放到数据模型中
        map.put("name","yzpnb");
        map.put("stus",students);
        map.put("stu1",stu1);
        map.put("stuMap",stringStudentHashMap);
        return "test1";
    }

freemarker的注释等内容

  1. 注释,<#–注释内容–>
  2. 插值,${变量},最终展示的是变量值内容
  3. FTL指令,与HTML标签类似,名字前加#区分,标签中的表达式和逻辑,都会解析
  4. 文本,直接输出

1. List指令

1. 遍历List

FreeMarker改为vue freemarker vue模板_java_02


2. 测试


FreeMarker改为vue freemarker vue模板_java_03

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>HelloWorld!</title>
</head>
<body>
Hello ${name}!
<table>
    <tr>
        <td>序号</td>
        <td>姓名</td>
        <td>年龄</td>
        <td>钱包</td>
    </tr>
    <#list stus as stu><#--list指令,格式<#list list集合 as 变量>,变量会依次取出list集合中的值-->
        <tr>
            <td>${stu_index + 1}</td><#--插值表达式,解析其中变量和表达式,stu_index表示下标-->
            <td>${stu.name}</td>
            <td>${stu.age}</td>
            <td>${stu.money}</td>
        </tr>
    </#list>
</table>
</body>
</html>

2. 遍历map



<body>
    Hello ${name}!
    <table>
        直接通过插值表达式输出map集合中stu1的学生信息<br/>
        姓名:${stuMap['stu1'].name}<br/>
        年龄:${stuMap['stu1'].age}<br/>
        <br/><br/>
        通过.的形式输出stu2<br/>
        姓名:${stuMap.stu2.name}<br/>
        年龄:${stuMap.stu2.age}<br/>
        <br/><br/>
        遍历map数据:输出map集合中学生信息<br/>
        <tr>
            <td>序号</td>
            <td>姓名</td>
            <td>年龄</td>
            <td>钱包</td>
        </tr>
        <#list stuMap?keys as k><#--stuMap?keys 表示依次遍历stuMap的key值,保存到k中-->
            <tr>
                <td>${k_index + 1}</td>
                <td>${stuMap[k].name}</td>
                <td>${stuMap[k].age}</td>
                <td>${stuMap[k].money}</td>
            </tr>
        </#list>
    </table>
</body>

2. if指令


<body>
    Hello ${name}!
    <table>
        <tr>
            <td>姓名</td>
            <td>年龄</td>
            <td>钱包</td>
        </tr>
        <#list stus as stu>
            <tr>
                <#--如果当前遍历的name是小明,那么输出为红色
                    style="background-color: red"生效,否则不生效
                    if指令,条件成立,解析里面内容,否则不解析
                -->
                <td <#if stu.name == '小明'>style="background-color: red"</#if>>
                    ${stu.name}
                </td>
                <td>${stu.age}</td>
                <td>${stu.money}</td>
            </tr>
        </#list>
    </table>
</body>

3. 其它指令

1. 运算符

  1. + - * / %:算数运算符都支持
  2. &&(与) ||(或) !(非):逻辑运算符,只能用于布尔值
  3. =、==、!=、>(使用gt也可以)、>=(gte)、<(lt)、<=(lte):比较运算符,尽量使用gt而不使用>,因为会解析成标签,可以使用括号解决问题,比如<#if (x>y)>。=和!=可用于字符串,数值和日期,但是两边类型必须相同,freemarker是精确比较,‘x’、‘X’、'x '都不相等。另外,除去=和!=两个运算符外,其它运算符不能作用于字符串

2. 空值处理

  1. 判断某变量是否存在使用??,用法为变量??,如果存在返回true,否则返回false,例如,放在stus为空报错可以加上如下判断
<#if stus??>
            <#list stus as stu>
                <tr>
                    <#--如果当前遍历的name是小明,那么输出为红色
                        style="background-color: red"生效,否则不生效
                        if指令,条件成立,解析里面内容,否则不解析
                    -->
                    <td <#if stu.name == '小明'>style="background-color: red"</#if>>
                        ${stu.name}
                    </td>
                    <td>${stu.age}</td>
                    <td>${stu.money}</td>
                </tr>
            </#list>
        </#if>
  1. 确实变量默认使用"!",使用!要指定一个默认值,当变量为空时,显示默认值,例如$ {name!’’}表示如果name为空显示空字符串,再比如,$ {(stu.bestFriend.name)!‘null’},表示stu或bestFriend或name为空,默认显示null字符串。另外,(stu.bestFriend.name)这样的嵌套对象最后使用括号括起来

3. 内建函数

语法:变量+?+函数名称


<body>
    stus集合的大小为:${stus?size}<br/>
    显示stu1的生日,格式<br/>
    显示年月日:${stu1.birthday?date}<br/>
    显示时分秒:${stu1.birthday?time}<br/>
    显示日期+时间:${stu1.birthday?datetime}<br/>
    自定义格式化:${stu1.birthday?string("yyyy年MM月")}<br/>
    freemarker默认显示数值,为每三位使用逗号分隔:${stu1.money}<br/>
    如果不想以逗号分隔,可以使用内建函数c:${stu1.money?c}<br/>

    使用assign标签定义变量text:<br/>
    <#assign text="{'bank':'工商银行','account':'10101920201928212'}"/>
    ${text}
    将json字符串变为对象,保存到data变量中<br>
    <#assign data=text?eval/>
    开户行:${data.bank}<br/>
    账号:${data.account}<br/>
</body>

三、生成静态化页面

1. 通过模板文件

在controller层,添加一个方法

FreeMarker改为vue freemarker vue模板_开发语言_04

@RequestMapping("/test2")
    public String testGenerateHtml(Map<String,Object> map) throws IOException, TemplateException {
        //1.数据模型
        //创建两个学生实例
        Student stu1 = new Student("小明",18,new Date(),1000.86f,null,null);
        ArrayList<Student> friends = new ArrayList<>();
        friends.add(stu1);
        Student stu2 = new Student("小红",19,new Date(),200.1f,friends,stu1);

        //创建一个集合,添加两个学生,用于测试集合数据
        ArrayList<Student> students = new ArrayList<>();
        students.add(stu1);
        students.add(stu2);
        //将上面创建的放到数据模型中
        map.put("stus",students);
        map.put("stu1",stu1);
        //2.创建配置类
        Configuration configuration = new Configuration(Configuration.getVersion());
        //3.设置模板路径
        String path = this.getClass().getResource("/").getPath();
        configuration.setDirectoryForTemplateLoading(new File(path+"templates/"));
        //4.设置字符集
        configuration.setDefaultEncoding("utf-8");
        //5.加载模板
        Template template = configuration.getTemplate("test1.ftl");
        //6.静态化
        String content = FreeMarkerTemplateUtils.processTemplateIntoString(template, map);
        //7.静态化内容
        System.out.println(content);
        InputStream inputStream = IOUtils.toInputStream(content);
        //8.输出文件
        FileOutputStream fileOutputStream = new FileOutputStream(new File("D:/test1.html"));
        int copy = IOUtils.copy(inputStream, fileOutputStream);
        return "test1";
    }

2. 通过模板字符串静态化


@RequestMapping("/test3")
    public String testGenerateHtmlByString(Map<String,Object> map) throws IOException, TemplateException {
        //1.数据模型
        //创建两个学生实例
        Student stu1 = new Student("小明",18,new Date(),1000.86f,null,null);
        ArrayList<Student> friends = new ArrayList<>();
        friends.add(stu1);
        Student stu2 = new Student("小红",19,new Date(),200.1f,friends,stu1);

        //创建一个集合,添加两个学生,用于测试集合数据
        ArrayList<Student> students = new ArrayList<>();
        students.add(stu1);
        students.add(stu2);
        //将上面创建的放到数据模型中
        map.put("stus",students);
        map.put("stu1",stu1);
        //2.创建配置类
        Configuration configuration = new Configuration(Configuration.getVersion());
        //3.设置模版内容
        String templateString ="<html lang=\"en\">\n" +
                "<head>\n" +
                "    <meta charset=\"UTF-8\">\n" +
                "    <title>HelloWorld!</title>\n" +
                "</head>\n" +
                "<body>\n" +
                "    stus集合的大小为:${stus?size}<br/>\n" +
                "    显示stu1的生日,格式<br/>\n" +
                "    显示年月日:${stu1.birthday?date}<br/>\n" +
                "    显示时分秒:${stu1.birthday?time}<br/>\n" +
                "    显示日期+时间:${stu1.birthday?datetime}<br/>\n" +
                "    自定义格式化:${stu1.birthday?string(\"yyyy年MM月\")}<br/>\n" +
                "    freemarker默认显示数值,为每三位使用逗号分隔:${stu1.money}<br/>\n" +
                "    如果不想以逗号分隔,可以使用内建函数c:${stu1.money?c}<br/>\n" +
                "\n" +
                "    使用assign标签定义变量text:<br/>\n" +
                "    <#assign text=\"{'bank':'工商银行','account':'10101920201928212'}\"/>\n" +
                "    ${text}\n" +
                "    将json字符串变为对象,保存到data变量中<br>\n" +
                "    <#assign data=text?eval/>\n" +
                "    开户行:${data.bank}<br/>\n" +
                "    账号:${data.account}<br/>\n" +
                "</body>\n" +
                "</html>";
        //4.模板加载器
        StringTemplateLoader stringTemplateLoader = new StringTemplateLoader();
        stringTemplateLoader.putTemplate("template",templateString);
        configuration.setTemplateLoader(stringTemplateLoader);
        //5.获取到模板
        Template template = configuration.getTemplate("template", "utf-8");
        //6.静态化
        String content = FreeMarkerTemplateUtils.processTemplateIntoString(template, map);
        //7.静态化内容
        System.out.println(content);
        InputStream inputStream = IOUtils.toInputStream(content);
        //8.输出文件
        FileOutputStream fileOutputStream = new FileOutputStream(new File("D:/test3.html"));
        int copy = IOUtils.copy(inputStream, fileOutputStream);
        return "test1";
    }