Thymeleaf-demo
中餐厅Demo嘉宾:黄晓明 秦海璐 林述巍 王俊凯(走) 杨紫 仝卓 王鹤棣
1)嘉宾展示列表;
2)增加、删除嘉宾 更改角色(店长、财务、大堂经理、主厨、帮厨。。。)
交互设计:
1)首先展示列表页,页面中有多个按钮,每一行上面有更改和删除按钮,列表下方有增加按钮。
2)点击增加时,出现新的页面,页面需要填入名字和角色两个基本信息,填好提交返回列表页。
3)点击删除时,列表页更新。
4)点击更改时,出现新的编辑页面,名字不可改,角色可修改,修改提交后返回列表页。
系统设计:
1)实体类Guest name role
2)操作Model的方式GuestDao 初始化的数据、数据的增删改查处理
3)业务控制逻辑GuestController 接收请求,逻辑处理,返回相应的页面
4)逻辑处理GuestService去调用相应的GuestDao
接口设计
1) /guest/list 查询列表 无查询参数 返回结果:List
2)/guest/toAdd 点击增加按钮 返回add.html页面 需填写名字和角色 /guest/add 增加操作 传参为Guest 返回结果:跳转到list页面3)/guest/toUpdate 点击修改按钮 传参Guest name 返回update.html页面 名字固定 角色可改 /guest/update 修改操作 传参Guest 返回结果:跳转到list页面
4)/guest/delete 删除操作 传参Guest name 返回结果:跳转到list页面
list.html
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Title</title>
<link rel="stylesheet" th:href="@{/bootstrap.css}">
</head>
<body>
<h2>中餐厅嘉宾列表</h2><br>
<table class="table table-hover">
<thead>
<tr>
<th>名字</th>
<th>角色</th>
</tr>
</thead>
<tbody>
<tr th:each="guest:${guestList}">
<td th:text="${guest.name}">name</td>
<td th:text="${guest.role}">role</td>
<td>
<a th:href="@{/guest/toUpdate(name=${guest.name})}">修改角色</a>
</td>
<td>
<a th:href="@{/guest/delete(name=${guest.name})}">删除嘉宾</a>
</td>
</tr>
</tbody>
</table>
<div class="form-group">
<div class="col-sm-2 control-lable" >
<a href="/guest/toAdd" th:href="@{/guest/toAdd}"
class="btn btn-info">add</a>
</div>
</div>
</body>
</html>
update.html
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>修改嘉宾角色</title>
<link rel="stylesheet" th:href="@{/bootstrap.css}">
</head>
<body>
<form th:action="@{/guest/update}" th:object="${guest}" method="post">
名字:<input type="text" id="name" name="name"
th:value="*{name}" readonly>
角色:<input type="text" id="role" name="role"
th:value="*{role}">
<input type="submit" value="提交">
</form>
</body>
</html>
add.html
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>添加嘉宾</title>
<link rel="stylesheet" th:href="@{/bootstrap.css}">
</head>
<body>
<form th:action="@{/guest/add}" method="post">
嘉宾名字<input type="text" id="name" name="name">
嘉宾角色<input type="text" id="role" name="role">
<input type="submit" value="提交">
</form>
</body>
</html>
controller
package com.duing.controller;
import com.duing.bean.Guest;
import com.duing.service.GuestService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import java.util.List;
@Controller
public class GuestController {
@Autowired
private GuestService guestService;
@RequestMapping("/guest/list")
public String list(Model model){
List<Guest> guestList= guestService.list();
model.addAttribute("guestList",guestList);
return "list";
}
@RequestMapping("/guest/add")
public String add(String name,String role,Model model){
Guest guest=new Guest(name, role);
model.addAttribute("guest",guest);
guestService.add(guest);
return "redirect:/guest/list";
}
@RequestMapping("/guest/toAdd")
public String toAdd(){
return "add";
}
@RequestMapping("/guest/toUpdate")
public String toUpdate(Model model,String name){
Guest guest= guestService.get(name);
model.addAttribute("guest",guest);
return "update";
}
@RequestMapping("/guest/update")
public String update(Guest guest,Model model){
guestService.update(guest);
return "redirect:/guest/list";
}
@RequestMapping("/guest/delete")
public String delete(String name,Model model){
guestService.delete(name);
return "redirect:/guest/list";
}
}
service
package com.duing.service;
import com.duing.bean.Guest;
import com.duing.dao.GuestDao;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class GuestServiceImpl implements GuestService{
@Autowired
private GuestDao guestDao;
@Override
public List<Guest> list() {
return guestDao.list();
}
@Override
public void add(Guest guest) {
guestDao.add(guest);
}
@Override
public void update(Guest guest) {
guestDao.update(guest);
}
@Override
public void delete(String name) {
guestDao.delete(name);
}
@Override
public Guest get(String name) {
return guestDao.get(guestDao.getIndex(name));
}
}
dao
package com.duing.dao;
import com.duing.bean.Guest;
import org.springframework.stereotype.Repository;
import java.util.ArrayList;
import java.util.List;
@Repository
public class GuestDao {
static List<Guest> guestList = new ArrayList<>();
static {
guestList.add(new Guest("黄晓明","店长"));
guestList.add(new Guest("秦海璐","财务"));
guestList.add(new Guest("林述巍","总厨"));
guestList.add(new Guest("王俊凯","经理"));
guestList.add(new Guest("杨紫","前台"));
}
public List<Guest> list(){
return guestList;
}
public void add(Guest guest){
guestList.add(guest);
}
public int getIndex(String name){
for(int i=0;i< guestList.size();i++){
if (name.equals(guestList.get(i).getName())) {
return i;
}
}
return -1;
}
public Guest get(int i){
return guestList.get(i);
}
public void update(Guest guest){
guestList.get(getIndex(guest.getName())).setRole(guest.getRole());
}
public void delete(String name){
int i=getIndex(name);
guestList.remove(i);
}
}
RESTful API设计
一句话理解:看url就知道要什么,看http method就知道要做什么(增删改查),看http status code就知道哪里有问题
以上面中餐厅为例
传统API | RESTful API | |
---|---|---|
查询 | /guest/list |
/guest |
to添加 | /guest/toAdd |
/guest/toAdd |
添加 | /guest/add?guest={guest} |
/guest |
to编辑 | /guest/toUpdate?name={name} |
/guest/toUpdate/{name} |
编辑 | /guest/update?guest={guest} |
/guest |
删除 | /guest/delete?name={name} |
/guest/{name} |
编辑功能的更改有几点注意事项:
1)form表单原生只支持get和post方法,可以通过隐藏属性值,实现put以及delete的提交方式。
<input type="hidden" name="_method" value="put">
- /guest/toUpdate/{name}路径的属性接收和以往不同。
通过注解 @PathVariable(“name”)映射到方法的属性中,直译的意思就是 从路径中获取name的值
@GetMapping("/toUpdate/{name}")
public String toUpdate(Model model,@PathVariable("name") String name){
Guest guest = guestService.get(name);
model.addAttribute("guest",guest);
return "update";
}
删除功能的更改有几点注意事项:
1) 通过webjars引入jquery
pom.xml
<dependency>
<groupId>org.webjars</groupId>
<artifactId>jquery</artifactId>
<version>3.4.1</version>
</dependency>
list.html
<script type="text/javascript" th:src="@{/webjars/jquery/3.4.1/jquery.js}"></script>
- 如何通过delete的方法提交按钮? 借助form表单
<!--声明删除按钮-->
<button th:attr="del_url=@{/guest/}+${guest.name}" name="del_button">删除</button>
<!--声明删除按钮借助的表单-->
<form method="post" id="del_form">
<input type="hidden" name="_method" value="delete">
</form>
<!--增加按钮的点击监听,给表单的action赋值,然后提交-->
<script>
$(function () {
$("button[name='del_button']").click(function () {
$("#del_form").prop("action",$(this).attr("del_url")).submit();
});
});
</script>
相较于之前的代码,改变的部分
controller
package com.duing.controller;
import com.duing.bean.Guest;
import com.duing.service.GuestService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import java.util.List;
/**
* @RequestMapping("/guest")
* 放在类的上面,表示类里面的方法都是以 /guest 开头的
*/
@Controller
@RequestMapping("/guest")
public class GuestController {
@Autowired
private GuestService guestService;
//@RequestMapping(method = RequestMethod.GET)
//等价于下面的注解
@GetMapping
public String list(Model model){
List<Guest> guestList= guestService.list();
model.addAttribute("guestList",guestList);
return "list";
}
@PostMapping
public String add(String name,String role,Model model){
Guest guest=new Guest(name, role);
model.addAttribute("guest",guest);
guestService.add(guest);
return "redirect:/guest";
}
@GetMapping("/toAdd")
public String toAdd(){
return "add";
}
/**
* 将/guest/toUpdate/{name}格式的url映射到此方法
* 其中的name属性值通过注解@PathVariable映射到方法的属性中
*/
@GetMapping("/toUpdate/{name}")
public String toUpdate(Model model,@PathVariable("name") String name){
Guest guest= guestService.get(name);
model.addAttribute("guest",guest);
return "update";
}
@PutMapping
public String update(Guest guest,Model model){
guestService.update(guest);
return "redirect:/guest";
}
@DeleteMapping("/{name}")
public String delete(@PathVariable("name") String name,Model model){
guestService.delete(name);
return "redirect:/guest";
}
}
list.html
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Title</title>
<link rel="stylesheet" th:href="@{/bootstrap.css}">
<script type="text/javascript" th:src="@{/webjars/jquery/3.4.1/jquery.js}"></script>
</head>
<body>
<h2>中餐厅嘉宾列表</h2><br>
<table class="table table-hover">
<thead>
<tr>
<th>名字</th>
<th>角色</th>
</tr>
</thead>
<tbody>
<tr th:each="guest:${guestList}">
<td th:text="${guest.name}">name</td>
<td th:text="${guest.role}">role</td>
<td>
<a th:href="@{/guest/toUpdate/}+${guest.name}">修改角色</a>
</td>
<td>
<!-- <a th:href="@{/guest/delete(name=${guest.name})}">删除嘉宾</a>-->
<!--声明删除按钮-->
<button th:attr="del_url=@{/guest/}+${guest.name}" name="del_button">删除嘉宾</button>
</td>
</tr>
</tbody>
</table>
<div class="form-group">
<div class="col-sm-2 control-lable" >
<a href="/guest/toAdd" th:href="@{/guest/toAdd}"
class="btn btn-info">add</a>
</div>
</div>
<!--删除按钮借助的表单-->
<form method="post" id="del_form">
<input type="hidden" name="_method" value="delete">
</form>
<script>
$(function () {
$("button[name='del_button']").click(function () {
$("#del_form").prop("action",$(this).attr("del_url")).submit();
});
});
</script>
</body>
</html>
add.html
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>添加嘉宾</title>
<link rel="stylesheet" th:href="@{/bootstrap.css}">
</head>
<body>
<form th:action="@{/guest}" method="post">
嘉宾名字<input type="text" id="name" name="name">
嘉宾角色<input type="text" id="role" name="role">
<input type="submit" value="提交">
</form>
</body>
</html>
update.html
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>修改嘉宾角色</title>
<link rel="stylesheet" th:href="@{/bootstrap.css}">
</head>
<body>
<form th:action="@{/guest}" th:object="${guest}" method="post">
<!-- form表单只提供post和get,隐式传递method使之为put-->
<input type="hidden" name="_method" value="put">
名字:<input type="text" id="name" name="name"
th:value="*{name}" readonly>
角色:<input type="text" id="role" name="role"
th:value="*{role}">
<input type="submit" value="提交">
</form>
</body>
</html>