文章目錄
RestfulCRUD(員工列表)
RestfulCRUD:CRUD滿足Rest風格;
URI: /資源名稱/資源標識 HTTP請求方式區分對資源CRUD操作
普通CRUD(uri來區分操作) | RestfulCRUD | |
---|---|---|
查詢 | getEmp | emp—GET |
添加 | addEmp?xxx | emp—POST |
修改 | updateEmp?id=xxx&xxx=xx | emp/{id}—PUT |
刪除 | deleteEmp?id=1 | emp/{id}—DELETE |
實驗的請求架構;
實驗功能 | 請求URI | 請求方式 |
---|---|---|
查詢所有員工 | emps | GET |
查詢某個員工(來到修改頁面) | emp/1 | GET |
來到添加頁面 | emp | GET |
添加員工 | emp | POST |
來到修改頁面(查出員工進行信息回顯) | emp/1 | GET |
修改員工 | emp | PUT |
刪除員工 | emp/1 | DELETE |
1. 員工列表
1.查詢所有員工
(1)給員工管理設置超鏈接,發送請求/emps
(2)請求/emps
通過Conteoller層視圖解析器到templates/tem/list.html
頁面,並展示
@Controller
public class EmployeeController {
@Autowired
EmployeeDao employeeDao;
//查詢所有員工返回員工列表頁面
@GetMapping("/emps")
public String list(Map<String,Object> modelMap){
Collection<Employee> employees = employeeDao.getAll();
modelMap.put("emps",employees);
return "emp/list";
}
}
注意:只要修改dashboard.html中css的引入爲thymeleaf,list.html頁面的不要修改
我因爲修改了導致後面浪費了較長時間
2. thymeleaf公共片段抽取語法
1、抽取公共片段
<div th:fragment="copy">
© 2011 The Good Thymes Virtual Grocery
</div>
2、引入公共片段
~{templatename::selector}:模板名::選擇器
~{templatename::fragmentname}:模板名::片段名
<div th:insert="~{footer :: copy}"></div>
3、默認效果
insert的公共片段在div標籤中
如果使用th:insert等屬性進行引入,可以不用寫~{}
:
如果使用thymeleaf的行內寫法加上~{}
:[[~{}]];[(~{})]
4、三種引入公共片段的th屬性:
th:insert:將公共片段整個插入到聲明引入的元素中
th:replace:將聲明引入的元素替換爲公共片段
th:include:將被引入的片段的內容包含進這個標籤中
示例:
<footer th:fragment="copy">
© 2011 The Good Thymes Virtual Grocery
</footer>
引入方式
<div th:insert="footer :: copy"></div>
<div th:replace="footer :: copy"></div>
<div th:include="footer :: copy"></div>
效果
<div>
<footer>
© 2011 The Good Thymes Virtual Grocery
</footer>
</div>
<footer>
© 2011 The Good Thymes Virtual Grocery
</footer>
<div>
© 2011 The Good Thymes Virtual Grocery
</div>
3. dashboard.html 和 list.html公共頁面元素的抽取
將公共片段的代碼抽取到templates/commons/bar.html
</head>
<body>
<!--topbar 頂欄公共片段-->
<nav class="navbar navbar-dark sticky-top bg-dark flex-md-nowrap p-0"
th:fragment="topbar">
<a class="navbar-brand col-sm-3 col-md-2 mr-0" href="http://getbootstrap.com/docs/4.0/examples/dashboard/#">Company name</a>
<input class="form-control form-control-dark w-100" type="text" placeholder="Search" aria-label="Search">
<ul class="navbar-nav px-3">
<li class="nav-item text-nowrap">
<a class="nav-link" href="http://getbootstrap.com/docs/4.0/examples/dashboard/#">Sign out</a>
</li>
</ul>
</nav>
<!--sidebar 側欄公共片段-->
<nav class="col-md-2 d-none d-md-block bg-light sidebar"
id="sidebar">
<div class="sidebar-sticky">
在dashboard.html
中引入頂欄和側欄的公共片段:
<body>
<!--引入topbar-->
<div th:replace="commons/bar::topbar"></div>
<div class="container-fluid">
<div class="row">
<!--引入sidebar-->
<div th:replace="commons/bar::#sidebar"></div>
在list.html
中引入頂欄和側欄的公共片段:
<body>
<!--引入bar.html中抽取的topbar-->
<!--模板名:會使用thymeleaf的前後綴配置規則進行解析-->
<div th:replace="~{commons/bar::topbar}"></div>
<div class="container-fluid">
<div class="row">
<!--引入sidebar-->
<div th:replace="~{commons/bar::#sidebar(activeUri='emps')}"></div>
4. th:class 實現員工管理和Dashboard動態高亮
class屬性:class屬性的值對應的就是你定義的css的名字,它和class的屬性值相對應。
給Dashboard添加動態class:
如果activeUri==‘main.html’,使用class='nav-link active’的css樣式
<a th:class="${activeUri=='main.html'?'nav-link active':'nav-link'}"
th:href="@{/main.html}">
</a>
在dashboard.html頁面中帶上activeUri:
<div th:replace="commons/bar::#sidebar(activeUri='main.html')"></div>
給員工管理的添加動態class:
如果activeUri==‘emps’,使用class='nav-link active’的css樣式
<a th:class="${activeUri=='emps'?'nav-link active':'nav-link'}"
th:href="@{/emps}">
</a>
在list.html頁面中帶上activeUri:
<div th:replace="~{commons/bar::#sidebar(activeUri='emps')}"></div>
5. 遍歷集合顯示員工信息
<body>
<div th:replace="~{commons/bar::topbar}"></div>
<div class="container-fluid">
<div class="row">
<div th:replace="~{commons/bar::#sidebar(activeUri='emps')}"></div>
<main role="main" class="col-md-9 ml-sm-auto col-lg-10 pt-3 px-4">
<!--添加員工添加按鈕-->
<h2><button class="btn btn-sm btn-success">員工添加</button></h2>
<div class="table-responsive">
<table class="table table-striped table-sm">
<thead>
<tr>
<th>#</th>
<th>lastName</th>
<th>email</th>
<th>gender</th>
<th>department</th>
<th>birth</th>
<th>操作</th>
</tr>
</thead>
<tbody>
<tr th:each="emp:${emps}">
<td th:text="${emp.id}"></td>
<td th:text="${emp.lastName}"></td>
<td th:text="${emp.email}"></td>
<td th:text="${emp.gender}==0?'女':'男'"></td>
<td th:text="${emp.department.departmentName}"></td>
<td th:text="${#dates.format(emp.birth,'yyyy-MM-dd')}"></td>
<!--添加編輯和刪除按鈕-->
<td>
<button class="btn btn-sm btn-primary">編輯</button>
<button class="btn btn-sm btn-danger">刪除</button>
</td>
</tr>
</tbody>
</table>
</div>
</main>
</div>
</div>
2. 員工添加
1. 來到員工添加頁面
1.將員工添加按鈕變成超鏈接,提交請求路徑:
<!--員工添加爲get方式提交,超鏈接本身就是get方式,因此不用謝提交方式-->
<h2><a class="btn btn-sm btn-success" th:href="@{/emp}">員工添加</a></h2>
2.編寫Controller層處理請求:
//來到員工添加頁面
@GetMapping("/emp")
public String toAddPage(Map<String,Object> modelMap){
//查詢出所有的部門在頁面顯示
Collection<Department> departments = departmentDao.getDepartments();
modelMap.put("depts",departments);
return "emp/add";
}
3.修改add.html頁面:
<form>
<div class="form-group">
<label>LastName</label>
<input type="text" class="form-control" placeholder="zhangsan">
</div>
<div class="form-group">
<label>Email</label>
<input type="email" class="form-control" placeholder="[email protected]">
</div>
<div class="form-group">
<label>Gender</label><br/>
<div class="form-check form-check-inline">
<input class="form-check-input" type="radio" name="gender" value="1">
<label class="form-check-label">男</label>
</div>
<div class="form-check form-check-inline">
<input class="form-check-input" type="radio" name="gender" value="0">
<label class="form-check-label">女</label>
</div>
</div>
<div class="form-group">
<label>department</label>
<select class="form-control">
<!--提交的是部門id,根據部門id顯示部門名稱信息-->
<option th:value="${dept.id}" th:each="dept:${depts}" th:text="${dept.departmentName}"></option>
</select>
</div>
<div class="form-group">
<label>Birth</label>
<input type="text" class="form-control" placeholder="zhangsan">
</div>
<button type="submit" class="btn btn-primary">添加</button>
</form>
效果:
補充知識:
問題:option標籤中屬性value的值和標籤體中的內容有何區別?
2. 點擊添加按鈕完成員工添加功能
1.設置表單提交的請求路徑,添加的請求方式爲post方式:
<form th:action="@{/emp}" method="post">
2.編寫Controller層處理請求:
//員工添加功能
@PostMapping("/emp")
public String addEmp(Employee employee){
employeeDao.save(employee);
//來到員工列表頁面
//redirect:重定向一個地址(request)
//forward:轉發到一個地址(response)
return "redirect:/emps";
}
3.如何獲取請求參數的值綁定到Employee對象的屬性上呢?
SpringMvc可以實現自動封裝,前提是前端傳遞的參數名和 JavaBean對象的屬性名必須一致,否則就是null
因此給沒給要提交的請求參數加上name屬性,並且屬性名稱要和JavaBean對象的屬性名稱一致,這個就可以從後端直接獲取到前端提交的請求參數的值了。
<form th:action="@{/emp}" method="post">
<div class="form-group">
<label>LastName</label>
<input type="text" name="lastName" class="form-control" placeholder="zhangsan">
</div>
<div class="form-group">
<label>Email</label>
<input type="email" name="email" class="form-control" placeholder="[email protected]">
</div>
<div class="form-group">
<label>Gender</label><br/>
<div class="form-check form-check-inline">
<input class="form-check-input" type="radio" name="gender" value="1">
<label class="form-check-label">男</label>
</div>
<div class="form-check form-check-inline">
<input class="form-check-input" type="radio" name="gender" value="0">
<label class="form-check-label">女</label>
</div>
</div>
<div class="form-group">
<label>department</label>
<select class="form-control" name="department.id">
<!--提交的是部門id,根據部門id顯示部門名稱信息-->
<option th:value="${dept.id}" th:each="dept:${depts}" th:text="${dept.departmentName}"></option>
</select>
</div>
<div class="form-group">
<label>Birth</label>
<input type="text" class="form-control" name="birth" placeholder="zhangsan">
</div>
<button type="submit" class="btn btn-primary">添加</button>
</form>
4.修改添加生日時的日期格式:
系統默認的日期格式爲2011/12/12,可以在application.properties文件中自己指定想要的日期格式:
# 設置日期格式
spring.mvc.date-format=yyyy-MM-dd
補充知識:
問題1:標籤中的name屬性有什麼用?
例子:
<form action="/example/html/form_action.asp" method="get">
<p>Name: <input type="text" name="fullname" /></p>
<p>Email: <input type="text" name="email" /></p>
<input type="submit" value="Submit" />
</form>
提交的參數爲:
fullname=zhangsan&email=zhangsan.com
問題2:如何實現提交的請求參數和JavaBean對象的屬性進行自動封裝?
注意:name屬性的值爲請求參數的名稱
<form action="book" method="post">
書名: <input type="text" name="bookName"/><br>
作者: <input type="text" name="author"/><br>
庫存: <input type="text" name="stock"/><br>
價格: <input type="text" name="price"/><br>
銷量: <input type="text" name="sales"/><br>
<input type="submit" value="添加一本圖書"/>
</form>
javaBean對象以及裏面的屬性,請求參數要和屬性名一致
public class Book {
private String bookName;
private String author;
private Integer stock;
private Integer price;
private Integer sales;
}
@Controller
public class PojoController {
@RequestMapping("/book")
public String test(Book book){
System.out.println("我要保存的圖書:"+book);
return "success";
}
}
如果使用get方式提交,會看到提交的參數爲:
bookName=jianai&author=hh&stock=12&price=34&sales=45
3. 員工修改
1. 來到員工修改頁面
1.在list.html頁面設置點擊編輯的請求:
<a class="btn btn-sm btn-primary" th:href="@{/emp/}+${emp.id}">編輯</a>
2.在Controller處理請求:
//來到員工修改頁面
@GetMapping("/emp/{id}")
public String toEditPage(@PathVariable("id")Integer id,Map<String,Object> modelMap){
Employee employee = employeeDao.get(id);
modelMap.put("emp",employee);
//頁面要顯示所有我的部門列表
Collection<Department> departments = departmentDao.getDepartments();
modelMap.put("depts",departments);
//回到修改頁面(即使修改頁面也是添加頁面)
return "emp/add";
}
3.修改修改頁面add.html:
<!--區分是員工添加還是員工修改,員工修改頁面emp!=null-->
<form th:action="@{/emp}" method="post">
<!--發送put請求修改員工數據-->
<!--1.SpringMvc中配置HiddenHTTPMethodFilter(SpringBoot已經配置好了)
2.頁面創建一個post表單
3.創建一個input選項,name="_method";值value就是我們制定的跟你去方式-->
<input type="hidden" name="_method" value="put" th:if="${emp!=null}"/>
<input type="hidden" name="id" th:if="${emp!=null}" th:value="${emp.id}"/>
<div class="form-group">
<label>LastName</label>
<input type="text" name="lastName" class="form-control" th:value="${emp!=null}?${emp.lastName}">
</div>
<div class="form-group">
<label>Email</label>
<input type="email" name="email" class="form-control" th:value="${emp!=null}?${emp.email}">
</div>
<div class="form-group">
<label>Gender</label><br/>
<div class="form-check form-check-inline">
<input class="form-check-input" type="radio" name="gender" value="1" th:checked="${emp!=null}?${emp.gender==1}">
<label class="form-check-label">男</label>
</div>
<div class="form-check form-check-inline">
<input class="form-check-input" type="radio" name="gender" value="0" th:checked="${emp!=null}?${emp.gender==0}">
<label class="form-check-label">女</label>
</div>
</div>
<div class="form-group">
<label>department</label>
<select class="form-control" name="department.id">
<!--提交的是部門id,根據部門id顯示部門名稱信息-->
<option th:selected="${emp!=null}?${dept.id==emp.department.id}" th:value="${dept.id}" th:each="dept:${depts}" th:text="${dept.departmentName}"></option>
</select>
</div>
<div class="form-group">
<label>Birth</label>
<input type="text" class="form-control" name="birth" th:value="${emp!=null}?${#dates.format(emp.birth,'yyyy-MM-dd')}">
</div>
<button type="submit" class="btn btn-primary" th:text="${emp!=null}?'修改':'添加'">添加</button>
</form>
效果:
補充:
問題1:inpu標籤中的value屬性?
<form action="/example/html/form_action.asp" method="get">
First name: <input type="text" name="fname" value="George" /><br />
Last name: <input type="text" name="lname" value="Bush" /><br />
<input type="submit" value="Submit form" />
</form>
提交後:name提交的請求參數 名稱,value代表提交的請求參數的值
fname=George&lname=Bush
問題2 :select標籤中的selected屬性?
<select>
<option>Volvo</option>
<option selected="selected">Saab</option>
<option>Mercedes</option>
<option>Audi</option>
</select>
2. 點擊修改按鈕完成員工修改功能
//員工修改
@PutMapping("/emp")
public String updateEmployee(Employee employee){
System.out.println(employee);
employeeDao.save(employee);
return "redirect:/emps";
}
遺留問題:在控制檯打印employee對象,但是卻打印不出來,修改數據能修改成功
原因:原來是springboot2.2.x後默認不支持put、delete請求。
需在配置文件裏手動配置:
spring.mvc.hiddenmethod.filter.enabled=true
8. 員工刪除
<form th:action="@{/emp/}+${emp.id}" method="post">
<input type="hidden" name="_method" value="delete"/>
<button type="submit" class="btn btn-sm btn-danger">刪除</button>
</form>
//員工刪除
@DeleteMapping("/emp/{id}")
public String deleteEmp(@PathVariable("id")Integer id){
employeeDao.delete(id);
return "redirect:/emps";
}
報錯405:
原因:原來是springboot2.2.x後默認不支持put、delete請求。
需在配置文件裏手動配置:
spring.mvc.hiddenmethod.filter.enabled=true