SpringBoot(4) -视图渲染技术

1.Freemarker简介及入门

学习网址

http://freemarker.foofun.cn/

1.1首先,新建一个模块

image-20230810093719569

1.2预加载依赖

image-20230810093855074

1.3添加application.yml的配置

mybatis:
  mapper-locations: classpath:mappers/**/*.xml
  type-aliases-package: com.hyx.springboot04.entity
logging:
  level:
    com.hyx.springboot04: debug
server:
  port: 8080
spring:
  application:
    name: springboot04
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    name: defaultDataSource
    password: 123456
    url: jdbc:mysql://localhost:3306/ssmbuild?useUnicode=true&characterEncoding=UTF-8
    username: root
  freemarker:
    cache: false
    charset: utf-8
    expose-request-attributes: true
    expose-session-attributes: true
    suffix: .ftl
    template-loader-path: classpath:/templates/
  resources:
    static-locations: classpath:/static/**


1.4构建freemarker的模板

image-20230810100425488

1.5现在在templete新建一个index.ftl文件

image-20230810103845079

1.6新建一个controller层

image-20230810103821759

1.7测试一下成功

image-20230810103938326

2.FreeMarker的语法

2.1 语法

image-20230810104244225

2.2新建一个实体类

package com.hyx.springboot04.entity;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@NoArgsConstructor
@AllArgsConstructor
public class User {
    private int id;
    private String name;

}

2.3修改index.ftl

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>语法测试</title>
</head>
<body>
<p>取值</p>
${name }

<p>条件</p>
<#if sex== 'nv'>
    女
    <#elseif sex=='nan'>
    男
    <#else>
    南通
</#if>

<p>循环</p>
<#list user as u>
    ${u.id }=======${u.name }
</#list>
<p>include</p>
<#include '/common.ftl'>

<p>局部变量和全局变量</p>
${ctx}
<hr>
${ctx2}

</body>
</html>

2.4新建一个common.ftl

这是顶部导航栏信息

项目名称
局部变量
<#assign ctx>
    ${springMacroRequestContext.contextPath}
</#assign>

全局变量
<#global ctx2>
    ${springMacroRequestContext.contextPath}
</#global>

2.5修改controller

package com.hyx.springboot04.web;

import com.hyx.springboot04.entity.User;
import org.springframework.http.HttpRequest;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import java.util.Arrays;

@Controller
public class IndexController {

    @GetMapping("/")
    public String index(HttpServletRequest request) {
        System.out.println("come on....index");
        request.setAttribute("name", "zs");
        request.setAttribute("sex", "gay");
        request.setAttribute("user", Arrays.asList(
                new User(1, "张三"),
                new User(2, "李四"),
                new User(3, "王五")));
        //suffix: .ftl
        //template-loader-path: classpath:/templates/
        //===>   templates/index.ftl

        return "index";
    }

}

2.6重启测试

image-20230810122807444

发现取值都取到

2.7注意问题,为空

如果freemarker去取值的时候,那个值根本不存在,也就是为空的时候会报错,那么如何去避免报错呢?在后面加!,这样如果没有值的话就不显示

示例

image-20230810123412183

image-20230810123344715

改变

image-20230810123500883

image-20230810123542904

这样为空的就不会报错啦

这下面是举例子

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title></title>
</head>
<body>
<h2>1.取值</h2>
<h3>1.1. 提供默认值</h3>
<#--报错-->
<#--${uname}    -->
<#--不报错,但是页面无内容-->
<#--${uname !}-->
<#--给值设置一个默认值-->
${uname! '无名'}

<h3>1.2. 对null值先进行判断</h3>
<p>1)exists用在逻辑判断;</p>
<#if uname?exists>
    ${uname}
</#if>
<br>
<p>2)??是判断对象是否为空</p>
<#if uname??>
    ${uname}
</#if>
<br>
<p>3)if_exists用来打印东西</p>
${uname?if_exists}
<br>

<h3>2.条件</h3>
<#if sex=='nv'>
    女
<#elseif sex='nan'>
    男
<#else>
    未知
</#if>
<br>


<h3>3.循环</h3>
<p>1)取出数组中的元素</p>
<#list arr as a>
    ${a}==
</#list>
<br>
<p>2)取出集合中的对象(注:访问的类要被public所修饰)</p>
<#list lst as item>
    ${item.id} : ${item.name}    <br>
</#list>

<h3>4 include</h3>
<#include "/common.ftl" >

<h3>5 局部变量(assign)/全局变量(global)</h3>
${ctx}:${ctx2}

</body>
</html>

3.FreeMarker的综合案例

3.1导入相关表数据

运行一下sql文件,略


添加分页配置

<dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-aspects</artifactId>
      <version>5.0.2.RELEASE</version>
    </dependency>
    
    <dependency>
       <groupId>com.github.pagehelper</groupId>
       <artifactId>pagehelper-spring-boot-starter</artifactId>
       <version>1.2.3</version>
     </dependency> 

image-20230810130035295

在application.yml中添加如下配置

pagehelper:
  reasonable: true
  supportMethodsArguments: true
  page-size-zero: true
  helper-dialect: mysql

3.2建立目录结构

entity/mapper/contorller/service

3.2.1 entity导入Clazz.java类
package com.hyx.springboot04.entity;


public class Clazz {

    protected Integer cid;


    protected String cname;


    protected String cteacher;

    protected String pic;

    public Clazz(Integer cid, String cname, String cteacher, String pic) {
        this.cid = cid;
        this.cname = cname;
        this.cteacher = cteacher;
        this.pic = pic;
    }

    public Clazz() {
        super();
    }

    public Integer getCid() {
        return cid;
    }

    public void setCid(Integer cid) {
        this.cid = cid;
    }

    public String getCname() {
        return cname;
    }

    public void setCname(String cname) {
        this.cname = cname;
    }

    public String getCteacher() {
        return cteacher;
    }

    public void setCteacher(String cteacher) {
        this.cteacher = cteacher;
    }

    public String getPic() {
        return pic;
    }

    public void setPic(String pic) {
        this.pic = pic;
    }
}
3.2.2导入ClazzBiz.java类
package com.hyx.springboot04.biz;



import com.hyx.springboot04.entity.Clazz;
import com.hyx.springboot04.util.PageBean;

import java.util.List;
import java.util.Map;

public interface ClazzBiz {
    int deleteByPrimaryKey(Integer cid);

    int insert(Clazz record);

    int insertSelective(Clazz record);

    Clazz selectByPrimaryKey(Integer cid);

    int updateByPrimaryKeySelective(Clazz record);

    int updateByPrimaryKey(Clazz record);

    List<Clazz> listPager(Clazz clazz, PageBean pageBean);
    List<Map> listMapPager(Clazz clazz, PageBean pageBean);
}
3.2.3添加ClazzImpl实现类
package com.hyx.springboot04.biz.impl;


import com.hyx.springboot04.biz.ClazzBiz;
import com.hyx.springboot04.entity.Clazz;
import com.hyx.springboot04.mapper.ClazzMapper;
import com.hyx.springboot04.util.PageBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Map;

/**
 * @author小李飞刀
 * @site www.javaxl.com
 */
@Service
public class ClazzBizImpl implements ClazzBiz {
    @Autowired
    private ClazzMapper clazzMapper;
    @Override
    public int deleteByPrimaryKey(Integer cid) {
        System.out.println("不做任何操作...");
        return clazzMapper.deleteByPrimaryKey(cid);
//        return 0;
    }

    @Override
    public int insert(Clazz record) {
        return clazzMapper.insert(record);
    }

    @Override
    public int insertSelective(Clazz record) {
        return clazzMapper.insertSelective(record);
    }

    @Override
    public Clazz selectByPrimaryKey(Integer cid) {
        return clazzMapper.selectByPrimaryKey(cid);
    }

    @Override
    public int updateByPrimaryKeySelective(Clazz record) {
        return clazzMapper.updateByPrimaryKeySelective(record);
    }

    @Override
    public int updateByPrimaryKey(Clazz record) {
        return clazzMapper.updateByPrimaryKey(record);
    }

    @Override
    public List<Clazz> listPager(Clazz clazz, PageBean pageBean) {
        return clazzMapper.listPager(clazz);
    }

    @Override
    public List<Map> listMapPager(Clazz clazz, PageBean pageBean) {
        if(true)
            throw new RuntimeException("查询班级信息异常,异常存在于ClazzBizImpl.list。。。。");
        return clazzMapper.listMapPager(clazz);
    }
}


3.2.4添加ClazzContorller类
package com.hyx.springboot04.controller;

import com.hyx.springboot04.biz.ClazzBiz;
import com.hyx.springboot04.entity.Clazz;
import com.hyx.springboot04.util.PageBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

import javax.servlet.http.HttpServletRequest;
import java.util.List;

/**
 * @author小李飞刀
 * @site www.javaxl.com
 */
@Controller
@RequestMapping("/clz")
public class ClazzController {
    @Autowired
    private ClazzBiz clazzBiz;
    @RequestMapping("/list")
    public String list(Clazz clazz, HttpServletRequest request){
        System.out.println("我添加了 新的代码,终于不重启了....");
        PageBean pageBean = new PageBean();
        pageBean.setRequest(request);
        List<Clazz> lst = this.clazzBiz.listPager(clazz, pageBean);

        //String pagestr = PageFreemarker.toHTML(pageBean);
        request.setAttribute("lst",lst);
        request.setAttribute("pageBean",pageBean);
        //request.setAttribute("pagestr",pagestr);
        return "clz/clzList";
    }

    @RequestMapping("/toEdit")
    public String toEdit(Clazz clazz, HttpServletRequest request){
        Integer cid = clazz.getCid();
//        传递的id代表了修改,没传代表新增
        if(cid != null){
            List<Clazz> lst = this.clazzBiz.listPager(clazz, null);
            request.setAttribute("b",lst.get(0));
        }
        return "clz/clzEdit";
    }

    @RequestMapping("/add")
    public String add(Clazz clazz){
        this.clazzBiz.insertSelective(clazz);
        return "redirect:/clz/list";
    }


    @RequestMapping("/edit")
    public String edit(Clazz clazz){
        this.clazzBiz.updateByPrimaryKeySelective(clazz);
        return "redirect:/clz/list";
    }

    @RequestMapping("/del")
    public String del(Clazz clazz){
        this.clazzBiz.deleteByPrimaryKey(clazz.getCid());
        return "redirect:/clz/list";
    }

}
3.2.5新建一个aspect的包 在其中添加一个切面类
package com.hyx.springboot04.aspect;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.hyx.springboot04.util.PageBean;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;

import java.util.List;


@Component
@Aspect
public class PagerAspect {

    /**
     * *:返回值类型
     * *..:无限包
     * *Service:以Service结尾接口名
     * *Pager:以Pager方法
     * 只要同时匹配上诉四个条件,就会被列为目标对象
     * 上述配置要生效,代理注解<aop:aspectj-autoproxy/>不能少
     * @param args
     * @return
     * @throws Throwable
     */
    @Around("execution(* *..*Biz.*Pager(..))")
    public Object invoke(ProceedingJoinPoint args) throws Throwable {
        Object[] params = args.getArgs();
        PageBean pageBean = null;
        for (Object param : params) {
            if(param instanceof PageBean){
                pageBean = (PageBean)param;
                break;
            }
        }

        if(pageBean != null && pageBean.isPagination())
            PageHelper.startPage(pageBean.getPage(),pageBean.getRows());

//        执行目标方法
        Object list = args.proceed(params);

        if(null != pageBean && pageBean.isPagination()){
            PageInfo pageInfo = new PageInfo((List) list);
            pageBean.setTotal(pageInfo.getTotal()+"");
        }
        return list;
    }

}
3.2.6将jsp改为ftl
<!DOCTYPE html>
<html lang="en">
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <link
            href="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/4.5.0/css/bootstrap.css"
            rel="stylesheet">
    <script
            src="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/4.5.0/js/bootstrap.js"></script>
    <title>博客列表</title>
    <style type="text/css">
        .page-item input {
            padding: 0;
            width: 40px;
            height: 100%;
            text-align: center;
            margin: 0 6px;
        }

        .page-item input, .page-item b {
            line-height: 38px;
            float: left;
            font-weight: 400;
        }

        .page-item.go-input {
            margin: 0 10px;
        }
    </style>
<body>
<#--班级查询的搜索框-->
<#include '/common.ftl' >
<form class="form-inline"
      action="${ctx }/templates/clz/list" method="post">
    <div class="form-group mb-2">
        <input type="text" class="form-control-plaintext" name="cname"
               placeholder="请输入班级名称">
    </div>
    <button type="submit" class="btn btn-primary mb-2">查询</button>
    <a class="btn btn-primary mb-2" href="${ctx }/templates/clz/toEdit">新增</a>
</form>


<table class="table table-striped bg-success">
    <thead>
    <tr>
        <th scope="col">ID</th>
        <th scope="col">班级名称</th>
        <th scope="col">指导老师</th>
        <th scope="col">操作</th>
    </tr>
    </thead>
    <tbody>
    <#list lst as b>
        <tr>
            <td>${b.cid !}</td>
            <td>${b.cname !}</td>
            <td>${b.cteacher !}</td>
            <td>
                <a href="${ctx }/templates/clz/toEdit?cid=${b.cid}">修改</a>
                <a href="${ctx }/templates/clz/del?cid=${b.cid}">删除</a>
            </td>
        </tr>
        </#list>
    </tbody>
</table>
</body>
</html>

测试运行

image-20230810164637155

添加修改代码


<!DOCTYPE html>
<html lang="en">
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title>博客的编辑界面</title>
</head>
<body>
<#include '/common.ftl'>
<#if b??>
    <form action="${ctx }/clz/edit" method="post">
        cid:<input type="text" name="cid" value="${b.cid }"><br>
        cname:<input type="text" name="cname" value="${b.cname }"><br>
        cteacher:<input type="text" name="cteacher" value="${b.cteacher }"><br>
        <input type="submit">
    </form>
    <#else>
        <form action="${ctx }/clz/add" method="post">
            cid:<input type="text" name="cid" value=""><br>
            cname:<input type="text" name="cname" value=""><br>
            cteacher:<input type="text" name="cteacher" value=""><br>
            <input type="submit">
        </form>
</#if>


</body>
</html>

image-20230810172540761

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值