一、创建maven项目
前几步相同
spring-boot 搭建web项目 - hehehenhen - 博客园 (cnblogs.com)
二、引入依赖
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>org.example</groupId> <artifactId>spring_boot_freemarker</artifactId> <version>1.0-SNAPSHOT</version> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.0.1.RELEASE</version> </parent> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-freemarker</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> </dependency> <dependency> <groupId>com.squareup.okhttp3</groupId> <artifactId>okhttp</artifactId> <version>3.9.1</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> </dependency> <dependency> <groupId>commons-io</groupId> <artifactId>commons-io</artifactId> <version>2.6</version> </dependency> </dependencies> </project>
三、配置文件
这连个文件都在resource文件夹下
application.yml
核心配置文件
server: port: 8088 #服务端口 spring: application: name: test-freemarker #指定服务名 freemarker: cache: false #关闭模板缓存,方便测试 settings: template_update_delay: 0 #检查模板更新延迟时间,设置为0表示立即检查,如果时间大于0会有缓存不方便进行模板测试
logback-spring.xml
<?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>
日志配置文件
四、创建模型
我这里用了lombok插件,如果没有可以去掉注解,添加get/set方法,toString方法。
package cn.newstrength.pojo; import lombok.Data; import lombok.ToString; import java.util.List; /** * @author lanpengbiao * @version 1.0 * @Description Student * @date Created in 2021-11-25 15:41 * @since jdk1.7 */ @Data @ToString public class Student { private String name; private String age; private String mondy; private String birthday; private Student bestFriend; private List friends; }
五、创建控制类
这里的返回值是模板的名称
package cn.newstrength.controller; import cn.newstrength.pojo.Student; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; /** * @author lanpengbiao * @version 1.0 * @Description controller * @date Created in 2021-11-25 15:32 * @since jdk1.7 */ @Controller public class StudentController { @RequestMapping("/freemarker/test1") public String freemarker(Map<String, Object> map){ Student stu1=new Student(); Student stu2=new Student(); stu1.setAge("1"); stu1.setMondy("100"); stu1.setName("小明"); stu2.setAge("2"); stu2.setMondy("200"); stu2.setName("小红"); List list=new ArrayList(); list.add(stu1); list.add(stu2); stu1.setFriends(list); stu2.setFriends(list); stu1.setBestFriend(stu2); stu2.setBestFriend(stu1); Map stuMap=new HashMap(); stuMap.put("stu1",stu1); stuMap.put("stu2",stu2); map.put("name","黑马程序员"); map.put("stus",list); map.put("stuMap",stuMap); map.put("stu1",stu1); map.put("stu2",stu2); //返回模板文件名称 return "test1"; } }
六、创建模板文件
在resource文件下创建 :templates文件夹,在templates下创建模板文件,模板文件的后缀名为 :.ftl
我的测试模板为:
test1.ftl
<!DOCTYPE html> <html> <#-- 1、注释,即<#‐‐和‐‐>,介于其之间的内容会被freemarker忽略 2、插值(Interpolation):即${..}部分,freemarker会用真实的值代替${..} 3、FTL指令:和HTML标记类似,名字前加#予以区分,Freemarker会解析标签中的表达式或逻辑。 4、文本,仅文本信息,这些不是freemarker的注释、插值、FTL指令的内容会被freemarker忽略解析直接输出内容。 5、if 指令即判断指令,freemarker在解析时遇到if会进行判断,条件为真则输出if中间的内容,否 则跳过内容不再输出。 6、判断某变量是否存在使用 “??” 用法为:variable??,如果该变量存在,返回true,否则返回false 7、缺失变量默认值使用 “!” 使用!要以指定一个默认值,当变量为空时显示默认值。如果是嵌套对象则建议使用()括起来。 ${name!''}表示如果name为空显示空字符串。 ${(stu.bestFriend.name)!''}表示,如果stu或bestFriend或name为空默认显示空字符串。 8 8、得到某个集合的大小 ${集合名?size} 9、日期格式化: 显示年月日: ${today?date} 显示时分秒:${today?time} 显示日期+时间:${today?datetime} 自定义格式化: ${today?string("yyyy年MM月")} 10、${point?c} map.put("point", 102920122); point是数字型,使用${point}会显示这个数字的值,并且每三位使用逗号分隔。 如果不想显示为每三位分隔的数字,可以使用c函数将数字型转成字符串输出 11、assign标签assign的作用是定义一个变量。 12、将json字符串转成对象,text是一个字符串json <#assign text="{'bank':'工商银行','account':'10101920201920212'}" /> <#assign data=text?eval /> 13 14 --> <head> <meta charset="utf-8"> <title>Hello World!</title> </head> <body> <#--2、插值(Interpolation):即${..}部分,freemarker会用真实的值代替${..}--> Hello ${name}! <hr> <br/> </br> </br> <div> <#-- 使用map指令遍历数据模型中的stuMap。 --> <br/><br/> 输出stu1的学生信息:<br/> 姓名:${stuMap['stu1'].name}<br/> 年龄:${stuMap['stu1'].age}<br/> 输出stu1的学生信息:<br/> 姓名:${stu1.name}<br/> 年龄:${stu1.age}<br/> </div> <hr> <div> </div> 遍历输出两个学生信息:list<br/> <table> <tr> <td>序号</td> <td>姓名</td> <td>年龄</td> <td>钱包</td> </tr> <#list stus as stu> <tr> <#--_index:得到循环的下标,使用方法是在stu后边加"_index",它的值是从0开始--> <td>${stu_index + 1}</td> <td <#if stu.name =='小明'>style="background:red;"</#if>>${stu.name}</td> <td>${stu.age}</td> <td >${stu.mondy}</td> </tr> </#list> </table> <div> <hr> 遍历输出两个学生信息:map<br/> <table> <tr> <td>序号</td> <td>姓名</td> <td>年龄</td> <td>钱包</td> </tr> <#list stuMap?keys as k> <tr> <td>${k_index + 1}</td> <td>${stuMap[k].name}</td> <td>${stuMap[k].age}</td> <td >${stuMap[k].mondy}</td> </tr> </#list> </table> </div> <div> <hr> <table> <tr> <td>姓名</td> <td>年龄</td> <td>出生日期</td> <td>钱包</td> <td>最好的朋友</td> <td>朋友个数</td> <td>朋友列表</td> </tr> <#-- if 指令即判断指令,freemarker在解析时遇到if会进行判断,条件为真则输出if中间的内容,否 则跳过内容不再输出。 判断某变量是否存在使用 “??” 用法为:variable??,如果该变量存在,返回true,否则返回false --> <#if stus??> <#list stus as stu> <tr> <td>${stu.name!''}</td> <td>${stu.age}</td> <td>${(stu.birthday?date)!''}</td> <#--显示年月日: ${today?date}--> <td>${stu.mondy}</td> <td>${(stu.bestFriend.name)!''}</td> <td>${(stu.friends?size)!0}</td> <#--得到某个集合的大小 ${集合名?size}--> <td> <#if stu.friends??> <#list stu.friends as firend> ${firend.name!''}<br/><#-- 缺失变量默认值使用 “!” 使用!要以指定一个默认值,当变量为空时显示默认值。--> </#list> </#if> </td> </tr> </#list> </#if> </table> </div> <hr> <div> 将json字符串转成对象,text是一个字符串json <#assign text="{'bank':'工商银行','account':'10101920201920212'}" /> <#assign data=text?eval /> 开户行:${data.bank} 账号:${data.account} </div> </br> </br> </br> <br/> </body> </html>
六、测试
创建启动类:
注意启动类的位置
package cn.newstrength; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; /** * @author lanpengbiao * @version 1.0 * @Description FreemarkerTestApplication * @date Created in 2021-11-25 15:52 * @since jdk1.7 */ @SpringBootApplication public class FreemarkerTestApplication { public static void main(String[] args) { SpringApplication.run(FreemarkerTestApplication.class); } }
浏览器访问:
实际根据自己配置的端口和路径
http://localhost:8088/freemarker/test1