文章目录
一、简介
REST:Representational State Transfer,表现层资源状态转移。
- a 资源:资源是一种看待服务器的方式。将服务器看作是有很多的离散的资源组成。每个资源是服务器上一个可命名的抽象概念。因为资源是一个抽象的概念,所以它不仅仅能代表服务器文件系统中的一个文件、数据库中的一张表等等具体的东西,还能代表想象力允许且开发者能够理解的东西。与面向对向设计类似,资源是以名词为核心来组织的,首相关注的是名词,一个资源可以由一个或多个URI来标识。URI既是资源名称,也是资源在Web上的地址。对某个资源感兴趣的客户端应用,通过URI与其交互。
- 资源的表述:是一段对于资源在某个特定时期的状态的描述,可以在客户端-服务端之间转移(交换)。资源的表述可以有多种格式。常用的有HTML、XML、JSON、TXT、PNG等格式。资源的表述格式可以通过协商机制来确定。请求·相应方向的表述通常使用不同格式。
- 状态转移:在客户端与服务器端之间转移,代表资源状态的表述。通过转移和操作资源的表述,来间接实现操作资源的目的。
二、实现
通过HTTP中的GET、POST、PUT、DELETE对应获取、新建、更新与删除操作。
通过 ‘/’ 完成请求,不再使用 **‘?’**传参。
操作 | 原来 | 现在 |
---|---|---|
查询 | queryUserById?id=1 | user/1(get 请求方式) |
保存 | saveUser | user(post 请求方式) |
删除 | deleteUserById?id=1 | user/1(delete 请求方式) |
更新 | updateUserById?id=1 | user/1(put 请求方式) |
模拟GET与POST请求
<!DOCTYPE HTML>
<html lang="en" xmlns:th="http://ww.thymeleaf.org">
<head>
<meta charset="utf-8">
<title>index</title>
</head>
<body>
<a th:href="@{/user}">查询用户信息</a>
<a th:href="@{/user/1}">根据id查询用户信息</a>
<form th:action="@{/user}" method = "post">
用户名:<input type="text" name="username"><br/>
密码:<input type="password" name="password"><br/>
<input type="submit" value="添加用户"/><br/>
</form>
</body>
</html>
package boot.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
@Controller
public class UserController {
@RequestMapping(value = "/user",method = RequestMethod.GET)
public String getAllUser(){
System.out.println("查询用户所有信息");
return "success";
}
@RequestMapping(value = "/user/{id}",method = RequestMethod.GET)
public String getUserById(@PathVariable("id") int id){
System.out.println("查询用户"+ id + "的信息");
return "success";
}
@RequestMapping(value="/user",method = RequestMethod.POST)
public String insertUser(String username,String password) {
int id = (int) (Math.random()*1000);
System.out.println("添加用户"+ id + ",姓名:"+ username +",密码:"+ password);
return "success";
}
}
模拟PUT与DELETE请求
添加过滤器
在SpringBoot配置文件中,添加使用过滤器。
spring.mvc.hiddenmethod.filter.enabled=true
在WebConfiguration中添加http请求过滤器
package boot.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.filter.HiddenHttpMethodFilter;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;
@Configuration
//WebMvcConfigurationSupport springMVC支持的配置
public class WebConfig extends WebMvcConfigurationSupport {
//http请求过滤器,它在传入参数中,将名为"_method"的参数取出(若有),并将其值作为请求方式
@Bean
public HiddenHttpMethodFilter hiddenHttpMethodFilter() {
return new HiddenHttpMethodFilter();
}
}
<!DOCTYPE HTML>
<html lang="en" xmlns:th="http://ww.thymeleaf.org">
<head>
<meta charset="utf-8">
<title>index</title>
</head>
<body>
<form th:action="@{/user/1}" method = "post">
用户名:<input type="text" name="username"><br/>
密码:<input type="password" name="password"><br/>
<input type="hidden" name="_method" value="put"/>
<input type="submit" value="更新用户信息"/><br/>
</form>
<form th:action="@{/user/1}" method = "post">
<input type="hidden" name="_method" value="delete"/>
<input type="submit" value="删除用户信息"/><br/>
</form>
</body>
</html>
package boot.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.context.annotation.Scope;
@Scope("singleton")
@Controller
public class UserController {
@RequestMapping(value="/user/{id}",method = RequestMethod.PUT)
public String UpdateUser(@PathVariable("id") int id ,String username,String password) {
System.out.println("更新用户"+ id + ",姓名:"+ username +",密码:"+ password);
return "success";
}
@RequestMapping(value="/user/{id}",method = RequestMethod.DELETE)
public String DeleteUser(@PathVariable("id") int id) {
System.out.println("删除用户"+ id);
return "success";
}
}
三、基础实践
(工程基配置略)
主页
<!DOCTYPE html>
<html lang="en" xmlns:th="http:/www.thymeleaf.org">
<head>
<meta charset="UTF-8"/>
<title>首页</title>
</head>
<body>
<h1>首页</h1>
<a th:href="@{/employee}">查看所有员工</a>
</body>
</html>
主页跳转设置
package com.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
public class indexController {
@RequestMapping("/")
public String LocateIndexPage() {
return "index";
}
}
员工类
创建实体包Entity
其中创建一个员工类
package com.entity;
public class Employee {
private Integer id;
private String last_name;
private String email;
//0:male,1:female
private Integer gender;
/***********Structure****************/
public Employee() {
}
public Employee(Integer id,String last_name,String email,Integer gender) {
this.id = id;
this.last_name = last_name;
this.email = email;
this.gender = gender;
}
/**********method****************/
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getLast_name() {
return last_name;
}
public void setLast_name(String last_name) {
this.last_name = last_name;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public Integer getGender() {
return gender;
}
public void setGender(Integer gender) {
this.gender = gender;
}
}
员工数据
创建一个包Dao
创建一个类EmployeeDao
我们不连接数据库,因此,我们直接赋值。
package com.dao;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import org.springframework.stereotype.Repository;
import com.entity.Employee;
@Repository
public class EmployeeDao {
private static Map<Integer,Employee> employees = null;//存储所有employee数据
private static Integer initId = 1006;//id号
static {
/*
* 设置初始数据
*/
employees = new HashMap<Integer,Employee>();
employees.put(1001, new Employee(1001,"E-AA","aa@163.com",1));
employees.put(1002, new Employee(1002,"E-BB","bb@163.com",1));
employees.put(1003, new Employee(1003,"E-CC","cc@163.com",0));
employees.put(1004, new Employee(1004,"E-DD","dd@163.com",0));
employees.put(1005, new Employee(1005,"E-EE","ee@163.com",1));
}
/*
* 设置基础方法
*/
public void save(Employee employee) {
if(employee.getId() == null) {
employee.setId(initId++);
}
employees.put(employee.getId(),employee);
}
public Collection<Employee> getAll(){
return employees.values();
}
public Employee get(Integer id) {
return employees.get(id);
}
public void delete(Integer id) {
employees.remove(id);
}
}
所有员工详情页面
<!DOCTYPE html>
<html lang="en" xmlns:th="http:/www.thymeleaf.org">
<head>
<meta charset="UTF-8"/>
<title>员工信息</title>
</head>
<body>
<!-- 引入vue.js(没有可以到vue官网下载一个) ,vue.js放在static下,方便访问-->
<!-- 一般而言,只需要<script type="text/javascript" src="/js/vue.js"> 就可以实现静态资源访问,但有时会无法访问。因此我们用一下方法+设置WebConfig方式-->
<script type="text/javascript" th:src="@{/static/js/vue.js}"></script>
<table id="dataTable" align="center" border="1" cellpadding="2" style="text-align:center">
<tr>
<th colspan="5">Employee Info</th>
</tr>
<tr>
<th>id</th>
<th>lastName</th>
<th>email</th>
<th>gender</th>
<th>options</th>
</tr>
<tr th:each="employee: ${employeeList}">
<td th:text="${employee.id}"></td>
<td th:text="${employee.last_name}"></td>
<td th:text="${employee.email}"></td>
<td th:text="${employee.gender == 0? '男':'女'}"></td>
<td>
<!--方式1
<a th:href="@{'/employee/' + ${employee.id}}">delete</a>
-->
<!--方式2-->
<a @click="deleteEmployee" th:href="@{/employee/}+${employee.id}">delete</a><b>|</b><a th:href="@{/employee/}+${employee.id}">update</a>
</td>
</tr>
</table>
<script type="text/javascript">
var vue = new Vue({
el:"#dataTable",
methods:{
deleteEmployee:function(event){
var deleteForm = document.getElementById("deleteForm");
//设置action为href中地址(thymeleaf解析会先执行)
deleteForm.action = event.target.attributes[0].nodeValue;
//提交
deleteForm.submit();
//取消超链接的默认行为
event.preventDefault();
}
}
})
</script>
<form id = "deleteForm" method="post">
<input type="hidden" name="_method" value="delete"/>
</form>
</body>
</html>
设置过滤器与添加静态资源路径
如果静态资源无法加载,试着手动载WebConfig中添加。
package com.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.filter.HiddenHttpMethodFilter;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;
@Configuration
public class WebConfig extends WebMvcConfigurationSupport {
//添加静态资源路径
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/static/**").addResourceLocations("classpath:/static/");
}
//http请求过滤器,使得可以让Put与Delete请求可识别
@Bean
public HiddenHttpMethodFilter hiddenHttpMethodFilter() {
return new HiddenHttpMethodFilter();
}
}
添加员工页面
<!DOCTYPE html>
<html lang="en" xmlns:th="http:/www.thymeleaf.org">
<head>
<meta charset="UTF-8"/>
<title>首页</title>
</head>
<body>
<h1>首页</h1>
<form th:action="@{/employee}" method="post">
lastName:<input type="text" name="last_name"/><br/>
email:<input type="text" name="email"/><br/>
gender:<input type="radio" name="gender" value="1"/>male
<input type="radio" name="gender" value="0"/>female<br/>
<input type="submit" value="提交"/><br/>
</form>
</body>
</html>
更新员工数据页面
<!DOCTYPE html>
<html lang="en" xmlns:th="http:/www.thymeleaf.org">
<head>
<meta charset="UTF-8"/>
<title>首页</title>
</head>
<body>
<h1>首页</h1>
<form th:action="@{/employee}" method="post">
<input type="hidden" name="_method" value="put"/>
<input type="hidden" name="id" th:value="${employee.id}"/>
lastName:<input type="text" name="last_name" th:value="${employee.last_name}"/><br/>
email:<input type="text" name="email" th:value="${employee.email}"/><br/>
gender:<input type="radio" name="gender" value="0" th:field="${employee.gender}"/>male
<input type="radio" name="gender" value="1" th:field="${employee.gender}"/>female<br/>
<input type="submit" value="提交"/><br/>
</form>
</body>
</html>
控制层
package com.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
import com.dao.EmployeeDao;
import com.entity.Employee;
@Controller
public class EmployeeController {
@Autowired
private EmployeeDao employeeDao;
@GetMapping("/employee")
public ModelAndView QueryAllEmployee() {
ModelAndView mav = new ModelAndView();
mav.addObject("employeeList",employeeDao.getAll());
mav.setViewName("employee_list");
return mav;
}
@DeleteMapping("/employee/{id}")
public String deleteEmployeeById(@PathVariable("id") Integer id) {
employeeDao.delete(id);
//重定向防止重复提交请求
return "redirect:/employee";
}
@PostMapping("/employee")
public String saveEmployee(Employee employee) {
employeeDao.save(employee);
return "redirect:/employee";
}
@GetMapping("/employee/{id}")
public ModelAndView QueryEmployeeById(@PathVariable("id")Integer id) {
ModelAndView mav = new ModelAndView();
mav.addObject("employee",employeeDao.get(id));
mav.setViewName("employee_update");
return mav;
}
@PutMapping("/employee")
public String updateEmployee(Employee employee) {
employeeDao.save(employee);
return "redirect:/employee";
}
@RequestMapping("/toAdd")
public String toAddPage() {
return "employee_add";
}
}