1.Springboot配置server相關配置(包括默認tomcat的相關配置)
下面的配置也都是模板,需要的時候在application.properties配置即可
############################################################
#
# Server 服務端相關配置
#
############################################################
# 配置api端口號
server.port=8088
# 配置context-path, 一般來說這個配置在正式發布的時候不配置
server.context-path=/MySpringboot
# 錯誤頁,指定發生錯誤時,跳轉的URL --> BasicErrorController
#server.error.path=/error
# session最大超時時間(分鍾),默認為30分鍾
server.session-timeout=60
# 該服務綁定IP地址,啟動服務器時如本機不是該IP地址則拋出異常啟動失敗,
# 只有特殊需求的情況下才配置, 具體根據各自的業務來設置
#server.address=192.168.1.2
############################################################
# Server - tomcat 相關常用配置
############################################################
# tomcat最大線程數, 默認為200
#server.tomcat.max-threads=250
# tomcat的URI編碼
server.tomcat.uri-encoding=UTF-8
# 存放Tomcat的日志、Dump等文件的臨時文件夾,默認為系統的tmp文件夾
#(如:C:%users\Shanhy\AppData\Local\Temp)
#server.tomcat.basedir=H:/springboot-tomcat-tmp
# 打開Tomcat的Access日志,並可以設置日志格式的方法:
#server.tomcat.access-log-enabled=true
#server.tomcat.access-log-pattern=
# accesslog目錄,默認在basedir/logs
#server.tomcat.accesslog.directory=
# 日志文件目錄
#logging.path=H:/springboot-tomcat-tmp
# 日志文件名稱,默認為spring.log
#logging.file=myapp.log
例如上面我簡單的修改了一下默認的端口與contextPath等信息,啟動測試:
2.整合模板引擎
springboot提倡的方式是整合freemarker和thymeleaf。之前用普通項目的時候都是用的JSP,實際上JSP是一種servlet,需要在后台渲染頁面之后在前台進行展示,所以比較耗時。而引擎相對於JSP來說就比較省時。引擎常用的有freemarker和thymeleaf,在項目中可以兩種一起結合使用,但是一般有一種就足夠了。注意applications.properties文件中兩者的前綴一個最后加/一個不加。
2.1整合Freemarker引擎
freemarker的文件一般后綴是 ftl,關於freemarker的基本使用參考我的freemarker標簽博客即可。
(1)首先pom中引入freemarker引擎
<!-- 引入 freemarker 模板依賴 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-freemarker</artifactId> </dependency>
(2)application.properties引入freemarker相關配置:
############################################################
#
# freemarker 靜態資源配置
#
############################################################
#設定ftl文件路徑
spring.freemarker.template-loader-path=classpath:/templates
# 關閉緩存, 即時刷新, 上線生產環境需要改為true
spring.freemarker.cache=false
spring.freemarker.charset=UTF-8
spring.freemarker.check-template-location=true
spring.freemarker.content-type=text/html
spring.freemarker.expose-request-attributes=true
spring.freemarker.expose-session-attributes=true
spring.freemarker.request-context-attribute=request
spring.freemarker.suffix=.ftl
(3)編寫后台Controller
package cn.qlq.action; import org.springframework.stereotype.Controller; import org.springframework.ui.ModelMap; import org.springframework.web.bind.annotation.RequestMapping; /** * 返回freemarker相關頁面 * * @author Administrator * */ @Controller @RequestMapping("freemarker") public class FreemarkerController { /** * 會跳轉到templates/freemarker/index.ftl * * @param map * @return */ @RequestMapping("/index") public String index(ModelMap map) { map.addAttribute("name", "testname"); return "freemarker/index"; } /** * 會跳轉到templates/freemarker/center/center.ftl * * @return */ @RequestMapping("/center") public String center() { return "freemarker/center/center"; } }
(4)建立模板結構:
index.ftl內容如下:
<!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8" /> <title>FreeMarker模板引擎</title> </head> <body> FreeMarker模板引擎 <h1>${name}</h1> </body> </html>
center.ftl內容如下:
<!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8" /> <title></title> </head> <body> FreeMarker模板引擎 <h1>center page</h1> </body> </html>
啟動項目進行測試:
2.2整合thymeleaf引擎
thymeleaf文件的后綴是html。這種方式也適用於前后端分離。
(1)首先pom中引入thymeleaf引擎
<!-- 引入 thymeleaf 模板依賴 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> </dependency>
(2)applications.properties引入配置:
############################################################
#
# thymeleaf 靜態資源配置
#
############################################################
spring.thymeleaf.prefix=classpath:/templates/
spring.thymeleaf.suffix=.html
spring.thymeleaf.mode=HTML5
spring.thymeleaf.encoding=UTF-8
spring.thymeleaf.content-type=text/html
# 關閉緩存, 即時刷新, 上線生產環境需要改為true
spring.thymeleaf.cache=false
(3)編寫后台Controller
package cn.qlq.action; import org.springframework.stereotype.Controller; import org.springframework.ui.ModelMap; import org.springframework.web.bind.annotation.RequestMapping; /** * 返回freemarker相關頁面 * * @author Administrator * */ @Controller @RequestMapping("th") public class ThymeleafController { /** * 會跳轉到templates/freemarker/index.html * * @param map * @return */ @RequestMapping("/index") public String index(ModelMap map) { map.addAttribute("name", "testname"); return "thymeleaf/index"; } /** * 會跳轉到templates/thymeleaf/center/center.html * * @return */ @RequestMapping("/center") public String center() { return "thymeleaf/center/center"; } }
(4)編寫界面:
center.html: (一個靜態的頁面)
<!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8" /> <title></title> </head> <body> Thymeleaf模板引擎 <h1>center page</h1> </body> </html>
index.html(下面這個試用於前后端分離,也就是說在后端沒有返回數據的時候h1顯示的是中間的hello word ~~~ ,如果有數據了會用${name}取到的值取代兩個標簽中間的內容)
<!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8" /> <title></title> </head> <body> Thymeleaf模板引擎 <h1 th:text="${name}">hello world~~~~~~~</h1> </body> </html>
單獨訪問這個index.html效果如下:
(5)啟動測試:
3.thymeleaf 獲取項目路徑 contextPath
1.頁面通過標簽獲取:
<span th:text="${#httpServletRequest.getContextPath()}">abc</span>
如下:
<a th:href="${#httpServletRequest.getContextPath()+'/index.html'}">XXX</a>
結果:
2.通過JS獲取
<script th:inline="javascript">
var contextPath= [[@{/}]];
</script>
關於項目中路徑帶根路徑的URL的寫法如下:
<link rel="stylesheet" th:href="${#httpServletRequest.getContextPath()+'/static/x-admin/css/xadmin.css'}"/> <script type="text/javascript" th:src="${#httpServletRequest.getContextPath()+'/static/js/jquery.min.js'}"></script>
補充:通過JS獲取request和session中變量的方法如下:
第一種方法:
<script th:inline="javascript"> var currentUsername= /*[[${session.user.username}]]*/; var address=/*[[${message.address}]]*/ </script>
第二種方法:
<script th:inline="javascript"> /*<![CDATA[*/ var currentUsername= /*[[${session.user.username}]]*/; /*]]>*/ </script>
4. thymeleaf 獲取session中的值
后台存:
@RequestMapping("doLogin") @ResponseBody public JSONResultUtil doLogin(String username, String password, HttpSession session) { User loginUser = null; if (username.equals("admin") && password.equals("admin")) { loginUser = new User(); loginUser.setFullname("系統管理員"); } else { loginUser = userService.getUserByUserNameAndPassword(username, password); } if (loginUser == null) { return JSONResultUtil.error("賬號或者密碼錯誤"); } session.setAttribute("user", loginUser); return JSONResultUtil.ok(); }
前台:
<span class="x-red" th:text="${session.user.fullname}">admin</span>
5.thymeleaf常用標簽用法(如果會用可以不看下面例子)
官方文檔:https://www.thymeleaf.org/documentation.htm
https://www.thymeleaf.org/doc/tutorials/2.1/usingthymeleaf.html
下面都是針對的動態數據的方式(數據從后台返回到前台的方法),如果是靜態方式使用方法同以前普通的html的使用方法一樣。
0.字符串拼接
<a th:href="${context+'/JS/XXXX'+context}">XXX</a>
context是變量,單引號中間的是常量
結果:
1.基本使用方式
th:id="${id}" th:name="${name}" th:value="${name}" 等標簽如果取到屬性就會取代原來界面上的對應的屬性。
例如對於如下頁面:
用戶姓名:<input id="id" name="name" value="value" th:id="${user.username}" th:name="${user.username}" th:value="${user.username}"/>
(1)查看靜態頁面
(2)經過后台的渲染頁面
2.對象引用方式
如下面寫法:
<div th:object="${user}"> 用戶姓名:<input th:id="*{username}" th:name="*{username}" th:value="*{username}"/> <br/> 用戶生日:<input th:value="*{#dates.format(birthday, 'yyyy-MM-dd hh:mm:ss')}"/> <br/> </div>
3.時間類型轉換
<br/> 用戶生日:<input th:value="${user.birthday}"/> <br/> 用戶生日:<input th:value="${#dates.format(user.birthday, 'yyyy-MM-dd')}"/>
界面查看:
4.th:text與th:utext
th:text會將后台傳回來的字符串原封不動的替換標簽中的內容為后台返回的內容
th:utext會解析后台傳回來的內容中的html標簽,也就是這個會解析html標簽。
如下:后台設置地址為:
user.setAddress("<font color='red'>中國<font>");
前台代碼:
text 與 utext :<br/> <span th:text="${user.address}">abc</span> <br/> <span th:utext="${user.address}">abc</span>
結果:
5.URL
URL的用法是: @{url}。
例如:
URL:<br/> <a href="http://www.baidu.com" th:href="@{${user.address}}">網站地址</a> <br/>
結果:
6.引入靜態資源文件js/css
如果引入靜態文件需要在applications.properties文件中進行配置放開靜態文件:
#設定靜態文件路徑,js,css等
spring.mvc.static-path-pattern=/static/**
對應的目錄結構:
頁面引入JS的方法:
<script th:src="@{/static/js/test.js}"></script>
7.條件判斷 th:if th:unless與th:if
th:if 相當於 JSTL的<:if>標簽,判斷等於直接用 == ,大於用ge(grater than),大於等於用ge(grater or equal)。。。。。。
th:unless是if的取反
<br/> <div th:if="${user.id} == 18">十八歲的天空</div> <div th:if="${user.id} gt 18">你老了</div> <div th:if="${user.id} lt 18">你很年輕</div> <div th:if="${user.id} ge 18">大於等於</div> <div th:if="${user.id} le 18">小於等於</div> <br/> <br/> <div th:unless="${user.id} == 18">十八歲的天空</div> <div th:unless="${user.id} gt 18">你老了</div> <div th:unless="${user.id} lt 18">你很年輕</div> <div th:unless="${user.id} ge 18">大於等於</div> <div th:unless="${user.id} le 18">小於等於</div> <br/>
后台設置id為2查看結果頁面填充結果:
8.循環
th:each相當於<c:foreach....>
<br/> <table> <tr> <th>姓名</th> <th>性別</th> <th>id描述</th> <th>生日</th> </tr> <tr th:each="person:${userList}"> <td th:text="${person.username}"></td> <td th:text="${person.sex}"></td> <td th:text="${person.id gt 18} ? id大於18 : id小於18">18歲</td> <td th:text="${#dates.format(user.birthday, 'yyyy-MM-dd hh:mm:ss')}"></td> </tr> </table> <br/>
后台:
@RequestMapping("/test") public String test(ModelMap map) { User user = new User(); user.setId(2); user.setSex("nv"); user.setUsername("lisi"); user.setAddress("http://qiaoliqiang.cn"); user.setBirthday(new Date()); map.addAttribute("user", user); User user2 = user; List<User> userList = new ArrayList<>(); userList.add(user); userList.add(user2); map.addAttribute("userList", userList); return "thymeleaf/test"; }
前台填充后結果:
例如:循環取list中數據放入option
<select name="bodylocation" > <option th:each="body:${bodys}" th:text="${body}" th:value="${body}"></option> </select>
循環中option的選中回顯如下:
<select name="bodylocation" > <option th:each="body:${bodys}" th:text="${body}" th:value="${body}" th:selected="${plan.bodylocation eq body}"></option> </select>
補充:循環遍歷集和顯示checkbox以及回顯選中的值:
<input type ="checkbox" name="userblank" th:each ="parentName : ${parentNames}" th:value="${parentName}" th:text ="${parentName}" th:attr ="checked=${parentNamesSeted.contains(parentName)?true:false}" />
java代碼:
List<String> parentNames = firstChargeReportService.listDistinctParentName(); map.addAttribute("from", from); map.addAttribute("parentNames", parentNames); List<String> parentNamesSeted = new ArrayList<>(); String userblank = user.getUserblank(); if (StringUtils.isNotBlank(userblank)) { parentNamesSeted = Arrays.asList(userblank.split(",")); } map.addAttribute("parentNamesSeted", parentNamesSeted);
補充:循環遍歷Map中數據
<input type="text" name="foods" autocomplete="off" class="layui-input" th:each="entry:${foods}" th:placeholder="${entry.key}" th:class="entry.value" onchange=""/>
補充:遍歷List<Map>的方式,已經知道Map中的key
<tr th:each="sequence:${sequences}"> <td th:text="${sequenceStat.index+1}"></td> <td th:utext="${sequence['fullname']}"></td> <td th:text="${sequence['stepnumber']}"></td> </tr>
補充:遍歷出來也有一個狀態信息,可以獲取序號、是否第一個等信息,如下:
When using th:each, Thymeleaf offers a mechanism useful for keeping track of the status of your iteration: the status variable.
Status variables are defined within a th:each attribute and contain the following data:
- The current iteration index, starting with 0. This is the index property.
- The current iteration index, starting with 1. This is the count property.
- The total amount of elements in the iterated variable. This is the size property.
- The iter variable for each iteration. This is the current property.
- Whether the current iteration is even or odd. These are the even/odd boolean properties.
- Whether the current iteration is the first one. This is the first boolean property.
- Whether the current iteration is the last one. This is the last boolean property.
例如:
<tr th:each="prod,iterStat : ${prods}" th:class="${iterStat.odd}? 'odd'"> <td th:text="${prod.name}">Onions</td> <td th:text="${prod.price}">2.41</td> <td th:text="${prod.inStock}? #{true} : #{false}">yes</td> </tr>
如果只寫了一個變量,比如prod,那么thymeleaf會默 認給個“變量名+Stat"的狀態變量 prodStat。
9.th:switch與th:case
相當於java的switch 。。。 case 語句
<div th:switch="${user.username}"> <p th:case="'zhangsan'">zhangsan</p> <p th:case="'lisi'">lisi</p> <p th:case="*">其他用戶</p> </div>
10. #{}讀取資源文件 properties文件 (不能直接讀取,需要結合th標簽使用)
(1)applications.properties文件中配置資源文件
############################################################ # # 配置i18n 資源文件,供thymeleaf 讀取 # ############################################################ spring.messages.basename=i18n/messages spring.messages.cache-seconds=3600 spring.messages.encoding=UTF-8
(2)建立相應文件:
messages.properties內容如下:
############################################################ # # 用戶自定義權限 # ############################################################ # 普通管理員 roles.manager=manager roles.superadmin=superadmin
(3)頁面使用#{key}讀取即可
<p th:utext="#{roles.manager}">xxxxxxx</p>
結果:
manager
11.表單提交
<form th:action="@{/th/postform}" th:object="${user}" method="post" th:method="post"> <input type="text" th:field="*{username}"/> <input type="text" th:field="*{address}"/> <input type="submit"/> </form>
查看填充后的源碼:
th:object="${user}"是上面介紹的對象引用的方式,
th:field="*{username}"相當於 id="username" name="username" value="${username}"
后台接受的方法:(重定向到 /th/test )
/** * * @return */ @RequestMapping("/postform") public String postform(User user) { System.out.println(user.getUsername()); System.out.println(user.getAddress()); return "redirect:/th/test"; }
12.下拉選擇框的默認選中與單選框的選中:
<br/> <select> <option >選擇框</option> <option th:selected="${user.username eq 'zhangsan'}">zhangsan</option> <option th:selected="${user.username eq 'lisi'}">lisi</option> <option th:selected="${user.username eq 'wangwu'}">wangwu</option> </select> <br/> <br/> <input type="radio" th:checked="${user.sex eq 'nan'}"/>男 <input type="radio" th:checked="${user.sex eq 'nv'}"/>女 <br/>
后台:
@RequestMapping("/test") public String test(ModelMap map) { User user = new User(); user.setId(2); user.setSex("nv"); user.setUsername("lisi"); user.setAddress("http://qiaoliqiang.cn"); user.setBirthday(new Date()); map.addAttribute("user", user); return "thymeleaf/test"; }
前台填充后結果:
13 . 判斷集合不為空集合
<div th:unless="${#lists.isEmpty(commentsByViewId)}"> <b>評論:<br/></b> <div th:each="comment:${commentsByViewId}"> <span th:text="${#dates.format(view.createtime, 'yyyy-MM-dd')}"></span> <span th:text="${comment.content}"></span> </div> </div>
補充:遍歷map的方式,獲取key、value以及序號
Map中數據如下
Map<String, String> result = new LinkedHashMap<>(); result.put("01", "1月"); result.put("02", "2月"); result.put("03", "3月"); result.put("04", "4月"); result.put("05", "5月"); result.put("06", "6月"); result.put("07", "7月"); result.put("08", "8月"); result.put("09", "9月"); result.put("10", "10月"); result.put("11", "11月"); result.put("12", "12月"); result.put("", "---");
遍歷方法:
<span th:each="item,userStat:${months}"> <span th:text="${item.key}"></span> <span th:text="${item.value}"></span> ===== <span th:text="${userStat.index}+1"></span> <span th:text="${userStat.current.key}"></span><!-- key--> <span th:text="${userStat.current.value}"></span><!-- value--> <br/> </span>
結果:
補充:thymeleaf中的==可以用於兩個變量比較
例如:下拉列表根據屬性動態設置值:
<select name="flowerId"> <option th:each="flowerIdAndName:${flowerIdAndNames}" th:text="${flowerIdAndName['name']}" th:value="${flowerIdAndName['id']}" th:selected="${bean.flowerId} == ${flowerIdAndName['id']}"></option> </select>
后端代碼:
Purchase findById = purchaseService.findById(id); map.addAttribute("bean", findById); List<Map<String, Object>> flowerIdAndNames = flowerService.listFlowerIdAndNames(); map.put("flowerIdAndNames", flowerIdAndNames);
補充:thymeleaf動態修改元素的display屬性
th:style="'display:' + @{(${bean.productstatus == '未出租' or bean.productstatus == '已出租'} ? 'inline-block' : 'none' )} + ''"
補充:thymeleaf在JS的onclick事件中傳遞參數的方法如下:
<a href="javascript:void(0)" title="刪除" th:onclick="'deleteStage(' + ${stage.id} + ')'"> <i class="layui-icon"></i> </a>
如果加字符串可以:
<a href="javascript:void(0)" th:onclick="'replyInstantMessage(' + ${instantMessage.id} + ',\'' + ${instantMessage.creator} + '\')'">回復</a>
總結:
(1) thymeleaf中 eq 等計算方式可以在}里面也可以在}外面,比如,下面是等價的:
<a _href="/fixedReport/list.html" th:if="${session.user.roles eq '系統管理員'}"> <i class="iconfont"></i> <cite>日報表</cite> </a>
<a _href="/fixedReport/list.html" th:if="${session.user.roles} eq '系統管理員'"> <i class="iconfont"></i> <cite>日報表</cite> </a>
(2)${}是獲取容器上下文變量的值,應該是包括所有上下文中的key-value。
*{}這個表達式,是獲取指定的對象中的變量值。需要在前面指定對象,可以是集合中的某個對象,也可以是單獨的一個對象。
#maps 這個是thymeleaf的工具類,還有#dates#calendars#numbers #strings#objects#bools#arrays#lists#sets#ids