接着上篇继续,博客网站少不了后台管理页面,在后台可以添加文章以及维护基础数据,因此本文主要就介绍怎样添加视图页面、怎样使用视图模型、绑定静态资源以及ThymeLeaf模板引擎的基本使用,具体如下:
1. 添加Menu类,表示后台管理页面中的左侧菜单

 1 package com.lvniao.blog.model;
 2 
 3 import java.util.ArrayList;
 4 import java.util.List;
 5 
 6 public class Menu {
 7 
 8     private Long id;
 9     
10     private String name;
11     
12     private String addr;
13     
14     private String icon;
15     
16     private Menu parent;
17     
18     private List<Menu> children = new ArrayList<Menu>();
19 
20     public Long getId() {
21         return id;
22     }
23 
24     public void setId(Long id) {
25         this.id = id;
26     }
27 
28     public String getName() {
29         return name;
30     }
31 
32     public void setName(String name) {
33         this.name = name;
34     }
35 
36     public String getAddr() {
37         return addr;
38     }
39 
40     public void setAddr(String addr) {
41         this.addr = addr;
42     }
43 
44     public String getIcon() {
45         return icon;
46     }
47 
48     public void setIcon(String icon) {
49         this.icon = icon;
50     }
51 
52     public Menu getParent() {
53         return parent;
54     }
55 
56     public void setParent(Menu parent) {
57         this.parent = parent;
58     }
59 
60     public List<Menu> getChildren() {
61         return children;
62     }
63 
64     public void setChildren(List<Menu> children) {
65         this.children = children;
66     }
67 }

Menu.java

2. 添加对应的Mapper类

 1 package com.lvniao.blog.mapper;
 2 
 3 import java.util.List;
 4 
 5 import org.apache.ibatis.annotations.Mapper;
 6 import org.apache.ibatis.annotations.Param;
 7 import org.apache.ibatis.annotations.Result;
 8 import org.apache.ibatis.annotations.Results;
 9 import org.apache.ibatis.annotations.Select;
10 import org.apache.ibatis.mapping.FetchType;
11 import org.apache.ibatis.annotations.Many;
12 
13 import com.lvniao.blog.model.Menu;
14 
15 @Mapper
16 public interface MenuMapper {
17 
18     @Select("select id, name, addr, icon, parentid from menus where parentid is null")
19     @Results({
20         @Result(id=true, column="id", property="id"),
21         @Result(column="name", property="name"),
22         @Result(column="addr", property="addr"),
23         @Result(column="icon", property="icon"),
24         @Result(column="id", property="children", 
25             many=@Many(select="com.lvniao.blog.mapper.MenuMapper.getMenuByParent", fetchType=FetchType.EAGER))
26     })
27     public List<Menu> getParentMenu();
28     
29     @Select("select id, name, addr, icon, parentid from menus where parentid=#{id}")
30     @Results({
31         @Result(id=true, column="id", property="id"),
32         @Result(column="name", property="name"),
33         @Result(column="addr", property="addr"),
34         @Result(column="icon", property="icon"),
35     })
36     public List<Menu> getMenuByParent(Long id);
37 }

MenuMapper

这儿使用了注解来完成一对多的映射;
3. 在控制器中添加动作

 1 package com.lvniao.blog.admin.controller;
 2 
 3 import java.util.List;
 4 
 5 import org.springframework.beans.factory.annotation.Autowired;
 6 import org.springframework.stereotype.Controller;
 7 import org.springframework.ui.Model;
 8 import org.springframework.web.bind.annotation.RequestMapping;
 9 
10 import com.lvniao.blog.mapper.MenuMapper;
11 import com.lvniao.blog.mapper.UserMapper;
12 import com.lvniao.blog.model.Menu;
13 
14 @Controller
15 @RequestMapping("/admin")
16 public class AdminController {
17     
18     @Autowired
19     private UserMapper userMapper;
20     
21     @Autowired
22     private MenuMapper menuMapper;
23     
24     @RequestMapping("/")
25     public String index(Model model) {
26         model.addAttribute("users", userMapper.getUsers());
27         model.addAttribute("menus", menuMapper.getParentMenu());
28         return "admin/index";
29     }
30 }

AdminController.java

通过在index方法中添加Model参数,这样调用该方法时,系统会自动注入视图模型,这样要在视图中显示的数据就可以通过视图模型来传递到视图中。
4. 添加视图

 1 <!DOCTYPE HTML>
 2 <html>
 3 <head>
 4     <title>lvniao</title>
 5     <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
 6     <meta charset="utf-8" name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no"/>
 7     <link rel="stylesheet" th:href="@{/css/base.css}"/>
 8     <link rel="stylesheet" th:href="@{/css/font-awesome.css}"/>
 9     <script th:src="@{/js/jquery-3.2.1.js}"></script>
10     <script th:src="@{/js/base.js}"></script>
11     <script>
12         $(function(){
13             init();
14         });
15         
16         function logout(){
17             $.ajax({
18                 url:"${pageContext.request.contextPath}/admin/home/logout",
19                 success:function(data){
20                     window.location.reload();
21                 }
22             })
23             
24         }
25     </script>
26 </head>
27 <body class="lv-container">
28     <div class="lv-head-section">
29         <div class="lv-head-logo">LVNIAO</div>
30         <div class="lv-head-function">
31             <div class="lv-head-btn lv-fold fa fa-bars"></div>
32             <div class="lv-sys-menu">
33                 <div class="lv-head-btn lv-first lv-sys-btn fa fa-th-list">
34                     <div class="lv-sys-panel">
35                         <div class="lv-sys-panel-content">
36                         </div>
37                     </div>
38                 </div>
39                 <div class="lv-head-btn lv-sys-btn fa fa-comment">
40                     <div class="lv-sys-panel">
41                         <div class="lv-sys-panel-content">
42                         </div>
43                     </div>
44                 </div>
45                 <div class="lv-head-btn lv-sys-btn fa fa-info-circle">
46                     <div class="lv-sys-panel">
47                         <div class="lv-sys-panel-content">
48                         </div>
49                     </div>
50                 </div>
51                 <div class="lv-head-btn lv-sys-btn fa fa-user-circle">
52                     <div class="lv-sys-panel">
53                         <div class="lv-sys-panel-content">
54                             <h1>hello ${sessionScope.CurrentUser.name }</h1>
55                             <a onclick="logout();">logout</a>
56                         </div>
57                     </div>
58                 </div>
59                 <div class="lv-head-btn lv-sys-btn fa fa-cog">
60                     <div class="lv-sys-panel">
61                         <div class="lv-sys-panel-content">
62                         </div>
63                     </div>
64                 </div>
65             </div>
66         </div>
67     </div>
68     <div class="lv-left-section">
69         <ul class="lv-main-menu">
70             <li class="lv-menu-item" th:each="menu:${menus}">
71                 <div class="lv-title" >
72                     <div class="lv-img " th:attrappend="class=${' ' + menu.icon}"></div>
73                     <div class="lv-text" th:text="${menu.name}"></div>
74                 </div>
75                 <ul class="lv-items">
76                     <li class="lv-item" th:each="sub:${menu.children}" th:attr="addr=${sub.addr}">
77                         <div class="lv-text" th:text="${sub.name}"></div>
78                     </li>
79                 </ul>
80             </li>
81         </ul>
82     </div>
83     <div class="lv-center-section">
84         <div class="lv-tab-container">
85             <div class="lv-tab-titles">
86                 <div class="lv-tab-title selected">
87                     <span class="lv-tab-icon fa fa-home"></span><span class="lv-tab-title-text">主页</span>
88                 </div>
89             </div>
90             <div class="lv-tab-pages">
91                 <div class="lv-tab-page">
92                     
93                 </div>
94             </div>
95         </div>
96     </div>
97 </body>
98 </html>

index.html

其中通过<link rel=”stylesheet” th:href=”@{/css/base.css}”/>来引入css文件,通过<script th:src=”@{/js/jquery-3.2.1.js}”></script>
来引入js文件,这些资源文件一定要放在static目录下才可以被发现。其中link一定要以/>结尾,否则视图解析会出错。
在上述代码片段中有以下代码:

<li class="lv-menu-item" th:each="menu:${menus}">
    <div class="lv-title" >
        <div class="lv-img " th:attrappend="class=${' ' + menu.icon}"></div>
        <div class="lv-text" th:text="${menu.name}"></div>
    </div>
    <ul class="lv-items">
        <li class="lv-item" th:each="sub:${menu.children}" th:attr="addr=${sub.addr}">
            <div class="lv-text" th:text="${sub.name}"></div>
        </li>
    </ul>
</li>

View Code

其中th:each=”menu:${menus}”表示遍历视图模型中menus的集合数据,迭代变量是menu;而th:attrappend=”class=${‘ ‘ + menu.icon}”表示给class属性添加后缀,注意一定要在绑定表达式中添加空格字符;
5. 在static目录下添加favicon.icon,并在application.properties文件中添加spring.mvc.favicon.enabled=false,这样就可以使用自己的网站图标了;
6. 运行,并输入http://localhost:8080/admin/,即可看到运行效果

5. 添加后台管理页面-风君雪科技博客