当天的git地址:thymeleaf静态页面展示 thymeleaf的坐标
<!--thymeleaf配置--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> </dependency>springboot 相关配置
spring: thymeleaf: cache: false #关闭缓存页面需要放在templates目录下。这是springboot自动配置作用
注意controller,方法上不能加@ResponseBody了,返回的页面名称,页面的前缀后缀被springboot给你省略掉了
@RequestMapping("demo") @Controller public class TestController { @GetMapping("test") public String test(Model model,String id) { System.out.println(id); model.addAttribute("name", "zs"); //集合存储 List<User> list = new ArrayList<>(); User jack = new User("jack", 23,"bj"); User lucy = new User("lucy", 21,"sh"); list.add(jack); list.add(lucy); model.addAttribute("list", list); //Map定义 Map<String,Object> dataMap = new HashMap<String,Object>(); dataMap.put("No","123"); dataMap.put("address","深圳"); model.addAttribute("dataMap",dataMap); //存储一个数组 String[] names = {"张三","李四","王五"}; model.addAttribute("names",names); //日期 model.addAttribute("now",new Date()); //if条件 model.addAttribute("age",22); return "index"; } } <!DOCTYPE html> <html xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8"> <title>Thymeleaf的入门</title> </head> <body> <!--form表单,@{}作用是链接地址--> <p th:text="${name}"></p> <form th:action="@{/demo/test}"> <input th:type="text" th:name="id"> <button>提交</button> </form> <!--循环 userStart是状态,没什么用--> <table> <tr> <td>下标</td> <td>姓名</td> <td>年龄</td> <td>住址</td> </tr> <tr th:each="user,userStart:${list}"> <td th:text="${userStart.index}"></td> <td th:text="${user.getName()}"></td> <td th:text="${user.getAge()}"></td> <td th:text="${user.getAddress()}"></td> </tr> </table> <!--遍历map--> <div th:each="map:${dataMap}"> <div th:text="${map}"/> <br/>----------------- KEY:<span th:text="${map.key}"/> VALUE:<span th:text="${map.value}"/> <br/>----------------- </div> <!--遍历数组--> <div th:each="name,nameStat:${names}"> <span th:text="${nameStat.count}"/> <span th:text="${name}"/> </div> <!--日期转换--> <div th:text="${#dates.format(now,'yyyy-MM-dd hh:dd:ss')}"/> <!--条件判断--> <div th:if="${(age==22)}">我它娘22了</div> <div id="W" th:include="footer::copy"/> </body> </html>controller 将用户条件集合 查询上来的结果返回回去
@GetMapping("/list") public String search(@RequestParam Map<String, String> searchMap, Model model) { //特殊符号处理 handleSearchMap(searchMap); //执行查询返回值 Map resultMap = searchService.search(searchMap); model.addAttribute("searchMap", searchMap); model.addAttribute("resultMap", resultMap); return "search"; }html :展示的样式
获取条件map,搜索条件就行了
<!--搜索框--> <li class="active"> <span th:text="${searchMap.keywords}"></span> </li>判断条件map里有没有品牌条件,有的话就显示
<!--品牌--> <li class="with-x" th:if="${#maps.containsKey(searchMap,'brand')}"> 品牌:<span th:text="${searchMap.brand}"/> <a th:href="@{${#strings.replace(url,'&brand='+searchMap.brand,'')}}">×</a> </li>1、是一个from表单,需要将条件回显到搜索框中
<div class="search"> <form th:action="@{search/list}" class="sui-form form-inline"> <!--searchAutoComplete--> <div class="input-append"> <input th:type="text" id="autocomplete" name="keywords" th:value="${searchMap.keywords}" class="input-error input-xxlarge" /> <button class="sui-btn btn-xlarge btn-danger" th:type="submit">搜索</button> </div> </form> </div>每次点击一个条件都。都会拼接上一次的请求。例如:http://localhost:9009/search/list?keywords=手机
所以我们可以在后端拼接每次条件的url路径。
1、/search/list 是写死的,后面条件慢慢拼接2、拼接一个?号3、遍历条件map,获取里面所有的4、分页,和排序不用拼接上去5、把条件的名称和对应的条件的内容,条件可能不止一个在拼接一个&符号6、拼接完毕,再把最后一个&截取掉 //字符串拼接 StringBuilder url = new StringBuilder("/search/list"); //map里有查询条件 if (searchMap.size() > 0 && searchMap != null) { //拼接? url.append("?"); //遍历查询条件的key for (String paramKey : searchMap.keySet()) { //排序和分页不用拼接到url上 if (!"sortRule".equals(paramKey) && !"sortField".equals(paramKey) && !"pageNum".equals(paramKey)) { //拼接url http://localhost:9009/search/list?keywords=手机&spec_颜色=金色 url.append(paramKey).append("=").append(searchMap.get(paramKey)).append("&"); } } //截取掉最后一位的连接符 & String urlString = url.toString(); urlString = urlString.substring(0, urlString.length() - 1); model.addAttribute("url", urlString);通过标签进行跳转。获取返回上来的上次url请求路径。拿上次的url拼接这次的价格
<div class="type-wrap" th:unless="${#maps.containsKey(searchMap,'price')}"> <div class="fl key">价格</div> <div class="fl value"> <ul class="type-list"> <li> <a th:href="@{${url}(price='0-500')}">0-500元</a> </li> <li> <a th:href="@{${url}(price='500-1000')}">500-1000元</a> </li> <li> <a th:href="@{${url}(price='1000-1500')}">1000-1500元</a> </li> <li> <a th:href="@{${url}(price='1500-2000')}">1500-2000元</a> </li> <li> <a th:href="@{${url}(price='2000-3000')}">2000-3000元 </a> </li> <li> <a th:href="@{${url}(price='3000')}">3000元以上</a> </li> </ul> </div> <div class="fl ext"> </div> </div>1、给x号 写入到标签
2、当我点击x号。会把url路径上的品牌条件,替换为空字符串
<!--品牌--> <li class="with-x" th:if="${#maps.containsKey(searchMap,'brand')}"> 品牌:<span th:text="${searchMap.brand}"/> <a th:href="@{${#strings.replace(url,'&brand='+searchMap.brand,'')}}">×</a> </li>分页的工具类,创建再common下
package com.changgou.util; import java.io.Serializable; import java.util.List; /** * 分页对象 * @param <T> */ public class Page <T> implements Serializable{ //当前默认为第一页 public static final Integer pageNum = 1; //默认每页显示条件 public static final Integer pageSize = 20; //判断当前页是否为空或是小于1 public static Integer cpn(Integer pageNum){ if(null == pageNum || pageNum < 1){ pageNum = 1; } return pageNum; } // 页数(第几页) private long currentpage; // 查询数据库里面对应的数据有多少条 private long total;// 从数据库查处的总记录数 // 每页显示多少分页标签 private int size; // 下页 private int next; private List<T> list; // 最后一页 private int last; private int lpage; private int rpage; //从哪条开始查 private long start; //全局偏移量 public int offsize = 2; public Page() { super(); } /**** * * @param currentpage 当前页 * @param total 总记录数 * @param pagesize 每页显示多少条 */ public void setCurrentpage(long currentpage,long total,long pagesize) { //如果整除表示正好分N页,如果不能整除在N页的基础上+1页 int totalPages = (int) (total%pagesize==0? total/pagesize : (total/pagesize)+1); //总页数 this.last = totalPages; //判断当前页是否越界,如果越界,我们就查最后一页 if(currentpage>totalPages){ this.currentpage = totalPages; }else{ this.currentpage=currentpage; } //计算起始页 this.start = (this.currentpage-1)*pagesize; } /**** * 初始化分页 * @param total * @param currentpage * @param pagesize */ public void initPage(long total,int currentpage,int pagesize){ //总记录数 this.total = total; //每页显示多少条 this.size=pagesize; //计算当前页和数据库查询起始值以及总页数 setCurrentpage(currentpage, total, pagesize); //分页计算 int leftcount =this.offsize, //需要向上一页执行多少次 rightcount =this.offsize; //起点页 this.lpage =currentpage; //结束页 this.rpage =currentpage; //2点判断 this.lpage = currentpage-leftcount; //正常情况下的起点 this.rpage = currentpage+rightcount; //正常情况下的终点 //页差=总页数和结束页的差 int topdiv = this.last-rpage; //判断是否大于最大页数 /*** * 起点页 * 1、页差<0 起点页=起点页+页差值 * 2、页差>=0 起点和终点判断 */ this.lpage=topdiv<0? this.lpage+topdiv:this.lpage; /*** * 结束页 * 1、起点页<=0 结束页=|起点页|+1 * 2、起点页>0 结束页 */ this.rpage=this.lpage<=0? this.rpage+(this.lpage*-1)+1: this.rpage; /*** * 当起点页<=0 让起点页为第一页 * 否则不管 */ this.lpage=this.lpage<=0? 1:this.lpage; /*** * 如果结束页>总页数 结束页=总页数 * 否则不管 */ this.rpage=this.rpage>last? this.last:this.rpage; } /**** * * @param total 总记录数 * @param currentpage 当前页 * @param pagesize 每页显示多少条 */ public Page(long total,int currentpage,int pagesize) { initPage(total,currentpage,pagesize); } //上一页 public long getUpper() { return currentpage>1? currentpage-1: currentpage; } //总共有多少页,即末页 public void setLast(int last) { this.last = (int) (total%size==0? total/size : (total/size)+1); } /**** * 带有偏移量设置的分页 * @param total * @param currentpage * @param pagesize * @param offsize */ public Page(long total,int currentpage,int pagesize,int offsize) { this.offsize = offsize; initPage(total, currentpage, pagesize); } public long getNext() { return currentpage<last? currentpage+1: last; } public void setNext(int next) { this.next = next; } public long getCurrentpage() { return currentpage; } public long getTotal() { return total; } public void setTotal(long total) { this.total = total; } public long getSize() { return size; } public void setSize(int size) { this.size = size; } public long getLast() { return last; } public long getLpage() { return lpage; } public void setLpage(int lpage) { this.lpage = lpage; } public long getRpage() { return rpage; } public void setRpage(int rpage) { this.rpage = rpage; } public long getStart() { return start; } public void setStart(long start) { this.start = start; } public void setCurrentpage(long currentpage) { this.currentpage = currentpage; } /** * @return the list */ public List<T> getList() { return list; } /** * @param list the list to set */ public void setList(List<T> list) { this.list = list; } public static void main(String[] args) { //总记录数 //当前页 //每页显示多少条 int cpage =17; Page page = new Page(1001,cpage,50,7); System.out.println("开始页:"+page.getLpage()+"__当前页:"+page.getCurrentpage()+"__结束页"+page.getRpage()+"____总页数:"+page.getLast()); } }controller层
1、创建分页对象2、把当前页、一页显示的条目数全部传入到分页对象中 //分页数数据 /** * 1、总页数 * 2、当前页 * 3、一页显示的条目数 */ Page<SkuInfo> page= new Page<SkuInfo>( Long.parseLong(resultMap.get("total")+""), Integer.parseInt(resultMap.get("pageNum")+""), Page.pageSize ); model.addAttribute("page",page);前端html
上一页 <li class="prev disabled"> <a th:href="@{${url}(pageNum=${page.upper})}">«上一页</a> </li>下一页
<li class="next"> <a th:href="@{${url}(pageNum=${page.next})}">下一页»</a> </li>中间显示的条目数
1、遍历获取当前显示的多少页,到多少页(例如2-6)2、判断那个是当前页,如果是当前页给一个当前页的样式3、展示显示页码4、每个页码,都拼接上了url路径 <li th:each="i:${#numbers.sequence(page.lpage,page.rpage)}" th:class="${i}==${page.currentpage}?'active':''"> <a th:href="@{${url}(pageNum=${i})}" th:text="${i}"></a> </li>fo> page= new Page( Long.parseLong(resultMap.get(“total”)+""), Integer.parseInt(resultMap.get(“pageNum”)+""), Page.pageSize );
model.addAttribute(“page”,page);
**前端html** * 上一页 ```java <li class="prev disabled"> <a th:href="@{${url}(pageNum=${page.upper})}">«上一页</a> </li>下一页
<li class="next"> <a th:href="@{${url}(pageNum=${page.next})}">下一页»</a> </li>中间显示的条目数
1、遍历获取当前显示的多少页,到多少页(例如2-6)2、判断那个是当前页,如果是当前页给一个当前页的样式3、展示显示页码4、每个页码,都拼接上了url路径 <li th:each="i:${#numbers.sequence(page.lpage,page.rpage)}" th:class="${i}==${page.currentpage}?'active':''"> <a th:href="@{${url}(pageNum=${i})}" th:text="${i}"></a> </li>