【SpringBoot】FreeMarker视图渲染

06-18 1392阅读

目录

一、FreeMarker 简介

1.1 什么是FreeMarker?

1.2 Freemarker模板组成部分

1.3 为什么要使用FreeMarker

二、Springboot集成FreeMarker

2.1 配置

2.2 数据类型

2.2.1 字符串

2.2.2 数值

2.2.3 布尔值

2.2.4 日期

2.3 常见指令  

2.3.2 assign

2.3.3 include

...

三、常见指令实现增删改查(综合案例)⭐

3.1 后端

3.2 前端

3.3 效果展示

3.3.1 新增功能

3.3.2 修改功能

3.3.3 查询功能

3.3.4 删除功能


一、FreeMarker 简介

1.1 什么是FreeMarker?

       FreeMarker是一款 模板引擎 ,它允许开发人员使用模板和数据来生成输出文本,如HTML网页、电子邮件、配置文件和源代码等。它是一个Java类库,可以被嵌入到开发人员所创建的产品中。开发人员可以使用FreeMarker来动态生成和渲染视图,以便将数据呈现给最终用户

官方手册【SpringBoot】FreeMarker视图渲染https://freemarker.apache.org/

下面是一些关键点:

  1. 模板引擎: FreeMarker是一种模板引擎,允许开发者定义模板文件,其中包含要动态填充的占位符或表达式。这些模板文件可以包含HTML、XML、文本等。

  2. 动态内容生成: FreeMarker的主要用途是根据模板和数据生成最终的输出内容。模板中的占位符将被实际的数据替代,从而生成动态的、个性化的输出。

  3. 嵌入式组件: FreeMarker是一个Java类库,可以轻松地集成到Java应用程序中。这使得开发人员可以在他们的Java应用中使用FreeMarker来处理视图层的动态内容生成。

  4. 面向程序员: FreeMarker通常被程序员用于构建动态的用户界面或生成其他类型的文本输出。它不直接面向最终用户,而是提供给开发人员一个工具,使他们能够以更灵活和动态的方式生成内容。

1.2 Freemarker模板组成部分

FreeMarker模板文件主要由如下4个部分组成:

  • 文本:直接输出的部分

  • 注释:使用 格式做注释,里面内容不会输出

  • 插值:即 ${...} 或 #{...} 格式的部分,类似于占位符,将使用数据模型中的部分替代输出

  • FTL指令:即FreeMarker指令,全称是:FreeMarker Template Language,和HTML标记类似,但名字前加#予以区分,不会输出

    1.3 为什么要使用FreeMarker

    FreeMarker在Spring Boot中被广泛使用的原因与其特性和与Spring Boot的集成有关。

    1. 轻量级: FreeMarker相对轻量,不引入过多的依赖,易于集成和使用。

    2. 与Spring框架整合良好: FreeMarker与Spring框架集成良好,通过Spring Boot的自动配置,可以很容易地配置FreeMarker作为模板引擎。

    3. Spring Boot 默认支持: Spring Boot对多个模板引擎提供了自动配置支持,包括FreeMarker。因此,Spring Boot项目中使用FreeMarker非常方便,只需在依赖中引入相应的starter即可。

    4. 开箱即用: FreeMarker可以作为Spring Boot的一部分,无需额外的配置。这使得开发者能够快速启动项目并使用FreeMarker构建视图。

    5. 简化模板文件的构建: FreeMarker的模板语法相对简洁,可以更容易地与后端Java代码交互。在Spring Boot项目中,Java对象的数据可以直接在FreeMarker模板中使用。

           FreeMarker的诞生是为了取代JSP。虽然JSP功能强大,可以写Java代码实现复杂的逻辑处理,但是页面会有大量业务逻辑,不利于维护和阅读,更不利于前后台分工,容易破坏MVC结构,所以舍弃JSP,选择使用FreeMarker是大势所趋。

    二、Springboot集成FreeMarker

    2.1 配置

    1、配置pom.xml,引入依赖:

        org.springframework.boot
        spring-boot-starter-freemarker
    

     

    2、添加application.yml配置:

      freemarker:
        # 设置模板后缀名
        suffix: .ftl
        # 设置文档类型
        content-type: text/html
        # 设置页面编码格式
        charset: UTF-8
        # 设置页面缓存
        cache: false
        # 设置ftl文件路径
        template-loader-path: classpath:/templates
        # 设置静态文件路径,js,css等
        mvc:
          static-path-pattern: /static/**

    3、新建模板文件(.ftl)

    在resources/templates目录新建一个.ftl文件

    第一创建是没有这个文件类型的选项的,所以我们要定义个.ftl格式的文件:

    settings --> Editor --> File and Code Templates 

    【SpringBoot】FreeMarker视图渲染

    该内容模板于html差不多的,最后在创建文件的时候就有个一个.ftl格式的文件选项

    【SpringBoot】FreeMarker视图渲染

    index.ftl:

    
    
        
        Freemarker
    
    
    

    Hello FreeMarker!!!

    Controller:

    package com.ycxw.boot.controller;
    import org.springframework.stereotype.Controller;
    import org.springframework.web.bind.annotation.RequestMapping;
    /**
     * @author 云村小威
     * @create 2023-12-13 18:57
     */
    @Controller
    public class IndexController {
        @RequestMapping("/")
        public String home(){
            return "index";
        }
    }
    

    一个基本的数据显示就成功了

    【SpringBoot】FreeMarker视图渲染

    2.2 数据类型

    2.2.1 字符串

            在文本中确定字符串值的方法是看双引号,比如: "some text",或单引号,比如: 'some text'。这两种形式是等同的。 如果文本自身包含用于字符引用的引号 ( " 或 ')或反斜杠时, 应该在它们的前面再加一个反斜杠;这就是转义。 转义允许直接在文本中输入任何字符, 也包括换行。

    ${"It's \"quoted\" and this is a backslash: \\"}

    字符串类型处理:

    方法含义
    ?substring(start,end)截取字符串(左闭右开)
    ?uncap_first首字母小写输出
    ?cap_first首字母大写输出
    ?lower_case字母转小写输出
    ?upper_case字母转大写输出
    ?length获取字符串长度
    ?starts_with("xx")?string是否以指定字符开头(boolean类型)
    ?ends_with("xx")?string是否以指定字符结尾(boolean类型)
    ?index_of("xx")获取指定字符的索引
    ?trim去除字符串前后空格
    ?replace("xx","xx")替换指定字符串

    字符串空值情况处理:

    FreeMarker 的变量必须赋值,否则就会抛出异常。而对于 FreeMarker 来说,null 值和不存在的变量是完全一样的,因为 FreeMarker 无法理解 null 值。

    
    
    ${str!}
    ${str!"这是一个默认值"}
    ${(str??)?string}

    【SpringBoot】FreeMarker视图渲染

    注意事项:

    使用??或?starts_with("xx"),判断字符串是否为空或指定字符开头;返回布尔类型。如果想要输出,需要将布尔类型转换成字符串在后面添加 ?c or ?string

    例如:

    ${"嗨害嗨"?starts_with("我")}
    ${str??}

    不进行转换则会报错

    2.2.2 数值

    输入不带引号的数字就可以直接指定一个数字, 必须使用点作为小数的分隔符而不能是其他的分组分隔符。

    ${0.45}
    ${18}
    ${1000?c}
    ${1000?string.currency}
    ${0.45?string.percent}
    ${0.45723123?string["0.##"]}

    2.2.3 布尔值

    直接写 true 或者 false 就表示一个布尔值了,不需使用引号。

    在freemarker中布尔类型不能直接输出;如果输出要先转成字符串

    ${flag?c}
    ${flag?string}
    ${flag?string("yes","no")}

     

    2.2.4 日期

    日期变量可以存储和日期/时间相关的数据。

    在freemarker中日期类型不能直接输出;如果输出要先转成日期型或字符串

    日期格式输出:

    输出方式说明
    ?date年月日
    ?time时分秒
    ?datetime年月日时分秒
    ?string("自定义格式")指定格式
    ${createDate?date} 
    ${createDate?time}
    ${createDate?datetime}
    ${createDate?string("yyyy年MM月dd日 HH时mm分ss秒")}

    注意事项:

    在.ftl文件中不能直接创建时间需要通过后端传入时间进行显示(替换掉createDate)

    2.3 常见指令  

    2.3.2 assign

    使用该指令你可以创建一个新的变量, 或者替换一个已经存在的变量。

    案例演示:

    
    
    ${str} 
    ${num} and ${names?join(",")}

    【SpringBoot】FreeMarker视图渲染

     

    2.3.3 include

    可以使用它在你的模板中插入另外一个 FreeMarker 模板文件 (由 path 参数指定)

    该标签主要用于引入其他资源,简化数据

    首先创建一个公共页面定义一个变量存储本地访问路径

    【SpringBoot】FreeMarker视图渲染 在index.ftl中进行引入调用src数值

    
    

    ...

    还有如:if/elseif/else、list指令在下面的综合案例中进行演示👇

    三、常见指令实现增删改查(综合案例)⭐

    3.1 后端

    BookMapper.xml

        
            select
            
            from t_book
            where 1=1
            
                and bookname like CONCAT('%',#{bookname},'%')
            
        

    在此添加了模糊查询的方法,其他的增删改都是自动生成。

    BookMapper.java

    package com.ycxw.boot.mapper;
    import com.ycxw.boot.entity.Book;
    import org.apache.ibatis.annotations.Param;
    import org.springframework.stereotype.Repository;
    import java.util.List;
    /**
    * @author 云村小威
    * @description 针对表【t_book(书本信息表)】的数据库操作Mapper
    * @createDate 2023-12-12 14:50:45
    * @Entity com.ycxw.boot.entity.Book
    */
    @Repository
    public interface BookMapper {
        List list(@Param("bookname")String bookname);
        ...其他方法
    }
    

    BookService.java

    package com.ycxw.boot.service;
    import com.ycxw.boot.entity.Book;
    import org.apache.ibatis.annotations.Param;
    import java.util.List;
    /**
     * @author 云村小威
     * @create 2023-12-12 15:11
     */
    public interface BookService {
        List list(@Param("bookname")String bookname);
        int insert(Book record);
        int deleteByPrimaryKey(Long id);
        int updateByPrimaryKey(Book record);
    }
    

    BookServiceImpl.java

    package com.ycxw.boot.service.impl;
    import com.ycxw.boot.entity.Book;
    import com.ycxw.boot.mapper.BookMapper;
    import com.ycxw.boot.service.BookService;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Service;
    import java.util.List;
    /**
     * @author 云村小威
     * @create 2023-12-12 15:12
     */
    @Service
    public class BookServiceImpl implements BookService {
        @Autowired
        private BookMapper bookMapper;
        @Override
        public List list(String bookname) {
            return bookMapper.list(bookname);
        }
        @Override
        public int insert(Book record) {
            return bookMapper.insert(record);
        }
        @Override
        public int deleteByPrimaryKey(Long id) {
            return bookMapper.deleteByPrimaryKey(id);
        }
        @Override
        public int updateByPrimaryKey(Book record) {
            return bookMapper.updateByPrimaryKey(record);
        }
    }
    

    IndexController.java

    package com.ycxw.boot.controller;
    import com.ycxw.boot.entity.Book;
    import com.ycxw.boot.service.BookService;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Controller;
    import org.springframework.ui.Model;
    import org.springframework.web.bind.annotation.*;
    import java.util.List;
    /**
     * @author 云村小威
     * @create 2023-12-13 18:57
     */
    @Controller
    public class IndexController {
        @Autowired
        private BookService bookService;
        /**
         * 查询所有
         *
         * @param model
         * @return
         */
        @RequestMapping("/")
        public String home(Model model) {
            List list = bookService.list(null);
            model.addAttribute("book", list);
            return "index";
        }
        /**
         * 新增
         *
         * @param book
         * @return
         */
        @PostMapping("/add")
        public String add(@RequestBody Book book) {
            bookService.insert(book);
            return "redirect:/";
        }
        /**
         * 删除
         *
         * @param book
         * @return
         */
        @RequestMapping("/del")
        public String del(Book book) {
            bookService.deleteByPrimaryKey(book.getId().longValue());
            return "redirect:/";
        }
        /**
         * 修改
         *
         * @param book
         * @return
         */
        @PutMapping("/edit")
        public String edit(@RequestBody Book book) {
            bookService.updateByPrimaryKey(book);
            return "redirect:/";
        }
        /**
         * 模糊查询
         *
         * @param bookname
         * @param model
         * @return
         */
        @RequestMapping(value = "/search", method = RequestMethod.POST)
        public String search(@RequestParam("bookname") String bookname, Model model) {
            // 在这里使用 bookname 进行相关的处理
            List list = bookService.list(bookname);
            model.addAttribute("book", list);
            return "index"; // 返回搜索结果页面
        }
    }
    

    3.2 前端

    common.ftl (公共资源)

    
    
    
    
    
    

    index.ftl(自定义引擎模版)

    
    
        
        FreeMarker
        
        
    
    
        
            
                
            
            
                搜索
                
                    新增书籍
                
            
        
        
            
    序号 书籍名称 价格 类型 操作
    ${b.id} ${b.bookname} ${b.price} ${b.booktype} 删除 修改
    新增书籍
    书籍名称 类型 请选择书籍类型 动作 冒险 文学 价格 取消 提交
    修改书籍
    书籍编号 书籍名称 类型 请选择书籍类型 动作 冒险 文学 价格 取消 确认修改 /*模糊查询*/ function query() { //获取输入值 var name = $("#input").val(); // 发送AJAX请求 $.ajax({ url: "${src}/search", type: "POST", contentType: "application/x-www-form-urlencoded", data: {"bookname": name}, success: function (data) { //更新整个页面元素 $("#body").html(data); } }); } /*新增方法*/ function add() { // 获取表单数据 var name = $("#name").val(); var type = $("#bookType").val(); var price = $("#price").val(); // 创建一个对象来存储表单数据 var book = { bookname: name, booktype: type, price: price }; // 发送AJAX请求 $.ajax({ url: "${src}/add", type: "POST", contentType: "application/json", data: JSON.stringify(book), success: function (res) { console.log(res); // 请求成功处理逻辑 alert("书籍添加成功!"); // 关闭弹窗 var modal = $("#exampleModal"); modal.modal("hide"); // 刷新页面 location.reload(); } }); } /* 修改方法(回显数据) */ function editModal(id, name, type, price) { // 将数据设置到弹窗表单中 $("#id").val(id); $("#name_edit").val(name); $("#type_edit").val(type); $("#price_edit").val(price); // 显示修改弹窗 $("#editModal").modal("show"); } /*修改方法*/ function edit() { // 获取表单数据 var id = $("#id").val(); var name = $("#name_edit").val(); var type = $("#type_edit").val(); var price = $("#price_edit").val(); // 创建一个对象来存储表单数据 var book = { id: id, bookname: name, booktype: type, price: price }; // 发送AJAX请求 $.ajax({ url: "${src}/edit", type: "PUT", contentType: "application/json", data: JSON.stringify(book), success: function (res) { console.log(res); // 请求成功处理逻辑 alert("书籍修改成功!"); // 关闭弹窗 var modal = $("#editModal"); modal.modal("hide"); // 刷新页面 location.reload(); } }); }

    3.3 效果展示

    3.3.1 新增功能

    【SpringBoot】FreeMarker视图渲染

    3.3.2 修改功能

    【SpringBoot】FreeMarker视图渲染

    3.3.3 查询功能

    【SpringBoot】FreeMarker视图渲染

    3.3.4 删除功能

    【SpringBoot】FreeMarker视图渲染

VPS购买请点击我

文章版权声明:除非注明,否则均为主机测评原创文章,转载或复制请以超链接形式并注明出处。

目录[+]