网站 建设 开发 协议/公司网站设计与制作
RESTful
1、RESTful简介
REST:Representational State Transfer,表现层资源状态转移。
a>资源
资源是一种看待服务器的方式,即,将服务器看作是由很多离散的资源组成。每个资源是服务器上一个可命名的抽象概念。因为资源是一个抽象的概念,所以它不仅仅能代表服务器文件系统中的一个文件、数据库中的一张表等等具体的东西,可以将资源设计的要多抽象有多抽象,只要想象力允许而且客户端应用开发者能够理解。与面向对象设计类似,资源是以名词为核心来组织的,首先关注的是名词。一个资源可以由一个或多个URI来标识。URI既是资源的名称,也是资源在Web上的地址。对某个资源感兴趣的客户端应用,可以通过资源的URI与其进行交互。
b>资源的表述
资源的表述是一段对于资源在某个特定时刻的状态的描述。可以在客户端-服务器端之间转移(交换)。资源的表述可以有多种格式,例如HTML/XML/JSON/纯文本/图片/视频/音频等等。资源的表述格式可以通过协商机制来确定。请求-响应方向的表述通常使用不同的格式。
c>状态转移
状态转移说的是:在客户端和服务器端之间转移(transfer)代表资源状态的表述。通过转移和操作资源的表述,来间接实现操作资源的目的。
2、RESTful的实现
具体说,就是 HTTP 协议里面,四个表示操作方式的动词:GET、POST、PUT、DELETE。
它们分别对应四种基本操作:GET 用来获取资源,POST 用来新建资源,PUT 用来更新资源,DELETE 用来删除资源。
REST 风格提倡 URL 地址使用统一的风格设计,从前到后各个单词使用斜杠分开,不使用问号键值对方式携带请求参数,而是将要发送给服务器的数据作为 URL 地址的一部分,以保证整体风格的一致性。
操作 | 传统方式 | REST风格 |
---|---|---|
查询操作 | getUserById?id=1 | user/1–>get请求方式 |
保存操作 | saveUser | user–>post请求方式 |
删除操作 | deleteUser?id=1 | user/1–>delete请求方式 |
更新操作 | updateUser | user–>put请求方式 |
3、HiddenHttpMethodFilter
由于浏览器只支持发送get和post方式的请求,那么该如何发送put和delete请求呢?
SpringMVC 提供了 HiddenHttpMethodFilter 帮助我们将 POST 请求转换为 DELETE 或 PUT 请求
HiddenHttpMethodFilter 处理put和delete请求的条件:
a>当前请求的请求方式必须为post
b>当前请求必须传输请求参数_method
满足以上条件,HiddenHttpMethodFilter 过滤器就会将当前请求的请求方式转换为请求参数_method的值,因此请求参数_method的值才是最终的请求方式
在web.xml中注册HiddenHttpMethodFilter
<filter><filter-name>HiddenHttpMethodFilter</filter-name><filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>
</filter>
<filter-mapping><filter-name>HiddenHttpMethodFilter</filter-name><url-pattern>/*</url-pattern>
</filter-mapping>
源码
if ("POST".equals(request.getMethod()) && request.getAttribute(WebUtils.ERROR_EXCEPTION_ATTRIBUTE) == null) {
//this.methodParam="_method"String paramValue = request.getParameter(this.methodParam); if (StringUtils.hasLength(paramValue)) { String method = paramValue.toUpperCase(Locale.ENGLISH); if (ALLOWED_METHODS.contains(method)) { requestToUse = new HttpMethodRequestWrapper(request, method); } }
} filterChain.doFilter(requestToUse, response);
后端
@RequestMapping(value = "/user" ,method = RequestMethod.PUT)
public String insertUser(User user){ System.out.println("修改用户"+user); return "success";
}
前端
注:
目前为止,SpringMVC中提供了两个过滤器:CharacterEncodingFilter和HiddenHttpMethodFilter
在web.xml中注册时,必须先注册CharacterEncodingFilter,再注册HiddenHttpMethodFilter
原因:
在 CharacterEncodingFilter 中通过 request.setCharacterEncoding(encoding) 方法设置字符集的
request.setCharacterEncoding(encoding) 方法要求前面不能有任何获取请求参数的操作
而 HiddenHttpMethodFilter 恰恰有一个获取请求方式的操作:
String paramValue = request.getParameter(this.methodParam);
RESTful案例
1、准备工作
和传统 CRUD 一样,实现对员工信息的增删改查。
-
搭建环境
-
准备实体类
package com.atguigu.mvc.bean;public class Employee {private Integer id;private String lastName;private String email;//1 male, 0 femaleprivate Integer gender;public Integer getId() {return id;}public void setId(Integer id) {this.id = id;}public String getLastName() {return lastName;}public void setLastName(String lastName) {this.lastName = lastName;}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;}public Employee(Integer id, String lastName, String email, Integer gender) {super();this.id = id;this.lastName = lastName;this.email = email;this.gender = gender;}public Employee() {} }
-
准备dao模拟数据
package com.atguigu.mvc.dao;import java.util.Collection; import java.util.HashMap; import java.util.Map;import com.atguigu.mvc.bean.Employee; import org.springframework.stereotype.Repository;@Repository public class EmployeeDao {private static Map<Integer, Employee> employees = null;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));}private static Integer initId = 1006;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);} }
2、功能清单
功能 | URL 地址 | 请求方式 |
---|---|---|
访问首页√ | / | GET |
查询全部数据√ | /employee | GET |
删除√ | /employee/2 | DELETE |
跳转到添加数据页面√ | /toAdd | GET |
执行保存√ | /employee | POST |
跳转到更新数据页面√ | /employee/2 | GET |
执行更新√ | /employee | PUT |
3、具体功能:访问首页
a>配置view-controller
<mvc:view-controller path="/" view-name="index"/>
b>创建页面
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head><meta charset="UTF-8" ><title>Title</title>
</head>
<body>
<h1>首页</h1>
<a th:href="@{/employee}">访问员工信息</a>
</body>
</html>
4、具体功能:查询所有员工数据
a>控制器方法
@RequestMapping(value = "/employee", method = RequestMethod.GET)
public String getEmployeeList(Model model){Collection<Employee> employeeList = employeeDao.getAll();model.addAttribute("employeeList", employeeList);return "employee_list";
}
b>创建employee_list.html
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head><meta charset="UTF-8"><title>Employee Info</title><script type="text/javascript" th:src="@{/static/js/vue.js}"></script>
</head>
<body><table border="1" cellpadding="0" cellspacing="0" style="text-align: center;" id="dataTable"><tr><th colspan="5">Employee Info</th></tr><tr><th>id</th><th>lastName</th><th>email</th><th>gender</th><th>options(<a th:href="@{/toAdd}">add</a>)</th></tr><tr th:each="employee : ${employeeList}"><td th:text="${employee.id}"></td><td th:text="${employee.lastName}"></td><td th:text="${employee.email}"></td><td th:text="${employee.gender}"></td><td><a class="deleteA" @click="deleteEmployee" th:href="@{'/employee/'+${employee.id}}">delete</a><a th:href="@{'/employee/'+${employee.id}}">update</a></td></tr></table>
</body>
</html>
5、具体功能:删除
a>创建处理delete请求方式的表单
<!-- 作用:通过超链接控制表单的提交,将post请求转换为delete请求 -->
<form id="delete_form" method="post"><!-- HiddenHttpMethodFilter要求:必须传输_method请求参数,并且值为最终的请求方式 --><input type="hidden" name="_method" value="delete"/>
</form>
b>删除超链接绑定点击事件
引入vue.js
<script type="text/javascript" th:src="@{/static/js/vue.js}"></script>
删除超链接
<a class="deleteA" @click="deleteEmployee" th:href="@{'/employee/'+${employee.id}}">delete</a>
通过vue处理点击事件
<script type="text/javascript">var vue = new Vue({el:"#dataTable",methods:{//event表示当前事件deleteEmployee:function (event) {//通过id获取表单标签var delete_form = document.getElementById("delete_form");//将触发事件的超链接的href属性为表单的action属性赋值delete_form.action = event.target.href;//提交表单delete_form.submit();//阻止超链接的默认跳转行为event.preventDefault();}}});
</script>
c>控制器方法
@RequestMapping(value = "/employee/{id}", method = RequestMethod.DELETE)
public String deleteEmployee(@PathVariable("id") Integer id){employeeDao.delete(id);return "redirect:/employee";
}
6、具体功能:跳转到添加数据页面
a>配置view-controller
<mvc:view-controller path="/toAdd" view-name="employee_add"></mvc:view-controller>
b>创建employee_add.html
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head><meta charset="UTF-8"><title>Add Employee</title>
</head>
<body><form th:action="@{/employee}" method="post">lastName:<input type="text" name="lastName"><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="add"><br>
</form></body>
</html>
7、具体功能:执行保存
a>控制器方法
@RequestMapping(value = "/employee", method = RequestMethod.POST)
public String addEmployee(Employee employee){employeeDao.save(employee);return "redirect:/employee";
}
8、具体功能:跳转到更新数据页面
a>修改超链接
<a th:href="@{'/employee/'+${employee.id}}">update</a>
b>控制器方法
@RequestMapping(value = "/employee/{id}", method = RequestMethod.GET)
public String getEmployeeById(@PathVariable("id") Integer id, Model model){Employee employee = employeeDao.get(id);model.addAttribute("employee", employee);return "employee_update";
}
c>创建employee_update.html
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head><meta charset="UTF-8"><title>Update Employee</title>
</head>
<body><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="lastName" th:value="${employee.lastName}"><br>email:<input type="text" name="email" th:value="${employee.email}"><br><!--th:field="${employee.gender}"可用于单选框或复选框的回显若单选框的value和employee.gender的值一致,则添加checked="checked"属性-->gender:<input type="radio" name="gender" value="1" th:field="${employee.gender}">male<input type="radio" name="gender" value="0" th:field="${employee.gender}">female<br><input type="submit" value="update"><br>
</form></body>
</html>
9、具体功能:执行更新
a>控制器方法
@RequestMapping(value = "/employee", method = RequestMethod.PUT)
public String updateEmployee(Employee employee){employeeDao.save(employee);return "redirect:/employee";
}
相关文章:

【springmvc】Rest ful风格
RESTful 1、RESTful简介 REST:Representational State Transfer,表现层资源状态转移。 a>资源 资源是一种看待服务器的方式,即,将服务器看作是由很多离散的资源组成。每个资源是服务器上一个可命名的抽象概念。因为资源是一…...

华为OD机试真题Python实现【用户调度】真题+解题思路+代码(20222023)
用户调度 题目 在通信系统中有一个常见的问题是对用户进行不同策略的调度,会得到不同系统消耗的性能。 假设由N个待串行用户,每个用户可以使用A/B/C三种不同的调度策略。 不同的策略会消耗不同的系统资源,请你根据如下规则进行用户调度,并返回总的消耗资源数。 规则是: …...

JavaSE学习笔记总结day19
今日内容 二、线程安全的集合 三、死锁 四、线程通信 五、生产者消费者 六、线程池 零、 复习昨日 创建线程的几种方式 1) 继承 2) 实现Runnable 3) callable接口 Future接口 4) 线程池 启动线程的方法 start() 线程的几种状态 什么是线程不安全 setName getName Thread.curr…...

FreeSql使用
目的: 1.方库分表 2.主从分离 3.分布式事务 过程: 官网:指南 | FreeSql 官方文档 1.Startup.cs 添加配置(本地数据库MySql) ConfigureServices: Func<IServiceProvider, IFreeSql> fsql r >{IFreeSql …...

Hadoop集群搭建,基于3.3.4hadoop和centos8【图文教程-从零开始搭建Hadoop集群】,常见问题解决
Hadoop集群搭建,基于3.3.4hadoop和centos8【小白图文教程-从零开始搭建Hadoop集群】,常见问题解决Hadoop集群搭建,基于3.3.4hadoop1.虚拟机的创建1.1 第一台虚拟机的创建1.2 第一台虚拟机的安装1.3 第一台虚拟机的网络配置1.3.1 主机名和IP映…...

UE4 材质学习 (焚烧材质)
效果步骤随便从网上下载一张图片(地址:链接/链接),导入UE中新建一个材质函数这里命名为“E_Function”双击打开该材质函数,由于需要输出变发光和变透明两种效果,因此这里需要两个输出节点:分别命…...

【c++】STL常用算法2—常用查找算法
文章目录常用查找算法findfind_ifadjacent_findbinary_searchcountcount_if常用查找算法 算法简介: find//查找元素 find_if//按条件查找元素 adjacent_find//查找相邻重复元素 binary_search//二分查找法 count//统计元素个数 count_if//按条件统计元素个数find …...

史上最全最详细的Java架构师成长路径图,程序员必备
从新手码农到高级架构师,要经过几步?要多努力,才能成为为人倚重的技术专家?本文将为你带来一张程序员发展路径图,但你需要知道的是,天下没有普适的道理,具体问题还需具体分析,实践才…...

第五章 事务管理
1.事务概念 *什么是事务:事务是数据库操作最基本单元,逻辑上是一组操作,要么都成功,要么都失败 *事务的特性(ACID):原子性、隔离性、一致性、持久性 2.搭建事务操作环境 *模拟场景ÿ…...

Redis:主从同步
Redis:主从同步一. 概述二. 原理(1) 全量同步(2) 增量同步(3) 优化Redis主从集群三. 总结一. 概述 引入: Redis主从集群采用一个Master负责写,多个Slave负责读的方式(读多写少),那么如何让读取数据时多个从…...

Unity Animator.Play(stateName, layer, normalizedTime) 播放动画函数用法
原理 接口: public void Play(string stateName, int layer -1, float normalizedTime float.NegativeInfinity);参数含义stateName动画状态机的某个状态名字layer第几层的动画状态机,-1 表示播放第一个状态或者第一个哈希到的状态normalizedTime从s…...

python学习——【第三弹】
前言 上一篇文章 python学习——【第二弹】中学习了python中的运算符内容,这篇文章接着学习python中的流程控制语句。 流程控制指的是代码运行逻辑、分支走向、循环控制,是真正体现我们程序执行顺序的操作。流程控制一般分为顺序执行、条件判断和循环控…...

科技云报道:AI大模型背后,竟是惊人的碳排放
科技云报道原创。 自从ChatGPT这样的大型语言模型在全球引起轰动以来,很少有人注意到,训练和运行大型语言模型正在产生惊人的碳排放量。 虽然OpenAI和谷歌都没有说过他们各自产品的计算成本是多少,但据第三方研究人员分析,ChatG…...

如何根据实际需求选择合适的三维实景建模方式?
随着实景三维中国建设的推进,对三维实景建模的数字化需求大幅增加。由于三维实景建模具有采集速度快、计算精度高等建模优势,引起了各个行业的高度关注。三维实景建模是一种应用数码相机或者激光扫描仪对现有场景进行多角度环视拍摄,然后利用…...

CENTO OS上的网络安全工具(十八)ClickHouse及编程环境部署
这篇其实去年就写好了,孰知就在12月31日那一天打进决赛圈,一躺,二过年,三休假,四加班,居然到了三个月以后,才有机会将它发出来…… 一年也就四个季度不是,实在是光阴荏苒,…...

Java中class文件的格式
常见的class文件格式如下图所示,下面我将对一下格式一一作出解释。 一、magic 该部分主要是对语言类型的规范,只有magic这个部分是CAFEBABE时才能被检测为Java语言,否则则不是。 二、minor version和major version minor version主要表示了…...

C++排序算法
排序算法复习 冒泡排序 链接:https://www.runoob.com/w3cnote/bubble-sort.html 每次循环对比【相邻】两个元素,将最大的元素放到数组最后 void bubbleSort(int* arr, int n){//每次确认一个元素的最终位置,循环n-1次即可确认全部元素的最…...

JAVA后端部署项目三步走
1. JAVA部署项目三步走 1.1 查看 运行的端口 lsof -i:8804 (8804 为端口) 发现端口25111被监听 1.2 杀死进程,终止程序 pid 为进程号 kill -9 pid 1.3 后台运行jar包 nohup java -jar -Xms128M -Xmx256M -XX:MetaspaceSize128M -XX:MaxM…...

php使用zookeeper实现分布式锁
介绍 一、zookeeper和redis实现分布式锁的对比 1、redis 分布式场景应用比较广泛,redis分布式锁,其实需要自己不断去尝试获取锁,比较消耗性能;zk分布式锁,获取不到锁,注册个监听器即可,不需要不…...

力扣-可回收且低脂的产品
大家好,我是空空star,本篇带大家了解一道超级超级超级简单的力扣sql练习题。 文章目录前言一、题目:1757. 可回收且低脂的产品二、解题1.正确示范①提交SQL运行结果2.正确示范②提交SQL运行结果3.正确示范③提交SQL运行结果4.正确示范④提交S…...

代码随想录刷题-数组-二分查找
文章目录写在前面原理习题题目1思路和代码题目-2写在前面 这个专栏是记录我刷代码随想录过程中的随想和总结。每一小节都是根据自己的理解撰写的,文章比较短,主要是为了记录和督促自己。刷完一章后,我会再单独整理一篇文章来总结和分享。 本…...

HCIA复习1
HCIA复习 抽象语言---->编码 编码---->二进制 二进制--->电信号 处理电信号 OSI参考模型----OSI/RM 应用层 表示层 会话层 传输层 端口号:0-65535;1-1023是注明端口 网络层 IP地址 数据链路层 物理层 ARP协议 正向ARP---通过IP地址获取目的MAC地…...

Kotlin中的destructuring解构声明
开发中有时只是想分解一个包含多个字段的对象来初始化几个单独的变量。要实现这一点,可以使用Kotlin的解构声明。本文主要了解:“1、如何使用解构声明这种特性 2、底层是如何实现的 3、如何在你自己的类中实现它1、解构声明的使用解构声明&a…...

Kubernetes Pod 水平自动伸缩(HPA)
Pod 自动扩缩容 之前提到过通过手工执行kubectl scale命令和在Dashboard上操作可以实现Pod的扩缩容,但是这样毕竟需要每次去手工操作一次,而且指不定什么时候业务请求量就很大了,所以如果不能做到自动化的去扩缩容的话,这也是一个…...

钉钉、企业微信和飞书向“钱”看
在急剧变革的时候,不管黑猫白猫,要抓到老鼠才算好猫。如今,各互联网企业早已进入降本增效的新阶段。勒紧裤腰带过日子之下,能不能盈利、商业化空间有多大,就成为各个业务极为重要的考核指标。在各业务板块中࿰…...

网上购物网站的设计
技术:Java、JSP等摘要:本文介绍了JSP和JAVA等相关技术,针对网上购物系统的实际需求,设计开发了一个基于JSP的小型电子商务网站也就是网上购物系统,。在设计开发中,采用的是SSH框架(strutsspring…...

【Java学习笔记】8.Java 运算符
Java 运算符 计算机的最基本用途之一就是执行数学运算,作为一门计算机语言,Java也提供了一套丰富的运算符来操纵变量。我们可以把运算符分成以下几组: 算术运算符关系运算符位运算符逻辑运算符赋值运算符其他运算符 算术运算符 算术运算符…...

RHCSA-使用命令管理文件(3.6)
硬链接与软链接基本操作: 创建软硬连接的命令:ln 硬链接:ln 源文件(已经存在的文件) 链接文件名(新建) 软连接:ln -s 源文件(已存在的文件) 快捷方式文件名…...

socket聊天室--socket的建立
socket聊天室–socket实现 文章目录 socket聊天室--socket实现socket()bind()listen()accept()connect()发送接收read()函数recv()函数write()函数send()函数close()关闭套接字IP 地址格式转换函数socket() #include <sys/types...

Raft图文详解
Raft图文详解 refer to: Raft lecture (Raft user study) - YouTube Raft PDF Raft算法详解 - 知乎 (zhihu.com) 今天来详细介绍一下Raft协议 Raft是来解决公式问题的协议,那么什么是共识呢? 在分布式系统里面,consensus指的是多个节点对…...