RESTful

news/2024/11/8 20:01:19/

RESTful

什么是RESTful?

REST:Representational State Transfer,表现层资源状态转移

RESTFUL是一种网络应用程序的设计风格和开发方式,基于HTTP,可以使用XML格式定义或JSON格式定义。RESTFUL适用于移动互联网厂商作为业务使能接口的场景,实现第三方OTT调用移动网络资源的功能,动作类型为新增、变更、删除所调用资源。本质:是一种软件架构风格核心:面向资源设置api

RESTFUL特点包括:

1、每一个URI代表1种资源;

2、客户端使用GET、POST、PUT、DELETE4个表示操作方式的动词对服务端资源进行操作:GET用来获取资源,POST用来新建资源(也可以用于更新资源),PUT用来更新资源,DELETE用来删除资源;

3、通过操作资源的表现形式来操作资源;

4、资源的表现形式是XML或者HTML;

5、客户端与服务端之间的交互在请求之间是无状态的,从客户端到服务端的每个请求都必须包含理解请求所必需的信息。

为什么要使用Restful?

解决问题:降低开发的复杂性;提高系统的可伸缩性

Restful与其他架构有什么区别?

soap webserver 是一种跨编程语言,跨操作平台的远程调用技术。通过http协议发送请求和接收结果时采用xml格式封装,并增加了一些特定的http消息头,这些特定的http消息头和xml内容格式就是soap协议

这俩个架构的区别在:1、效率2、易用性3、安全性

效率和易用性:

soap案例:由于soap添加的是特定的http消息头,如果业务提供方(微信)不提供文档…没有人会使用它的api

安全性:

Restful适用于效率要求很高,但安全性要求不高的场景

soap的成熟性对于安全性要求较高的接口设计带来便利

资源

资源是一种看待服务器的方式,将服务器看做很多离散的资源组成。每个资源是服务器上一个可命名的抽象概念。因为资源是一个抽象的概念, 所以它不仅仅能代表服务器文件系统的一个文件、数据库中的一张表等具体的东西,也可以将资源看为一种抽象的概念,例如一个资源可以由一个或者多个URI来表示,URI是资源的名称,也是在其Web服务器上的地址。

统一资源标识符(Uniform Resource Identifier,URI)

资源的表述

资源的表述是一段对于资源在某个时刻的状态的描述。可以在客户端-服务器之间转移。资源的表述可以有多种格式,例如HTML、XML、JSON、纯文本、图片、视频、音频等。资源的表述格式可以通过协商机制来确定。

请求-响应方向的表述通常使用不同的格式。

状态转移

状态转移的意思是,在客户端和服务器端之间转移代表资源状态的表述。通过转移和操作资源的表述来间接实现操作资源的目的。

RESTful的实现

RESTful的实现主,主要是GET、POST、PUT、DELTE四种访问方式

浏览器只能发送GET和POST两种请求方式

若直接在form表单中设置method=“put”,此时method失效,默认变为Get请求。

如何实现PUT、DELETE的请求方式?

设置控制器方法

package com.lobo.controller;import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;/**
* className: TestRestController<br/>
* author: MacieSerenity <br/>
* date: 2022/8/21-9:45
**/
@Controller
public class TestRestController {/*** 查询所有用户的信息:/user -> get* 根据用户id查询用户信息:/user/{id} -> get* 添加用户信息:/user ->post* 修改用户的信息:/user -> put* 删除用户的信息:/user/{id} -> delete*//*** 查询所有用户的信息:/user -> get* @return 视图*/
//    @RequestMapping(value = "/user",method = RequestMethod.GET)@GetMapping("/user")public String getAllUser(){System.out.printf("查询所有用户的信息:/user -> get");return "success";}/*** 根据用户id查询用户信息:/user/{id} -> get* @param id 用户ID* @return 视图*/
//    @RequestMapping(value = "/user/{id}",method = RequestMethod.GET)@GetMapping("/user/{id}")public String getUserById(@PathVariable("id")Integer id){System.out.println("根据用户id查询用户信息:/user/{"+id+"} -> get");return "success";}/*** 添加用户信息:/user ->post* @return 视图*/
//    @RequestMapping(value = "/user",method = RequestMethod.POST)@PostMapping("/user")public String addUser(){System.out.println("添加用户信息:/user ->post");return "success";}/*** 修改用户的信息:/user -> put* @return 视图*/
//    @RequestMapping(value = "/user",method = RequestMethod.PUT)@PutMapping("/user")public String modifyUser(){System.out.println("修改用户的信息:/user -> put");return "success";}/*** 删除用户的信息:/user/{id} -> delete* @return 视图*/
//    @RequestMapping(value = "/user/{id}",method = RequestMethod.DELETE)@DeleteMapping("/user/{id}")public String deletedUser(@PathVariable("id") Integer id){System.out.println("删除用户的信息:/user/{"+id+"} -> delete");return "success";}}

设置过滤器

注意Spring的编码过滤器应该在最上方(按照从上到下的顺序),然后再是处理请求方式的方式

若想实现PUT的请求方式,则需要满足以下几个条件:

1、需要在web.xml中配置好编码过滤器

2、当前请求必须为POST

3、设置隐藏域,参数name=“_method” value=“put”

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"version="4.0">
<!--    编码过滤器--><filter><filter-name>CharacterEncodingFilter</filter-name><filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class><init-param><param-name>encoding</param-name><param-value>UTF-8</param-value></init-param><init-param><param-name>forceEncoding</param-name><param-value>true</param-value></init-param></filter><filter-mapping><filter-name>CharacterEncodingFilter</filter-name><url-pattern>/*</url-pattern></filter-mapping><!--    设置处理请求方式的过滤器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><!--    Spring的Servlet控制器--><servlet><servlet-name>SpringMVC</servlet-name><servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class><init-param><param-name>contextConfigLocation</param-name><param-value>classpath:springmvc.xml</param-value></init-param><!--        将前端控制器的初始化时间提前到项目启动时--><load-on-startup>1</load-on-startup></servlet><servlet-mapping><servlet-name>SpringMVC</servlet-name><url-pattern>/</url-pattern></servlet-mapping></web-app>

HTML页面的请求方式

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head><meta charset="UTF-8"><title>首页</title>
</head>
<body><h1>Index页面</h1><hr>/**<br>* 查询所有用户的信息:/user -> get<br>* 根据用户id查询用户信息:/user/{id} -> get<br>* 添加用户信息:/user ->post<br>* 修改用户的信息:/user -> put<br>* 删除用户的信息:/user/{id} -> delete<br>*/<br><hr><a th:href="@{/user}">查询所有用户的信息</a><br><a th:href="@{/user/1}">查询用户id为1的信息</a><br><form th:action="@{/user}" method="post"><input type="submit" value="添加用户信息"></form><br>/**<br>* 注意:想要发送PUT请求,则返回的请求方式必须是POST方式<br>* 且需要在当前的请求域中设置一个请求参数_method且value=put<br>*/<br><form th:action="@{/user}" method="post"><input type="hidden" name="_method" value="put"><input type="submit" value="修改用户信息"></form><br>/** <br>使用DELETE请求方式,根据用户ID删除 <br>*/ <br><form th:action="@{/user/1}" method="post"><input type="hidden" name="_method" value="delete"><input type="submit" value="删除用户信息"></form><br>
</body>
</html>

点击【修改用户信息】按钮之后,查看后台使用的方法:
请添加图片描述

请添加图片描述

可以看到,通过隐藏域的参数,成功访问了put和delete的请求方式

案例

初始化实体类Employee

package com.lobo.entity;
@Data
@NoArgsConstructor
@AllArgsConstructor
@ToString
public class Employee {private Integer id;private String lastName;private String email;//性别,1表示男,0表示女private Integer gender;
}

模拟数据Dao层

package com.lobo.dao;
import com.lobo.entity.Employee;
//要记得加注解:
@Repository
public class EmployeeDao {private static Map<Integer, Employee>employeeMap = null;static {employeeMap=new HashMap<>();employeeMap.put(1001,new Employee(1001,"E-AA","aa@163.com",1));employeeMap.put(1002,new Employee(1002,"E-BB","bb@163.com",1));employeeMap.put(1003,new Employee(1003,"E-CC","cc@163.com",0));employeeMap.put(1004,new Employee(1004,"E-DD","dd@163.com",0));employeeMap.put(1005,new Employee(1005,"E-EE","ee@163.com",1));}public static Integer initId=1006;public void save(Employee employee){if (employee.getId()==null){employee.setId(initId++);}employeeMap.put(employee.getId(), employee);}public Collection<Employee> getAll(){return employeeMap.values();}public Employee get(Integer id){return employeeMap.get(id);}public void delete(Integer id){employeeMap.remove(id);}
}

功能清单

功能URL地址请求方式
访问首页/GET
查询全部数据/employeeGET
删除/employee/{id}DELETE
跳转到添加数据界面/toAddGET
执行保存/employeePOST
跳转到更新数据界面/employee/{id}GET
执行更新/employeePUT

功能实现

1、访问首页

spring配置文件中:

<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:context="http://www.springframework.org/schema/context"xmlns:mvc="http://www.springframework.org/schema/mvc"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsdhttp://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd  "><!--    扫描控制层组件--><context:component-scan base-package="com.lobo"/><!--    配置Thymeleaf视图解析器--><bean id="viewResolver" class="org.thymeleaf.spring5.view.ThymeleafViewResolver"><property name="order" value="1"/><property name="characterEncoding" value="utf-8"/><property name="templateEngine"><bean class="org.thymeleaf.spring5.SpringTemplateEngine"><property name="templateResolver"><bean class="org.thymeleaf.spring5.templateresolver.SpringResourceTemplateResolver"><!--                        视图前缀--><property name="prefix" value="/WEB-INF/templates/"/><!--                        视图后缀--><property name="suffix" value=".html"/><property name="templateMode" value="HTML"/><property name="characterEncoding" value="UTF-8"/></bean></property></bean></property></bean><!--    开启注解驱动--><mvc:annotation-driven/>
<!--    开启试图控制器--><mvc:view-controller path="/" view-name="index" /></beans>

EmployeeController

 @GetMapping("/")public String toIndex(){return "index";}

访问首页我们可以通过配置xml文件中的<mvc:view-controller path=“/” view-name=“index” />来进行配置,也可以通过使用Mapping的方式。

2、查看所有Employee信息

index.html

/** <br>
Employee的功能 <br>
*/ <br>
<a th:href="@{/employee}">查询所有员工的信息</a><br>

employee_list.html

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head><meta charset="UTF-8"><title>EmployeeList</title><link rel="stylesheet" th:href="@{static/css/index_work.css}"><link rel="stylesheet" th:href="@{static/css/index_like.css}"><link rel="stylesheet" th:href="@{static/css/style.css}">
</head>
<body><table><tr><th colspan="5">employee list</th></tr><tr><th>id</th><th>lastName</th><th>email</th><th>gender</th><th>options( <a th:href="@{/to/add}">添加</a></th></tr><tr th:each="employee : ${employees}"><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 href="">delete</a><a href="">update</a></td></tr></table>
</body>
</html>

控制器

package com.lobo.controller;
@Controller
public class EmployeeController {@AutowiredEmployeeDao employeeDao;@GetMapping("/")public String toIndex(){return "index";}@GetMapping("/employee")public String queryAll(Model model){Collection<Employee> employees = employeeDao.getAll();model.addAttribute("employees",employees);return "employee_list";}
}

添加样式

employee_list.html

    <link rel="stylesheet" th:href="@{static/css/index_work.css}"><link rel="stylesheet" th:href="@{static/css/index_like.css}"><link rel="stylesheet" th:href="@{static/css/style.css}">

此时如果我们想要添加css、js等静态资源,由于Servlet被Spring管理了,而DispatherServlet无法处理静态资源的请求,所以无法对请求的静态资源进行解析,所以会返回404错误。

具体原因如下:

配置默认的Servlet处理静态资源 同样需要开启注解驱动
当前工程的web.xml配置的前端控制器DispatcherServlet的url-pattern是/
tomcat的web.xml配置的DefaultServlet的url-pattern也是/
此时浏览器发送的请求会优先被DisPathcerServlet处理,但是DispatcherServlet无法处理静态资源解决方法:若配置了<mvc:default-servlet-handler />,此时浏览器发送的所有请求都会被DefaultServlet处理
若配置了<mvc:default-servlet-handler />和<mvc:annotation-driven/>
浏览器的请求会先被DispatcherServlet处理,无法处理后再交给DefaultServlet处理

所以我们需要在spring的配置文件中,将默认的Servlet的控制器打开,当Spring无法处理这种静态资源的请求时,会自动交由默认的Servlet进行处理,此时就能正确访问资源:

    <mvc:default-servlet-handler />
<!--    开启注解驱动--><mvc:annotation-driven/>
<!--    开启试图控制器--><mvc:view-controller path="/" view-name="index" />

注意:记得出了开启默认的Servlet,还要开启注解驱动,否则使用注解的Spring无法进行解析,也会发生访问不到网页的错误。

3、添加用户

新建添加页面

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head><meta charset="UTF-8"><title>添加用户</title><link rel="stylesheet" th:href="@{/static/css/index_work.css}">
</head>
<body><h1>添加用户</h1><form th:action="@{/employee}" method="post"><table><tr><th colspan="2">add Employee</th></tr><tr><td>LastName</td><td><input type="text" name="lastName" id="LastName"></td></tr><tr><td>Email</td><td><input type="text" name="email" id="Email"></td></tr><tr><td>Gender</td><td><input type="radio" name="Gender" value="1">male<input type="radio" name="Gender" value="1">female</td></tr><tr><td colspan="2"><input type="submit" value="添加"></td></tr></table></form>
</body>
</html>

在employee_list.html中添加链接

<th>options( <a th:href="@{/to/add}">添加</a></th>

控制器方法

使用重定向重新执行get请求方式的/employee

@PostMapping("/employee")public String addEmployee(Employee employee){employeeDao.save(employee);return "redirect:/employee";}

在这里插入图片描述

在这里插入图片描述

4、修改用户

添加修改页面

copy新建界面即可,然后更改名称

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head><meta charset="UTF-8"><title>修改用户</title><link rel="stylesheet" th:href="@{/static/css/index_work.css}">
</head>
<body>
<h1>修改用户</h1>
<form method="post" th:action="@{/employee}"><input name="_method" type="hidden" value="put"><input name="id" th:value="${employee.id}" type="hidden"><table><tr><th colspan="2">update Employee</th></tr><tr><td>LastName</td><td><input id="LastName" name="lastName" th:value="${employee.lastName}" type="text"></td></tr><tr><td>Email</td><td><input id="Email" name="email" th:value="${employee.email}" type="text"></td></tr><tr><td>Gender</td><td><input name="Gender" th:field="${employee.gender}" type="radio" value="0">male<input name="Gender" th:field="${employee.gender}" type="radio" value="1">female</td></tr><tr><td colspan="2"><input type="submit" value="修改"></td></tr></table>
</form></body>
</html>

注意这里的请求地址是/employee,我们传送的数据是带了id的Employee,我们Dao层读取到Employee的id后,就知道是修改,然后就会根据ID进行更新。

	@GetMapping("/employee/{id}")public String toUpdateEmployeePage(@PathVariable("id") Integer id, Model model) {Employee employee = employeeDao.get(id);model.addAttribute("employee", employee);return "update_employee";}@PutMapping(value = "/employee")public String updateEmployee(Employee employee) {employeeDao.save(employee);return "redirect:/employee";}

第一个方法是根据ID查询出用户的信息,然后将信息返回到修改的页面:

在这里插入图片描述

然后这里的修改就是写一个PUT方法,然后将用户存储,然后通过重定向到List界面即可

5、删除用户

删除用户的按钮需要我们对list网页进行部分的修改,然后引入vue.js将a标签修改为form表单提交。

修改employee_list.html

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head><meta charset="UTF-8"><title>EmployeeList</title><link rel="stylesheet" th:href="@{/static/css/index_work.css}">
</head>
<body>
<div id="app"><table><tr><th colspan="5">employee list</th></tr><tr><th>id</th><th>lastName</th><th>email</th><th>gender</th><th>options( <a th:href="@{/to/add}">添加</a></th></tr><tr th:each="employee : ${employees}"><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 @click="deleteEmployee" th:href="@{'/employee/'+${employee.id}}">delete</a><a th:href="@{'/employee/'+${employee.id}}">update</a></td></tr></table><form method="post"><input name="_method" type="hidden" value="delete"></form>
</div><script type="text/javascript" th:src="@{/static/js/vue.js}"></script>
<script type="text/javascript">var vue = new Vue({el: "#app",data: {},methods: {deleteEmployee() {//获取Form表单var form = document.getElementsByTagName("form")[0];//将超链接的href复制给form表单active属性//表示当前触发事件的标签form.action = event.target.href;//表单提交(触发提交)form.submit();//阻止超链接的默认行为(默认跳转页面)event.preventDefault();}}})
</script>
</body>
</html>

注意这里需要先引入vue,然后再写一个script标签,在之后的这个script标签中书写JS

还有就是VUE这里是methods,不要拼错了。

控制器方法

主要是根据ID删除,所以需要传一个ID参数

    @DeleteMapping("/employee/{id}")public String deleteEmployee(@PathVariable("id") Integer id) {employeeDao.delete(id);return "redirect:/employee";}

http://www.ppmy.cn/news/988266.html

相关文章

Python(四十九)获取列表指定元素的索引

❤️ 专栏简介&#xff1a;本专栏记录了我个人从零开始学习Python编程的过程。在这个专栏中&#xff0c;我将分享我在学习Python的过程中的学习笔记、学习路线以及各个知识点。 ☀️ 专栏适用人群 &#xff1a;本专栏适用于希望学习Python编程的初学者和有一定编程基础的人。无…

Android高德地图定位实现签到打卡功能(全网最详细+收藏)

前言 本章根据高德地图API&#xff0c;实现打卡签到功能。用到了定位SDK 和地图SDK、覆盖物。打卡范围图形可以支持多种形状&#xff0c;如&#xff1a;圆形、长方形、多边形。 核心逻辑&#xff1a; 获取当前定位信息&#xff0c;然后通过Marker绘制小图标进行展示&a…

rocketmq 5.13任意时间延迟消息

原理是采用timewhile 实现的&#xff0c;源码分析可以参考 https://blog.csdn.net/sinat_14840559/article/details/129266105 除了useDelayLevel 已经默认改为false private boolean useDelayLevel false;官方示意代码在public class TimerMessageProducer for (int i 0;…

使用mediapipe训练手指数字识别

mediapipe手指数字识别 本文是从0开始创建一个识别手势的机器学习模型&#xff0c;为了识别手势&#xff0c;采用mediapipe模型&#xff0c;这个模型会返回手指的位置&#xff0c;之后再通过训练一个模型将这些位置分类得到手势 一、导入依赖 import cv2 import numpy as np…

【Lua语法】字符串操作、字符串中的方法

1.对字符串的操作 --声明一个字符串 str "我是一个字符串"--1.获取字符串的长度 -- 前面加个#即可(注意&#xff1a;Lua中字母占1个长度&#xff0c;汉字占3个长度) print(#str)--2.字符串多行打印 -- 方法1.Lua中是支持转义字符的 print("哈哈\n嘻嘻&q…

输入矩阵解决多供给地与多需求地的资源分配最优化问题

输入矩阵解决多供给地与多需求地的资源分配的线性最优化问题, 输入&#xff1a; 供给地的数目及其资源量&#xff0c;需求地的数目及其需求量&#xff0c;供给地的地理位置&#xff0c;需求地的地理位置 &#xff08;编写函数计算供给地和需求地的距离&#xff0c;按两点间距…

[C++笔记]二叉搜索树

BSTree.h #pragma oncenamespace key {template<class K>//这里习惯用K而不是T&#xff0c;keystruct BSTreeNode {BSTreeNode<K>* _left;BSTreeNode<K>* _right;K _key;BSTreeNode(const K& key):_left(nullptr), _right(nullptr), _key(key){}};templ…

ViT-vision transformer

ViT-vision transformer 介绍 Transformer最早是在NLP领域提出的&#xff0c;受此启发&#xff0c;Google将其用于图像&#xff0c;并对分类流程作尽量少的修改。 起源&#xff1a;从机器翻译的角度来看&#xff0c;一个句子想要翻译好&#xff0c;必须考虑上下文的信息&…