SpringBoot + thymeleaf 集成前端项目

SpringBoot 项目集成前端项目

项目结构

其中static是中是可以直接访问的静态资源,templates中存放的是.html文件。

image-20220415142344941

Thymeleaf
添加必要依赖
<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
配置资源文件
spring:
  thymeleaf:
    cache: false
    suffix: .html

springboot默认跳转的是static/index.html,配置thymeleaf组件后,会动态跳转,默认/templates/index.html,若要修改路径可以配置thymeleaf.prefix: classpath:/自定义路径/。在配置文件内配置thymeleaf.suffix: .html后,跳转时不需要加上html后缀。

注意: 如果在Controller方法中通过return "index";的形式跳转页面的话,则该Controller要使用@Controller注解,不能使用@RestController,因为后者返回的是JSON,此时如果方法返回值需要跳转,那么方法的返回类型必须是View 或者ModelAndView。

实现增删改查

编写Controller类,方法体都在后文中

@Controller
@RequestMapping("/policy/publish")
public class PolicyPublishController{
    @Autowired
    private PolicyPublishService policyPublishService;

    private boolean isFirst = true;
}
查询所有数据

policyList.html

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <!-- Bootstrap core CSS -->
    <link rel="stylesheet" href="https://cdn.staticfile.org/twitter-bootstrap/3.3.7/css/bootstrap.min.css">
    <script src="https://cdn.staticfile.org/jquery/3.5.1/jquery.min.js"></script>
    <script src="https://cdn.staticfile.org/twitter-bootstrap/3.3.7/js/bootstrap.min.js"></script>
    <script th:src="@{bootstrap/index.js}"></script>
</head>
<body>

<div class="container-fluid">
    <div class="col-sm-12 column">
        <ol class="breadcrumb">
            <li class="active">菜单
            </li>
            <li class="active">政策管理
            </li>
        </ol>

        <div class="panel panel-default">
            <div class="panel-body">
                <form role="form" class="form-inline" style="display: inline">
                    <div class="form-group">
                        <label for="name">标题</label>
                        <input type="text" class="form-control" id="name" placeholder="请输入政策标题">
                    </div>
                    <div class="form-group">
                        <label for="name">状态</label>
                        <select class="form-control">
                            <option>正常</option>
                            <option>禁用</option>
                        </select>
                    </div>
                    <div class="form-group">
                        <button type="submit" class="btn btn-default">开始搜索</button>
                    </div>
                </form>

                <div style="display: inline">
                    <a href="/policy/publish/input" class="btn btn-success pull-right">发布政策</a>
                </div>
            </div>
        </div>

        <div class="table-responsive">
            <table class="table table-striped ">
                <thead>
                <tr>
                    <th>机构代码</th>
                    <th>发布日期</th>
                    <th>发布人id</th>
                    <th>发布人</th>
                    <th>政策标题</th>
                    <th>政策内容</th>
                    <th>文件路径</th>
                </tr>
                </thead>
                <tbody>
                <!--
                    这里的 policyPublishDetailDtoList
                    是 Controller 通过 model.addAttribute("policyPublishDetailDtoList", list);传过来的
					th:each th:text都是thymeleaf中常用的标签
                -->
                <tr th:each="policyPublishDetailDto:${policyPublishDetailDtoList}">
                    <td th:text="${policyPublishDetailDto.orgCode}" style="text-align:center;vertical-align:middle;"></td>
                    <td th:text="${#dates.format(policyPublishDetailDto.publishDate, 'yyyy-MM-dd')}" style="text-align:center;vertical-align:middle;"></td>
                    <td th:text="${policyPublishDetailDto.publisherId}" style="text-align:center;vertical-align:middle;"></td>
                    <td th:text="${policyPublishDetailDto.publisher}" style="text-align:center;vertical-align:middle;"></td>
                    <td th:text="${policyPublishDetailDto.policyTitle}" style="text-align:center;vertical-align:middle;"></td>
                    <td th:text="${policyPublishDetailDto.policyContent}" style="text-align:center;vertical-align:middle;"></td>
                    <td th:text="${policyPublishDetailDto.fileUrl}" style="text-align:center;vertical-align:middle;"></td>
                    <td>
                        <div class="btn-group">
        <!--                    <a class="btn btn-default" data-target="#myInputModal" data-toggle="modal">修改</a><a class="btn btn-danger">删除</a>-->
                            <a class="btn btn-default" th:href="@{/policy/publish/update/}+${policyPublishDetailDto.getId()}">修改</a>
<!--                            <a class="btn btn-danger" name="del_button" th:href="@{/policy/publish/}+${policyPublishDetailDto.id}">删除</a>-->
                            <button class="btn btn-danger" th:attr="del_url=@{/policy/publish/}+${policyPublishDetailDto.getId()}" name="del_button">删除</button>
                            <!--删除操作-->
                            <form method="post" id="form_delete">
                                <input type="hidden" name="_method" value="DELETE"/>
                            </form>
                        </div>
                    </td>
                </tr>
                </tbody>
            </table>
        </div>

        <ul class="pagination" style="float: right;">
            <li><a href="#">&laquo;</a></li>
            <li class="active"><a href="#">1</a></li>
            <li><a href="#">2</a></li>
            <li><a href="#">3</a></li>
            <li><a href="#">&raquo;</a></li>
        </ul>
    </div>
</div>
</body>
</html>

编写Controller

@GetMapping("")
public String query(@RequestParam(required = false) String name,
                    @RequestParam(required = false) String title,
                    @RequestParam(required = false) Integer userId,
                    Model model,
                    HttpServletRequest request) {
    PolicyPublishQueryVo vo = new PolicyPublishQueryVo();
    vo.setName(name);
    vo.setTitle(title);
    vo.setUserId(userId);

    List<PolicyPublishDetailDto> list = policyPublishService.query(vo);

    model.addAttribute("policyPublishDetailDtoList", list);
    model.addAttribute("policyPublishRequestDto", new PolicyPublishRequestDto());

    request.getSession().removeAttribute("relativePath");
    // 跳转到policyList.html页面
    return "policyList";
}

浏览器请求:

image-20220415145237394

注意:由于在policyList.html中使用了${policyPublishDetailDtoList}所以在Controller里面一定要model.addAttribute()添加对应的属性,否则在访问页面的时候thymeleaf会报错。

addPolicy.html

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>发布政策</title>

    <script th:src="@{bootstrap/index.js}"></script>
</head>
<body>

<form action="#" th:action="@{/files/doUpload}" th:method="post" enctype="multipart/form-data">
    上传文件:<input type="file" name="file">
    <input type="submit" value="确认上传">
</form>

<form action="#" th:action="@{/policy/publish}" th:object="${policyPublishRequestDto}" th:method="post">
    <br>
    机构代码:<input type="text" th:field="*{orgCode}" id="orgCode"><br>
    发布日期:<input type="date" th:field="*{publishDate}" id="publishDate" placeholder="格式: yyyy-MM-dd"><br>
    发布人Id:<input type="text" th:field="*{publisherId}" id="publisherId"><br>
    政策标题:<input type="text" th:field="*{policyTitle}" id="policyTitle"><br><br>
    政策内容:<textarea th:field="*{policyContent}" id="policyContent" rows="8"></textarea><br><br>
    文件路径:[[${relativePath}]]
    <br><br>
    <input type="submit" value="发布政策">
</form>

</body>
</html>

编写Controller

@GetMapping("/input")
public String input(Model model, HttpServletRequest request){
    model.addAttribute("policyPublishRequestDto", new PolicyPublishRequestDto());
    isFirst = new ModelAttributeUtils().setModelAttribute(isFirst,model,request,null);
    // 通过这个Controller进入到addPolicy.html
    return "addPolicy";
}

@PostMapping("")
public String addNewRecord(@ModelAttribute(value = "policyPublishRequestDto") PolicyPublishRequestDto dto, HttpServletRequest request) {
    dto.setFileUrl((String) request.getSession().getAttribute("relativePath"));
    boolean flag = policyPublishService.addNewRecord(dto);
    // 插入数据成功后,重定向到index.html
    return flag ? "redirect:/index" : "error";
}

image-20220415151603889

整个请求流程大致就是这样:

image-20220415150834884

修改数据

updatePolicy.html

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>修改政策信息</title>

    <script th:src="@{bootstrap/index.js}"></script>
</head>
<body>

<form action="#" th:action="@{/files/doUpload}" th:method="post" enctype="multipart/form-data">
    上传文件:<input type="file" name="file">
    <input type="submit" value="确认上传">
</form>

<form action="#" th:action="@{/policy/publish}" method="post" th:object="${policyPublishDetailDto}">
    <input type="hidden" name="_method" value="PUT">
    <br>
    机构代码:<input type="text" th:field="*{orgCode}" id="orgCode"><br>
    发布日期:<input type="date" th:field="*{publishDate}" id="publishDate"><br>
    发布人Id:<input type="text" th:field="*{publisherId}" id="publisherId"><br>
    政策标题:<input type="text" th:field="*{policyTitle}" id="policyTitle"><br><br>
    政策内容:<textarea th:field="*{policyContent}" id="policyContent" rows="8" th:placeholder="*{policyContent}"></textarea><br><br>
    文件路径:[[${relativePath}]]
    <br><br>
    <input type="submit" value="确认修改">
</form>

</body>
</html>

编写Controller

@GetMapping("/update/{id}")
public String update(@PathVariable("id") Integer id, Model model, HttpServletRequest request){
    PolicyPublishDetailDto dto = policyPublishService.load(id);
    request.getSession().setAttribute("dtoId", id);
    model.addAttribute("policyPublishDetailDto", dto);
    isFirst = new ModelAttributeUtils().setModelAttribute(isFirst,model,request,dto.getFileUrl());
    return "updatePolicy";
}

@PutMapping("")
public String updateRecord(PolicyPublishRequestDto dto,
                           HttpServletRequest request) {
    dto.setId((Integer) request.getSession().getAttribute("dtoId"));
    dto.setFileUrl((String) request.getSession().getAttribute("relativePath"));
    boolean flag = policyPublishService.update(dto);
    return flag ? "redirect:/index" : "error";
}

image-20220415151826312

注意: 使用Restful时修改操作使用的是PUT请求方法,但是form表单的提交方式只有GET 和POST ,此时需要指明form表单的请求方式为POST,并且在form表单里要写一个input隐藏域,并指明name="_method" value="PUT"来修改请求方式。后面的修改操作就修改value为DELETE。

image-20220415152213344

删除数据

删除数据的按钮写在policyList.html里了

<div class="btn-group">
    <a class="btn btn-default" th:href="@{/policy/publish/update/}+${policyPublishDetailDto.getId()}">修改</a>
    <button class="btn btn-danger" th:attr="del_url=@{/policy/publish/}+${policyPublishDetailDto.getId()}" name="del_button">删除</button>
    <!--删除操作-->
    <form method="post" id="form_delete">
        <!--这里要修改form表单的请求方式-->
        <input type="hidden" name="_method" value="DELETE"/>
    </form>
</div>

通过js实现删除按钮的点击事件:

$(function () {
    //name='del_button'的按钮的点击事件
    $("button[name='del_button']").click(function () {
        alert("删除成功!" + $(this).attr("del_url"));
        //点击删除按钮之后,让id="form_delete"的表单提交
        $("#form_delete").prop("action", $(this).attr("del_url")).submit();
    });
});

编写Controller

@DeleteMapping("/{id}")
public String deleteRecord(@PathVariable Integer id) {
    boolean flag = policyPublishService.delete(id);
    return flag ? "redirect:/index" : "error";
}

注意: 在 Spring Boot 的 META-INF/spring-configuration-metadata.json 配置文件中默认是关闭 Spring 的 hiddenmethod 过滤器的,此时直接在表单提交的数据中添加 “_method” 数据并不起作用。

## 将hiddenmethod 过滤器设置为启用即可
spring:
  mvc:
    hiddenmethod:
      filter:
        enabled: true
  • 3
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值