java

关注公众号 jb51net

关闭
首页 > 软件编程 > java > java http请求

Java 后端HTTP 请求(GET/POST)传输规范

作者:凯qwq

文章详细阐述了RESTful API设计的最佳实践,涵盖了GET和POST请求的规范、参数传递、响应体、版本控制、日志记录等,本文介绍实例代码介绍了Java后端HTTP请求(GET/POST)传输规范,感兴趣的朋友一起看看吧

一、核心原则

  1. 遵循 “RESTful 风格”,URI 仅表示资源,HTTP 方法表示操作;
  2. GET 仅用于查询,禁止通过 GET 传递敏感数据;POST 用于新增 / 修改 / 删除,或传递大量 / 敏感数据;
  3. 所有接口参数、响应数据统一使用 UTF-8 编码,避免乱码。

二、GET 请求规范

1. 用途限制

2. 参数传递规则(Java 编码落地)

(1)路径参数(唯一标识)

// URI:GET /api/v1/users/1001
@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);
    }
}

(2)查询参数(筛选 / 分页 / 排序)

// URI:GET /api/v1/orders?status=PAID&pageNum=1&pageSize=10
@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)复杂查询参数(多个筛选条件)

// 封装查询DTO
@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. 长度与编码

server:
  tomcat:
    uri-encoding: UTF-8
spring:
  http:
    encoding:
      charset: UTF-8
      enabled: true
      force: true

4. 敏感数据禁止

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. 用途限制

2. 参数传递规则(Java 编码落地)

(1)JSON 参数(主流)

// 新增用户DTO(含参数校验)
@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, "新增用户成功");
}

(2)文件上传(multipart/form-data)

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)幂等性保障(新增接口)

@Transactional(rollbackFor = Exception.class)
public Long addOrder(OrderCreateReqDTO createDTO) {
    // 1. 校验订单号是否已存在(幂等核心)
    if (orderMapper.existsByOrderNo(createDTO.getOrderNo())) {
        throw new BusinessException("订单已存在,请勿重复提交");
    }
    // 2. 新增订单
    Order order = new Order();
    BeanUtils.copyProperties(createDTO, order);
    orderMapper.insert(order);
    return order.getId();
}

3. 特殊场景:POST 查询(敏感 / 大量参数)

// 复杂订单查询(参数多、含敏感条件)
@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 编码落地)

2. 响应规范(统一返回体)

@Data
public class ResultDTO<T> {
    // 状态码:200成功,400参数错误,403权限不足,500服务异常
    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 编码落地)

@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. 接口版本控制

五、反例与正例对照表(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 后端编码额外规范

  1. 请求头规范
    • 跨域请求:后端配置CorsConfig,允许前端的 Origin、Method、Header;
    • 认证请求:token 统一放在Authorization请求头,后端用@RequestHeader("Authorization") String token接收。
  2. 日志规范
    • 所有接口入参 / 出参必须打印日志(使用 SLF4J),禁止打印敏感数据(如密码);
    • ✅ 示例:
@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);
}
  1. 性能规范
    • GET 请求建议添加缓存(如 Redis),避免频繁查库;
    • POST 请求建议异步处理(如 MQ),耗时操作(如文件解析、数据同步)不阻塞接口响应。

总结

  1. 编码核心:GET 用@PathVariable/@RequestParam,POST 用@RequestBody,参数校验用 JSR380+@Valid
  2. 响应核心:所有接口统一返回ResultDTO,异常统一由GlobalExceptionHandler捕获;
  3. 安全核心:GET 禁止传敏感数据,POST 新增接口保证幂等,日志屏蔽敏感信息;
  4. 规范核心:URI 用小写复数名词 + 版本号,参数命名小驼峰,编码统一 UTF-8。
请求类型参数传递位置前端核心写法(示例)后端核心写法(Java)适用场景关键规范 / 注意事项
GETURL 路径参数axios.get('/api/v1/users/1001')@GetMapping("/{userId}")@PathVariable("userId") Long userId查询单个资源(如查用户 / 订单)1. 路径参数为唯一标识(ID / 编号)2. URI 用复数名词,小写
GETURL 查询参数axios.get('/api/v1/orders', { params: { status: 'PAID', pageNum: 1 } })@GetMapping("/orders")@RequestParam String status@RequestParam Integer pageNum列表筛选 / 分页 / 排序1. 参数名小驼峰2. 非必传参数加required = false3. 可封装为 DTO 用@ModelAttribute接收
POSTRequest 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
POSTForm 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-urlencoded2. 敏感数据建议转 JSON 传递
POSTMultipart 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. 通用数据格式

// 后端接收日期示例
@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 仅表示资源
文件上传用 JSONaxios.post('/upload', { file: fileObj })@RequestBody接收文件JSON 无法传输二进制文件

总结

  1. 核心匹配:路径参数→@PathVariable、查询参数→@RequestParam、JSON→@RequestBody、文件→@RequestPart
  2. 场景优先:查询用 GET(路径 / 查询参数),新增 / 修改 / 文件用 POST(JSON/FormData);
  3. 规范统一:参数名小驼峰、日期格式统一、响应体结构一致,前后端按表对齐即可避免 90% 的参数传递问题。

到此这篇关于Java 后端HTTP 请求(GET/POST)传输规范的文章就介绍到这了,更多相关java http请求内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文