目录声明什么是RESTfulRESTful 的基本原则无状态性Stateless统一接口Uniform Interface分层系统Layered System缓存Cacheable按需代码Code on Demand, 可选HTTP 协议里面四个表示操作方式的动词PathVariablePathVariable 映射 URL 绑定的占位符PathVariable的参数基本用法多个路径变量默认值注意事项RequestParamRequestParam的参数基本用法默认值多个值必填与可选参数数据验证注意事项RequestBody基本用法支持的数据格式数据验证异常处理注意事项URL统一资源定位符URL 的基本结构完整 URL 示例URL 编码URL 的作用资源定位导航交互搜索引擎优化SEOPathVariable、RequestParam、RequestBody是构建 RESTful Web 服务的非常有用的工具声明本文大多引用出处来自Spring Boot中PathVariable、RequestParam和RequestBody的区别和使用_spring boot pathvariable-CSDN博客本文仅作学习记录参考若有侵权麻烦告知删除什么是RESTfulRESTful是一种基于HTTP协议的软件架构风格它用于设计网络应用程序接口API。REST代表“表述性状态转移”Representational State Transfer其核心思想是通过一组标准的操作和资源来实现客户端与服务器之间的交互。RESTful API 设计强调简洁、直观和易于理解遵循无状态通信原则使得开发者能够快速构建和维护分布式系统。RESTful 的基本原则无状态性Stateless每个请求都必须包含所有必要的信息以使服务器能够理解和处理该请求而不依赖于任何先前的交互或会话状态。统一接口Uniform Interface使用一致的方式定义资源及其操作包括资源标识Resource Identification每个资源都有一个唯一的URI统一资源标识符下文有详解。自描述消息Self-descriptive Messages响应中包含足够的信息让客户端知道如何处理数据例如内容类型如JSON、XML。HATEOASHypermedia as the Engine of Application State允许API返回链接到其他相关资源的数据指导客户端下一步操作。分层系统Layered System系统可以由多个层级组成每一层只与紧邻的一层进行交互从而增加了灵活性和可扩展性。缓存Cacheable响应可以被标记为可缓存以便后续相同的请求可以直接从缓存中获取结果减少对服务器的压力。按需代码Code on Demand, 可选服务器可以在响应中提供可执行代码如JavaScript以增强客户端的功能。这一特性在RESTful API中较少使用。HTTP协议里面四个表示操作方式的动词GET、POST、PUT、DELETE它们分别对应四种基本操作GET用来获取资源POST用来新建资源PUT用来更新资源DELETE用来删除资源PathVariable主要用于将 URL 中的模板变量映射到方法参数上。它允许开发者从请求路径中提取出特定部分的数据并直接传递给控制器方法的参数从而简化了对动态路径元素的处理。PathVariable 映射 URL 绑定的占位符通过PathVariable可以将URL中占位符参数绑定到控制器controller处理方法的形参中URL 中的 {xxx} 占位符可以通过PathVariable(“xxx“) 绑定到操作方法的形参中。PathVariable的参数**String value**可指定占位符 { } 中的参数名若只指定value这一个属性可省略属性名不写若占位符中的参数名和处理方法中的参数名相同可省略此属性**String name**等价与value和value无本质上的差异两个属性指定其一即可**boolean required**是否必需默认为 true即 请求中必须包含该参数如果没有包含将会抛出异常基本用法假设你有一个 RESTful API 用来管理用户信息每个用户的详细信息可以通过其唯一的 ID 来访问。你可以定义如下形式的 URLGET /users/{id}在这个例子中{id} 就是一个路径变量表示用户 ID。为了在控制器方法中获取这个 ID 的值可以使用PathVariable注解RestController RequestMapping(/users) public class UserController { GetMapping(/{id}) public ResponseEntityUser getUserById(PathVariable Long id) { // 根据ID查找用户逻辑 User user userService.findById(id); if (user ! null) { return ResponseEntity.ok(user); } else { return ResponseEntity.notFound().build(); } } }在这个例子中PathVariable Long id表示从 URL 路径/users/{id}中提取 id 参数并将其转换为 Long 类型后赋值给方法参数 id。多个路径变量当需要同时处理多个路径变量时可以在同一个方法签名中使用多个PathVariable注解GetMapping(/users/{userId}/posts/{postId}) public ResponseEntityPost getPostByUserAndPostId( PathVariable(userId) Long userId, PathVariable(postId) Long postId) { // 查找指定用户下的指定帖子逻辑 Post post postService.findByUserAndPostId(userId, postId); if (post ! null) { return ResponseEntity.ok(post); } else { return ResponseEntity.notFound().build(); } }注意如果你的方法参数名与路径变量名相同则可以直接省略PathVariable的参数名称如上面的第一个例子。如果不同则必须显式指定路径变量的名字如PathVariable(userId) Long userId。默认值有时你可能希望为路径变量提供默认值以防万一客户端没有提供或提供了无效的值。Spring 5.1 及以上版本支持通过 defaultValue属性来设置默认值GetMapping(/users/{id}) public ResponseEntityString getUserById(PathVariable(value id, required false) String id) { if (id null || id.isEmpty()) { id default; // 使用默认值 } // 其他业务逻辑... }不过需要注意的是默认值通常不适用于主键等关键字段因为这些字段往往要求必须由客户端提供准确的值。注意事项类型转换PathVariable支持自动进行简单的类型转换如字符串到整数、长整型等但如果遇到复杂的类型转换需求可能需要自定义转换器。验证虽然PathVariable可以结合 JSR 303 Bean Validation 注解如 NotNull, Size 等一起使用来进行参数验证但在实际应用中由于路径变量通常是唯一标识符更多时候是通过服务层逻辑来确保其有效性。安全性确保正确处理潜在的安全问题例如防止注入攻击。避免直接将未经验证的路径变量拼接到 SQL 查询或其他敏感操作中。总之PathVariable是构建 RESTful Web 服务的一个非常有用的工具它使得 URL 设计更加清晰且易于理解和维护。正确使用它可以大大提高代码的可读性和灵活性。RequestParamRequestParam是 Spring 框架中的一个注解主要用于将 HTTP 请求中的查询参数Query Parameters或表单数据绑定到控制器方法的参数上。它允许开发者轻松地从 GET 或 POST 请求中获取用户传递的参数值并将其直接映射到方法参数中进行处理。这对于构建动态且灵活的 Web 应用程序非常重要。RequestParam的参数**String value**请求中传入参数的名称如果不设置value值则会默认为该变量名**String name**等价与value和value无本质上的差异两个属性指定其一即可**boolean required**是否必需默认为 true即 请求中必须包含该参数如果没有包含将会抛出异常可选配置**String defaultValue**参数的默认值如果请求中没有同名的参数时该变量默认为此值基本用法假设你有一个 RESTful API 用来搜索用户信息可以通过用户名或者邮箱来查找用户。你可以定义如下形式的 URLGET /users?usernamejohnemailjohnexample.com在这个例子中username 和 email 就是查询参数。为了在控制器方法中获取这些参数的值可以使用RequestParam注解RestController RequestMapping(/users) public class UserController { GetMapping public ResponseEntityListUser searchUsers( RequestParam(value username, required false) String username, RequestParam(value email, required false) String email) { // 根据提供的参数查找用户逻辑 ListUser users userService.searchByUsernameOrEmail(username, email); return ResponseEntity.ok(users); } }在这个例子中RequestParam(value username, required false)表示从请求中提取名为 username 的查询参数并将其赋值给方法参数 username。如果该参数不存在则不会抛出异常因为 required false。类似地RequestParam(value email, required false)处理 email 参数。默认值有时你可能希望为某些参数提供默认值以防万一客户端没有提供或提供了无效的值。可以通过 defaultValue 属性来设置默认值GetMapping public ResponseEntityListUser searchUsers( RequestParam(value page, defaultValue 1) int page, RequestParam(value size, defaultValue 20) int size) { // 分页查询用户逻辑 Pageable pageable PageRequest.of(page - 1, size); PageUser userPage userService.findAll(pageable); return ResponseEntity.ok(userPage.getContent()); }在这个例子中如果没有提供 page 或 size 参数它们将分别被赋予默认值 1 和 20。多个值对于某些情况下一个参数可能会有多个值例如多选框提交的数据。可以使用数组或集合类型作为方法参数GetMapping(/filter) public ResponseEntityListUser filterUsers(RequestParam(role) ListString roles) { // 根据角色过滤用户逻辑 ListUser filteredUsers userService.findByRoles(roles); return ResponseEntity.ok(filteredUsers); }在这个例子中roles 参数可以接受多个值如/filter?roleadminroleuser。必填与可选参数通过设置 required 属性可以指定某个参数是否为必填项。如果设置为 true默认则当请求中缺少该参数时会抛出MissingServletRequestParameterException异常如果设置为 false则即使缺少该参数也不会报错参数值将为 null 或者使用默认值。RequestParam(value username, required true)数据验证虽然RequestParam支持简单的类型转换如字符串到整数、长整型等但在实际应用中通常还需要对参数进行更严格的验证。可以结合 JSR 303 Bean Validation 注解如 NotNull, Size 等一起使用来进行参数验证import javax.validation.constraints.NotNull; import javax.validation.constraints.Size; GetMapping public ResponseEntityListUser searchUsers( RequestParam Size(min 3, max 50) String username, RequestParam NotNull String email) { // 验证后的业务逻辑... }注意事项安全性确保正确处理潜在的安全问题例如防止SQL注入攻击。避免直接将未经验证的参数拼接到 SQL 查询或其他敏感操作中。编码问题对于包含特殊字符或非ASCII字符的参数值注意URL编码和解码的问题确保正确传输和解析。总之RequestParam是构建动态Web应用程序的一个非常有用的工具它使得从HTTP请求中获取参数变得简单而直观。正确使用它可以大大提高代码的可读性和灵活性同时也能增强系统的健壮性和安全性。RequestBodyRequestBody是 Spring 框架中的一个注解主要用于将 HTTP 请求体Request Body中的内容绑定到控制器方法的参数上。它允许开发者直接处理客户端发送过来的 JSON、XML 或其他格式的数据并将其转换为 Java 对象从而简化了数据的接收和解析过程。RequestBody接收数据时前端不能使用GET方式提交数据而是用POST等方式进行提交。基本用法假设你有一个 RESTful API 用来创建新用户。客户端会发送一个包含用户信息的 JSON 对象作为 POST 请求的主体。你可以使用RequestBody注解将这个 JSON 数据映射到一个 Java 对象中PostMapping(/users) public ResponseEntityUser createUser(RequestBody User user) { // 处理新用户的逻辑... User savedUser userService.save(user); return ResponseEntity.ok(savedUser); }在这个例子中RequestBody User user表示从请求体中读取 JSON 数据并将其反序列化为 User 类型的对象。Spring 会自动处理 JSON 到 Java 对象的转换前提是已经配置了适当的 Jackson 或 Gson 等 JSON 解析库。支持的数据格式RequestBody可以处理多种数据格式包括但不限于JSON最常用的格式之一适合表示结构化的数据。XML某些系统可能更倾向于使用 XML 格式。自定义格式如果需要支持特定的应用程序或行业标准格式可以通过实现自己的消息转换器来扩展RequestBody的功能。为了确保 Spring 能够正确地解析和转换这些不同格式的数据通常需要在请求头中指定Content-Type例如application/json用于 JSON 格式的数据。application/xml用于 XML 格式的数据。数据验证结合 JSR 303 Bean Validation 注解如 NotNull, Size 等可以对传入的请求体进行验证确保接收到的数据符合预期的要求import javax.validation.Valid; import javax.validation.constraints.NotEmpty; import javax.validation.constraints.Size; public class User { NotEmpty(message 用户名不能为空) private String username; Size(min 5, max 20, message 密码长度应在5到20个字符之间) private String password; // Getters and Setters... } PostMapping(/users) public ResponseEntityUser createUser(Valid RequestBody User user) { // 验证后的业务逻辑... }在这个例子中Valid 注解告诉 Spring 在调用 createUser 方法之前先对 User 对象进行验证。如果验证失败Spring 会自动返回一个包含错误信息的响应给客户端。异常处理当请求体不符合预期格式或无法正确解析时可能会抛出异常。常见的异常包括HttpMessageNotReadableException当请求体为空或者格式不正确时抛出。MethodArgumentNotValidException当使用 Valid 注解且验证失败时抛出。为了优雅地处理这些异常可以使用 ControllerAdvice 和 ExceptionHandler 来全局捕获并定制响应ControllerAdvice public class GlobalExceptionHandler { ExceptionHandler(HttpMessageNotReadableException.class) public ResponseEntityString handleHttpMessageNotReadable(HttpMessageNotReadableException ex) { return ResponseEntity.badRequest().body(请求体格式错误: ex.getMessage()); } ExceptionHandler(MethodArgumentNotValidException.class) public ResponseEntityString handleValidationErrors(MethodArgumentNotValidException ex) { StringBuilder errors new StringBuilder(); ex.getBindingResult().getAllErrors().forEach((error) - { errors.append(error.getDefaultMessage()).append(, ); }); return ResponseEntity.badRequest().body(errors.toString()); } }注意事项性能考虑对于大型请求体或频繁的请求应评估性能影响并考虑使用流式处理或其他优化策略。安全性避免直接将未经验证的请求体数据用于敏感操作如数据库查询等以防 SQL 注入或其他类型的攻击。大小限制可以通过配置服务器或框架参数来限制请求体的最大允许大小防止恶意用户上传过大的文件导致服务崩溃。如果后端参数是一个对象且该参数前是以**RequestBody**修饰的那么前端传递json参数时必须满足以下要求后端**RequestBody注解对应的类在将HTTP的输入流含请求体装配到目标类RequestBody**后的类时会根据json字符串中的key来匹配对应实体类的属性如果匹配一致且json中的该key对应的值符合实体类的对应属性类型时,会调用实体类的setter方法将值赋给该属性。json字符串中如果value为“的话后端对应属性如果是String类型的那么接受到的就是”如果是后端属性的类型是Integer、Double等类型那么接收到的就是null。json字符串中如果value为null的话后端对应收到的就是null。如果某个参数没有value的话在传json字符串给后端时要么干脆就不把该字段写到json字符串中要么写value时 必须有值null 或都行。总之RequestBody是构建 RESTful Web 应用程序的一个非常有用的工具它使得从 HTTP 请求体中获取和处理复杂数据变得简单而直观。正确使用它可以大大提高代码的可读性和灵活性同时也能增强系统的健壮性和安全性。URL统一资源定位符URL是Uniform Resource Locator的缩写意为“统一资源定位符”。它是互联网上用来标识资源位置的地址通常用于访问网页、文件、图片等网络资源。一个URL通常包含以下几个部分URL 的基本结构一个典型的 URL 由以下几个部分组成scheme://[userinfo]host[:port]/path?query#fragmentscheme协议指定用于访问资源的协议类型如http、https、ftp等。这是 URL 中最前面的部分后面跟有两个斜杠//。示例httpsuserinfo用户信息可选包含用户名和密码已不推荐使用用于认证目的。如果存在则以username:password的形式出现在主机名之前。示例alice:bobhost主机名表示托管资源的服务器地址可以是域名或 IP 地址。示例example.comport端口号可选指明服务器监听的服务端口默认情况下HTTP 使用 80 端口HTTPS 使用 443 端口。如果使用默认端口通常省略此部分。示例:8080path路径指定资源在服务器上的具体位置类似于文件系统的目录路径。它可以包括多个层级。示例/articles/2023/12/new-article.htmlquery查询字符串可选包含一系列键值对参数用于向服务器传递额外信息。查询字符串以问号?开始各个参数之间用与号分隔。示例?searchRESTfullangenfragment片段标识符可选用于指示文档内的某个特定部分通常用于 HTML 页面中的锚点链接。片段标识符以井号#开始。示例#section-3完整 URL 示例https://user:passexample.com:8080/articles/2023/12/new-article.html?searchRESTfullangen#section-3在这个例子中https是协议。user:pass是用户信息尽管这种做法已不推荐。example.com 是主机名。:8080是端口号。/articles/2023/12/new-article.html是路径。?searchRESTfullangen是查询字符串。#section-3是片段标识符。URL 编码由于 URL 只能包含某些字符集如 ASCII 字符因此对于不在允许范围内的字符如空格、非英文字符等需要进行编码处理。URL 编码遵循 RFC 3986 标准使用百分号%后接两位十六进制数来表示特殊字符。例如空格会被编码为%20。汉字“中”可能会被编码为%E4%B8%AD。URL 的作用资源定位URL 提供了一种标准化的方式来唯一地标识和定位互联网上的任何资源。导航用户可以通过点击链接或直接输入 URL 来浏览不同的网页和服务。交互开发人员利用 URL 来构建 RESTful API通过不同的 HTTP 方法如 GET、POST、PUT、DELETE对资源进行 CRUD 操作。搜索引擎优化SEO良好的 URL 结构有助于提高网站在搜索引擎结果页面中的排名因为清晰且描述性的 URL 更容易被索引和理解。总之URL 是互联网通信的基础之一它不仅简化了我们访问在线资源的过程也为开发者提供了强大的工具来设计和实现各种网络应用。正确理解和使用 URL 对于创建高效、易用且安全的 Web 应用至关重要。若本文存在问题欢迎批评指出谢谢