人们眼中的天才之所以卓越非凡,并非天资超人一等而是付出了持续不断的努力。1万小时的锤炼是任何人从平凡变成超凡的必要条件。———— 马尔科姆·格拉德威尔
不知道大家有没有遇到过这样一个情况:看着公司controller层接口,有的参数加上@RequestBody,有的参数又没有加,代码风格层出不穷。明明前端数据已经传过来,为什么总是接收不到?
在 HTTP 协议中,客户端(如浏览器、Postman、前端代码)向服务器发送请求时会携带请求头和请求体等信息,可以通过分析请求体与请求体中的信息来选择使用哪种方式接收前端数据。
存在以下几种主要方式传递数据:
1. Request Payload(JSON/XML 等结构化数据)
2. Query String Parameters(URL 参数)
3. Form Data(表单数据)
4. Path Variables(路径参数)
5. Headers(请求头)
6. Cookies
7. GraphQL(特殊请求体)
8. WebSocket(双向通信)
一、Request Payload(JSON/XML 等结构化数据)Request Payload请求主要是向服务端发送JSON、XML等结构化数据
请求体Content-Type类型:application/json、application/xml, text/plain 等
特点:
数据放在请求体(Body)中,适用于复杂结构(如嵌套对象、数组)。后端通常用 @RequestBody 接收(Spring系列 框架)。示例:
代码语言:javascript代码运行次数:0运行复制POST /api/data HTTP/1.1
Content-Type: application/json 👈 通常在前几行
{"orderProductId": "123", "batchNumbers": ["001", "002"]}代码语言:javascript代码运行次数:0运行复制@PostMapping("/payload")
public String handleJson(@RequestBody OrderRequest request) {
return "Received: " + request.getOrderProductId() + ", " + request.getBatchNumbers();
}
@Data
public static class OrderRequest {
private String orderProductId;
private List
}二、Query String Parameters(URL 参数)使用GET请求时常遇到,通过请求地址后面拼接参数的方式进行请求。
格式:?key1=value1&key2=value2
特点:
数据附加在 URL 后,适用于简单参数。后端用 @RequestParam 接收(Spring),当方法参数名和URL参数名完全一致时可省略。示例:
代码语言:javascript代码运行次数:0运行复制GET /query?orderProductId=123&batchNumbers=001&batchNumbers=002 HTTP/1.1代码语言:javascript代码运行次数:0运行复制@GetMapping("/query")
public String handleQuery(@RequestParam String orderProductId,
@RequestParam List
return "Query: " + orderProductId + ", " + batchNumbers;
}三、Form Data(表单数据)常见于各种前端框架中,是所有前端框架(如 React、Vue、Angular 等)和原生 HTML 表单的基础支持特性。
请求体Content-Type类型:application/x-www-form-urlencoded 或 multipart/form-data
特点:
x-www-form-urlencoded:键值对格式,类似 Query String,但放在请求体中。multipart/form-data:支持文件上传。示例:
代码语言:javascript代码运行次数:0运行复制
const formData = new FormData();
formData.append('username', 'John');
formData.append('avatar', fileInput.files[0]);
fetch('/api/upload', {
method: 'POST',
body: formData // 自动设置 Content-Type: multipart/form-data
});
// 发送 x-www-form-urlencoded
axios.post('/api/login', 'username=John&password=123456', {
headers: { 'Content-Type': 'application/x-www-form-urlencoded' }
});
// 发送 multipart/form-data(文件上传)
const formData = new FormData();
formData.append('file', file);
axios.post('/api/upload', formData);代码语言:javascript代码运行次数:0运行复制// 接收 x-www-form-urlencoded
@PostMapping("/login")
public String login(
@RequestParam String username,
@RequestParam String password) {
return "User: " + username;
}
// 接收 multipart/form-data(文件上传)
@PostMapping("/upload")
public String upload(
@RequestParam String description,
@RequestPart MultipartFile file) {
return "Uploaded: " + file.getOriginalFilename();
}四、Path Variables(路径参数)RESTful 风格规范,目前主流方式。
格式:/api/{orders}/{batches}
特点:
用于 RESTful API 设计(如资源 ID)。后端用 @PathVariable 接收(Spring)。示例:
代码语言:javascript代码运行次数:0运行复制GET /api/123/001 HTTP/1.1代码语言:javascript代码运行次数:0运行复制@GetMapping("/path/{orderId}/{batchId}")
public String handlePath(
@PathVariable String orderId,
@PathVariable String batchId) {
return "Path: " + orderId + ", " + batchId;
}五、Headers(请求头)常见于实现某些特殊功能,例如:身份认证(Authorization)、跨域控制(CORS)、语言本地化(Accept-Language)、CSRF 防护(X-CSRF-Token)等等
特点:
数据放在 HTTP 头中,适用于认证(如 Authorization)、元数据等。后端用 @RequestHeader 接收(Spring)。示例:
代码语言:javascript代码运行次数:0运行复制## 身份认证(Authorization)##
传递 Token 或 API Key
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
axios.get('/user', {
headers: { 'Authorization': `Bearer ${localStorage.getItem('token')}` }
});
@GetMapping("/user")
public String getUser(@RequestHeader("Authorization") String token) {
// 解析 Token 获取用户信息
return "User from token";
}代码语言:javascript代码运行次数:0运行复制## 跨域控制(CORS)##
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET,POST
@Configuration
public class CorsConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOrigins("*")
.allowedMethods("GET", "POST");
}
}六、CookiesCookies 在 Web 开发中主要用于客户端状态管理,通过浏览器自动存储和传递数据。
特点:
数据由浏览器自动附加在请求头(Cookie: name=value)。后端用 @CookieValue 接收(Spring)。前端自动处理,浏览器后续请求能够自动携带该 Cookie。示例:
代码语言:javascript代码运行次数:0运行复制## 用户会话管理(Session ID)##
Set-Cookie: sessionId=abc123; Path=/; HttpOnly; Secure
@PostMapping("/login")
public String login(HttpServletResponse response) {
String sessionId = UUID.randomUUID().toString();
Cookie cookie = new Cookie("sessionId", sessionId);
cookie.setHttpOnly(true);
cookie.setSecure(true); // 仅 HTTPS
cookie.setPath("/");
response.addCookie(cookie);
return "Login success";
}代码语言:javascript代码运行次数:0运行复制## 个性化设置(如主题/语言) ##
Set-Cookie: lang=zh-CN; Max-Age=2592000; Path=/
document.cookie = "lang=zh-CN; max-age=2592000; path=/";
@GetMapping("/news")
public String getNews(@CookieValue(value = "lang", defaultValue = "en") String lang) {
return "Display news in " + lang;
}代码语言:javascript代码运行次数:0运行复制## 个性化设置(如主题/语言) ##
Set-Cookie: cart=%7B%22items%22%3A%5B%7B%22id%22%3A101%7D%5D%7D; Path=/shop
@PostMapping("/add-to-cart")
public String addToCart(@CookieValue("cart") String cartJson,
@RequestBody Item item) {
Cart cart = objectMapper.readValue(cartJson, Cart.class);
cart.addItem(item);
// 返回更新后的 Cookie
}七、GraphQL(特殊请求体)GraphQL 是一种用于 API 的查询语言和运行时环境,它允许客户端精确请求所需的数据,避免了 REST API 中常见的过度获取或不足获取的问题。
GraphQL 通过其灵活的查询能力,非常适合数据关系复杂或客户端需求多变的场景。
请求体Content-Type类型:application/json
特点:
通过 JSON 体指定查询语句,灵活获取数据。需后端单独支持 GraphQL 协议。示例:Spring Boot 集成 GraphQL
代码语言:javascript代码运行次数:0运行复制
代码语言:javascript代码运行次数:0运行复制# 创建 schema.graphqls 文件
# src/main/resources/schema.graphqls
type Query {
user(id: ID!): User
}
type User {
id: ID!
name: String!
email: String
orders: [Order]
}
type Order {
id: ID!
totalPrice: Float
items: [OrderItem]
}代码语言:javascript代码运行次数:0运行复制@Component
public class UserResolver implements GraphQLQueryResolver {
public User user(String id) {
// 从数据库或服务获取数据
return userService.getUserById(id);
}
}
// 自动关联到 Schema 中的 `User.orders` 字段
@Component
public class OrderResolver implements GraphQLResolver
public List
return orderService.getOrdersByUserId(user.getId());
}
}代码语言:javascript代码运行次数:0运行复制POST /graphql HTTP/1.1
Content-Type: application/json
## 默认端点为 /graphql,直接接收 POST 请求 ##
{
"query": "query { user(id: \"123\") { name orders { id } }"
}
## 等同于下面 👇
query {
user(id: "123") {
name
orders {
id
}
}
}八、WebSocket(双向通信)WebSocket 是一种全双工通信协议,适用于需要**实时双向数据交互**的场景。
特点:
建立长连接后,客户端和服务器可随时互发数据(非 HTTP 请求)。数据格式通常为 JSON 或二进制。示例:Spring Boot 简单集成 websocket
代码语言:javascript代码运行次数:0运行复制
代码语言:javascript代码运行次数:0运行复制@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {
@Override
public void configureMessageBroker(MessageBrokerRegistry config) {
config.enableSimpleBroker("/topic", "/queue");
config.setApplicationDestinationPrefixes("/app");
}
@Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
registry.addEndpoint("/ws").withSockJS();
}
}代码语言:javascript代码运行次数:0运行复制const socket = new SockJS('/ws');
const stompClient = Stomp.over(socket);
stompClient.connect({}, () => {
stompClient.subscribe('/topic/updates', (message) => {
console.log('收到更新:', message.body);
});
});这里仅仅简单举例,WebSocket实际涉及的内容比较多,感兴趣的可以私下学习了解一下其实现原理以及集成第三方Mq组件和安全框架等等。
九、总结方式
数据位置
后端接收注解(Spring)
适用场景
Request Payload
请求体(Body)
@RequestBody
复杂结构(JSON/XML)
Query String
URL 参数
@RequestParam
简单参数
Form Data
请求体(Body)
@RequestParam
表单提交/文件上传
Path Variables
URL 路径
@PathVariable
RESTful 资源标识
Headers
请求头
@RequestHeader
认证、元数据
Cookies
请求头(自动附加)
@CookieValue
会话管理
GraphQL
请求体(JSON)
自定义解析
灵活数据查询
WebSocket
独立协议
自定义处理器
实时双向通信
根据自己的需求选择合适的方式,大多数 API 优先使用 JSON Payload 或 Query String。