跳到主要内容Java 后端 HTTP 请求(GET/POST)传输规范 | 极客日志Javajava
Java 后端 HTTP 请求(GET/POST)传输规范
本文介绍 Java 后端 HTTP GET 与 POST 请求传输规范。涵盖 RESTful 原则、参数传递(路径/查询/Body)、敏感数据保护、幂等性、响应体封装及异常处理。强调 URI 命名、版本控制、日志安全及前后端协作,提供代码示例与对照表,提升接口安全性与规范性。
一、核心原则
- 遵循'RESTful 风格',URI 仅表示资源,HTTP 方法表示操作;
- GET 仅用于查询,禁止通过 GET 传递敏感数据;POST 用于新增 / 修改 / 删除,或传递大量 / 敏感数据;
- 所有接口参数、响应数据统一使用 UTF-8 编码,避免乱码。
二、GET 请求规范
1. 用途限制
- 仅用于查询 / 获取资源,禁止用于新增、修改、删除操作;
- 后端注解:统一使用
@GetMapping,禁止用@RequestMapping(method = RequestMethod.GET)(冗余)。
2. 参数传递规则(Java 编码落地)
(1)路径参数(唯一标识)
- 后端用
@PathVariable接收,参数名与 URI 中的占位符一致;
- ✅ 正确代码示例:
@RestController
@RequestMapping("/api/v1/users")
public class UserController {
@GetMapping("/{userId}")
public ResultDTO<UserInfoRespDTO> getUserById(@PathVariable("userId") Long userId) {
UserInfoRespDTO user = userService.getUserById(userId);
return ResultDTO.success(user);
}
}
- ❌ 错误:用
@RequestParam接收唯一标识(如@RequestParam("userId") Long userId)。
(2)查询参数(筛选 / 分页 / 排序)
- 后端用
@RequestParam接收,可设置默认值、是否必传;
- 参数命名:小驼峰,与前端一致,禁止用下划线;
- ✅ 正确代码示例:
@GetMapping("/orders")
public ResultDTO<PageInfo<OrderListRespDTO>> getOrderList(
@RequestParam(value = "status", required = false) String status,
@RequestParam(value = "pageNum", defaultValue = "1") Integer pageNum,
@RequestParam(value = "pageSize", defaultValue = "10") Integer pageSize
) {
PageInfo<OrderListRespDTO> page = orderService.getOrderList(status, pageNum, pageSize);
return ResultDTO.success(page);
}
(3)复杂查询参数(多个筛选条件)
- 封装为
XXXQueryReqDTO,用@ModelAttribute接收(避免参数过多);
- ✅ 正确代码示例:
@Data
public class OrderQueryReqDTO {
private String status;
private String orderNo;
private LocalDateTime startTime;
private LocalDateTime endTime;
private Integer pageNum = 1;
private Integer pageSize = 10;
}
@GetMapping("/orders/query")
public ResultDTO<PageInfo<OrderListRespDTO>> queryOrder(@ModelAttribute OrderQueryReqDTO queryDTO) {
PageInfo<OrderListRespDTO> page = orderService.queryOrder(queryDTO);
return ResultDTO.success(page);
}
3. 长度与编码
- 后端无需手动 URL 解码(SpringMVC 自动解码);
- 若参数含中文 / 特殊字符,确保
application.yml中配置:
server:
tomcat:
uri-encoding: UTF-8
spring:
http:
encoding:
charset: UTF-8
enabled: true
force: true
4. 敏感数据禁止
- 后端通过拦截器 / 切面校验:若 GET 请求参数包含
password/token/phone等敏感字段,直接返回 400;
- 示例(拦截器逻辑):
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
String method = request.getMethod();
if ("GET".equals(method)) {
Map<String, String[]> paramMap = request.getParameterMap();
if (paramMap.containsKey("password") || paramMap.containsKey("token")) {
response.setStatus(400);
response.getWriter().write(JSON.toJSONString(ResultDTO.fail("GET 请求禁止传递敏感数据")));
return false;
}
}
return true;
}
三、POST 请求规范
1. 用途限制
- 用于新增 / 修改 / 删除资源,或传递大量 / 敏感数据的查询;
- 后端注解:统一使用
@PostMapping,禁止用@RequestMapping(method = RequestMethod.POST)。
2. 参数传递规则(Java 编码落地)
(1)JSON 参数(主流)
- 后端用
@RequestBody接收,参数封装为XXXReqDTO,并添加 JSR380 参数校验注解;
- ✅ 正确代码示例:
@Data
@Schema(description = "用户新增请求参数")
public class UserAddReqDTO {
@NotBlank(message = "用户名不能为空")
@Size(min = 2, max = 20, message = "用户名长度需在 2-20 位")
private String username;
@NotBlank(message = "密码不能为空")
@Pattern(regexp = "^[a-zA-Z0-9@#$%^&*]{6,32}$", message = "密码仅支持字母、数字、特殊符号,长度 6-32 位")
private String password;
@Pattern(regexp = "^1[3-9]\\d{9}$", message = "手机号格式错误")
private String phoneNumber;
}
@PostMapping("/users")
public ResultDTO<Long> addUser(@Valid @RequestBody UserAddReqDTO addDTO) {
Long userId = userService.addUser(addDTO);
return ResultDTO.success(userId, "新增用户成功");
}
- 注意:必须加
@Valid触发参数校验,否则注解不生效;校验失败会抛出MethodArgumentNotValidException,需在全局异常处理器中捕获。
(2)文件上传(multipart/form-data)
- 后端用
@RequestPart接收文件,@RequestParam接收附加参数;
- 配置文件上传大小限制:
spring:
servlet:
multipart:
max-file-size: 10MB
max-request-size: 50MB
@PostMapping("/files/upload")
public ResultDTO<FileUploadRespDTO> uploadFile(
@RequestPart("file") MultipartFile file,
@RequestParam("fileName") String fileName
) {
if (!file.getContentType().startsWith("image/")) {
return ResultDTO.fail(400, "仅支持图片上传");
}
FileUploadRespDTO resp = fileService.upload(file, fileName);
return ResultDTO.success(resp);
}
(3)幂等性保障(新增接口)
- 后端通过'唯一业务编号'+ 数据库唯一索引实现幂等;
- 示例:新增订单时,前端传递
orderNo(UUID),后端先查后插:
@Transactional(rollbackFor = Exception.class)
public Long addOrder(OrderCreateReqDTO createDTO) {
if (orderMapper.existsByOrderNo(createDTO.getOrderNo())) {
throw new BusinessException("订单已存在,请勿重复提交");
}
Order order = new Order();
BeanUtils.copyProperties(createDTO, order);
orderMapper.insert(order);
return order.getId();
}
3. 特殊场景:POST 查询(敏感 / 大量参数)
- 适用于参数过多(超过 URL 长度限制)、含敏感数据的查询;
- ✅ 正确代码示例:
@PostMapping("/orders/complex-query")
public ResultDTO<PageInfo<OrderListRespDTO>> complexQuery(@RequestBody OrderComplexQueryReqDTO queryDTO) {
PageInfo<OrderListRespDTO> page = orderService.complexQuery(queryDTO);
return ResultDTO.success(page);
}
四、通用规范(GET/POST 均适用)
1. URI 命名规则(Java 编码落地)
- Controller 类上的
@RequestMapping统一以 /api/v{版本号}/开头,资源用复数名词;
- ✅ 正确:
@RequestMapping("/api/v1/users"),❌ 错误:@RequestMapping("/api/v1/user")/@RequestMapping("/api/v1/getUser")。
2. 响应规范(统一返回体)
- 后端封装通用响应类
ResultDTO,所有接口统一返回该类型,禁止直接返回业务对象 / 字符串;
- ✅ 通用响应类代码:
@Data
public class ResultDTO<T> {
private Integer code;
private String msg;
private T data;
public static <T> ResultDTO<T> success(T data) {
ResultDTO<T> result = new ResultDTO<>();
result.setCode(200);
result.setMsg("操作成功");
result.setData(data);
return result;
}
public static ResultDTO<Void> success() {
return success(null);
}
public static ResultDTO<Void> fail(Integer code, String msg) {
ResultDTO<Void> result = new ResultDTO<>();
result.setCode(code);
result.setMsg(msg);
return result;
}
}
3. 异常处理(Java 编码落地)
- 全局异常处理器统一捕获所有异常,返回标准化
ResultDTO,禁止接口抛出未捕获异常;
- ✅ 全局异常处理器代码:
@RestControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(MethodArgumentNotValidException.class)
public ResultDTO<Void> handleValidException(MethodArgumentNotValidException e) {
String msg = e.getBindingResult().getFieldError().getDefaultMessage();
return ResultDTO.fail(400, msg);
}
@ExceptionHandler(BusinessException.class)
public ResultDTO<Void> handleBusinessException(BusinessException e) {
return ResultDTO.fail(e.getCode(), e.getMessage());
}
@ExceptionHandler(Exception.class)
public ResultDTO<Void> handleException(Exception e) {
log.error("服务端异常", e);
return ResultDTO.fail(500, "服务器内部错误,请稍后重试");
}
}
4. 接口版本控制
- 后端通过 URI 携带版本号(推荐),禁止通过参数(如
?version=1)或请求头控制版本;
- ✅ 正确:
@RequestMapping("/api/v1/users"),@RequestMapping("/api/v2/users")。
五、反例与正例对照表(Java 编码)
| 场景 | 反例(禁止) | 正例(推荐) |
|---|
| GET 查询单个用户 | @GetMapping("/getUser") + @RequestParam("userId") Long userId | @GetMapping("/{userId}") + @PathVariable Long userId |
| POST 新增用户 | @PostMapping("/addUser") + URL 传参 | @PostMapping("/users") + @RequestBody UserAddReqDTO |
| 响应数据 | return user;(直接返回业务对象) | return ResultDTO.success(user); |
| 参数校验 | 手动 if 判断(if (username == null) { throw new Exception(); }) | JSR380 注解(@NotBlank)+ @Valid |
六、Java 后端编码额外规范
- 请求头规范:
- 跨域请求:后端配置
CorsConfig,允许前端的 Origin、Method、Header;
- 认证请求:token 统一放在
Authorization请求头,后端用@RequestHeader("Authorization") String token接收。
- 所有接口入参 / 出参必须打印日志(使用 SLF4J),禁止打印敏感数据(如密码);
- ✅ 示例:
- 性能规范:
- GET 请求建议添加缓存(如 Redis),避免频繁查库;
- POST 请求建议异步处理(如 MQ),耗时操作(如文件解析、数据同步)不阻塞接口响应。
@GetMapping("/{userId}")
public ResultDTO<UserInfoRespDTO> getUserById(@PathVariable("userId") Long userId) {
log.info("【查询用户】入参:userId={}", userId);
UserInfoRespDTO user = userService.getUserById(userId);
log.info("【查询用户】出参:{}", JSON.toJSONString(user));
return ResultDTO.success(user);
}
总结
- 编码核心:GET 用
@PathVariable/@RequestParam,POST 用@RequestBody,参数校验用 JSR380+@Valid;
- 响应核心:所有接口统一返回
ResultDTO,异常统一由 GlobalExceptionHandler捕获;
- 安全核心:GET 禁止传敏感数据,POST 新增接口保证幂等,日志屏蔽敏感信息;
- 规范核心:URI 用小写复数名词 + 版本号,参数命名小驼峰,编码统一 UTF-8。
补充:前后端参数传递对照总表
| 请求类型 | 参数传递位置 | 前端核心写法(示例) | 后端核心写法(Java) | 适用场景 | 关键规范 / 注意事项 |
|---|
| GET | URL 路径参数 | axios.get('/api/v1/users/1001') | @GetMapping("/{userId}")
@PathVariable("userId") Long userId | 查询单个资源(如查用户 / 订单) | 1. 路径参数为唯一标识(ID / 编号) 2. URI 用复数名词,小写 |
| GET | URL 查询参数 | axios.get('/api/v1/orders', { params: { status: 'PAID', pageNum: 1 } }) | @GetMapping("/orders")
@RequestParam String status
@RequestParam Integer pageNum | 列表筛选 / 分页 / 排序 | 1. 参数名小驼峰 2. 非必传参数加 required = false 3. 可封装为 DTO 用 @ModelAttribute接收 |
| POST | Request Body(JSON) | axios.post('/api/v1/users', { username: '张三', password: '123456' }) | @PostMapping("/users")
@Valid @RequestBody UserAddReqDTO addDTO | 新增 / 修改资源、复杂查询 | 1. 必加 @Valid触发参数校验 2. DTO 加 JSR380 注解(@NotBlank/@Pattern) 3. Content-Type: application/json |
| POST | Form Data(表单) | let formData = new FormData();
formData.append('username', '张三');
axios.post('/api/v1/users/login', formData) | @PostMapping("/login")
@RequestParam String username
@RequestParam String password | 简单表单提交(如登录) | 1. Content-Type: application/x-www-form-urlencoded 2. 敏感数据建议转 JSON 传递 |
| POST | Multipart Form Data(文件 + 参数) | let formData = new FormData();
formData.append('file', file);
formData.append('fileName', '头像.png');
axios.post('/api/v1/files/upload', formData) | @PostMapping("/upload")
@RequestPart("file") MultipartFile file
@RequestParam("fileName") String fileName | 文件上传(单 / 多文件) | 1. 配置文件大小限制(spring.servlet.multipart) 2. 文件参数名统一为 file |
| GET/POST | 请求头参数 | axios.get('/api/v1/users', { headers: { Authorization: 'Bearer token123' } }) | @RequestHeader("Authorization") String token | 传递 token / 语言 / 版本等 | 1. 认证 token 统一放 Authorization头 2. 非敏感、固定参数用请求头 |
| POST | 混合参数(路径 + JSON) | axios.post('/api/v1/users/1001/update', { phone: '13800138000' }) | @PostMapping("/{userId}/update")
@PathVariable Long userId
@RequestBody UserUpdateReqDTO updateDTO | 修改单个资源(带 ID + 参数) | 1. 路径传唯一标识,Body 传修改参数 2. 禁止路径传大量参数 |
补充:说明(前后端协作关键)
1. 通用数据格式
- 字符编码:前后端统一用 UTF-8;
- 数值类型:前端传递数字(如
pageNum: 1),禁止传字符串(如 pageNum: "1"),后端用 Integer/Long接收。
- 日期格式:统一用
yyyy-MM-dd HH:mm:ss(前端传字符串,后端用 @DateTimeFormat接收)。
@GetMapping("/orders")
public ResultDTO<?> getOrders(@RequestParam @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime startTime) {
}
2. 错误码 / 响应格式统一
| 响应场景 | 前端接收格式 | 后端返回写法 |
|---|
| 成功 | { code: 200, msg: "成功", data: {} } | ResultDTO.success(data) |
| 参数校验失败 | { code: 400, msg: "用户名不能为空" } | ResultDTO.fail(400, "用户名不能为空") |
| 权限不足 | { code: 403, msg: "无权限" } | ResultDTO.fail(403, "无权限") |
| 服务端异常 | { code: 500, msg: "服务器错误" } | ResultDTO.fail(500, "服务器错误") |
3. 反例对照(禁止写法)
| 场景 | 前端反例 | 后端反例 | 问题说明 |
|---|
| GET 传敏感数据 | axios.get('/login?pwd=123456') | @RequestParam String pwd | 密码暴露在 URL / 日志中 |
| POST 用 URL 传大量参数 | axios.post('/users?name=张三&age=20&phone=138...') | @RequestParam接收 10 + 个参数 | URL 长度有限制,可读性差 |
| 路径参数用动词 | axios.get('/api/v1/getUser/1001') | @GetMapping("/getUser/{userId}") | 违反 RESTful 规范,URI 仅表示资源 |
| 文件上传用 JSON | axios.post('/upload', { file: fileObj }) | 用 @RequestBody接收文件 | JSON 无法传输二进制文件 |
总结
- 核心匹配:路径参数→
@PathVariable、查询参数→@RequestParam、JSON→@RequestBody、文件→@RequestPart;
- 场景优先:查询用 GET(路径 / 查询参数),新增 / 修改 / 文件用 POST(JSON/FormData);
- 规范统一:参数名小驼峰、日期格式统一、响应体结构一致,前后端按表对齐即可避免 90% 的参数传递问题。
微信扫一扫,关注极客日志
微信公众号「极客日志」,在微信中扫描左侧二维码关注。展示文案:极客日志 zeeklog
相关免费在线工具
- Keycode 信息
查找任何按下的键的javascript键代码、代码、位置和修饰符。 在线工具,Keycode 信息在线工具,online
- Escape 与 Native 编解码
JavaScript 字符串转义/反转义;Java 风格 \uXXXX(Native2Ascii)编码与解码。 在线工具,Escape 与 Native 编解码在线工具,online
- JavaScript / HTML 格式化
使用 Prettier 在浏览器内格式化 JavaScript 或 HTML 片段。 在线工具,JavaScript / HTML 格式化在线工具,online
- JavaScript 压缩与混淆
Terser 压缩、变量名混淆,或 javascript-obfuscator 高强度混淆(体积会增大)。 在线工具,JavaScript 压缩与混淆在线工具,online
- Base64 字符串编码/解码
将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online
- Base64 文件转换器
将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online