SpringBoot系列06:RESTful接口开发,请求参数接收、全局跨域CORS完整配置
2026/7/7 14:21:08 网站建设 项目流程

SpringBoot系列06:RESTful接口开发,请求参数接收、全局跨域CORS完整配置

✅ 系列专栏:SpringBoot零基础进阶实战系列

✅ 适配版本:SpringBoot 3.x / Java 17+

✅ 核心亮点:零基础上手、全覆盖参数接收、三种全局CORS配置、生产级避坑、可直接复用

✅ 阅读收益:彻底掌握RESTful接口规范、所有请求参数接收场景、解决前后端99%跨域问题


一、前言:为什么必须学RESTful与CORS配置?

在前后端分离开发模式中,RESTful API是目前行业统一的接口设计规范,替代了传统杂乱的接口请求方式,让接口语义清晰、统一规范、易于维护。而CORS跨域问题是前后端联调的高频痛点,90%的接口联调报错都源于跨域配置不当。

本文将从零开始,手把手带大家实现标准RESTful接口开发 + 全场景请求参数接收 + 生产级全局CORS配置,摒弃零散代码,提供可直接用于项目的完整方案,同时解析底层原理和常见踩坑点。

本文核心知识点清单

  • RESTful API设计规范(四大HTTP方法对应增删改查)

  • SpringBoot五种核心请求参数接收方式(全覆盖业务场景)

  • 三种生产级全局CORS跨域配置方案(优先级对比、场景适配)

  • 跨域核心原理、常见报错原因与终极解决方案

  • 生产环境CORS安全配置避坑指南


二、RESTful API核心设计规范

RESTful(Representational State Transfer)即表述性状态转移,核心思想是用HTTP请求方法定义操作,用URL定义资源,URL只命名资源,不包含操作行为。

2.1 传统接口 vs RESTful接口对比

传统接口风格(不规范):

  • /user/add 新增用户

  • /user/delete 删除用户

  • /user/update 修改用户

  • /user/get 查询用户

RESTful规范风格(标准统一):

HTTP方法业务操作接口地址说明
GET查询资源/api/user查询用户列表
GET查询单资源/api/user/{id}根据ID查询单个用户
POST新增资源/api/user新增用户
PUT全量修改资源/api/user/{id}根据ID完整更新用户信息
PATCH局部修改资源/api/user/{id}局部更新用户字段
DELETE删除资源/api/user/{id}根据ID删除用户

2.2 RESTful核心约束

  1. 资源唯一:URL定位唯一资源,名词复数命名(user、order、goods)

  2. 方法语义化:严格遵循HTTP方法对应增删改查

  3. 无状态:服务器不存储客户端状态,每次请求独立

  4. 返回统一格式:统一JSON响应体,包含状态码、信息、数据


三、SpringBoot全场景请求参数接收实战

SpringBoot RESTful接口中,参数接收分为5种核心场景,覆盖所有业务开发需求,下面结合RESTful接口逐一实战演示,所有代码基于SpringBoot3可直接运行。

前置基础:RESTful接口统一控制器注解

// 组合注解 = @Controller + @ResponseBody,直接返回JSON数据@RestController@RequestMapping("/api/user")publicclassUserRestController{}

3.1 @PathVariable 路径参数(URL路径传参)

适用场景:查询单个资源、删除、修改(RESTful标准传参),参数拼接在URL路径中

请求示例:GET /api/user/1001

/** * 根据ID查询单个用户 * @param id 用户ID(路径参数) * @return 用户信息 */@GetMapping("/{id}")publicResultgetUserById(@PathVariableLongid){returnResult.success("查询成功","用户ID:"+id);}

进阶用法:多路径参数、参数别名、必填控制

// 多路径参数 + 别名映射 + 非必填@GetMapping("/{userId}/role/{roleId}")publicResultgetUserRole(@PathVariable("userId")Longuid,@PathVariable(required=false)LongroleId){returnResult.success("多参数查询成功","用户ID:"+uid+",角色ID:"+roleId);}

3.2 @RequestParam 查询参数(URL问号传参)

适用场景:列表查询、条件筛选、分页参数,参数拼接在URL?后

请求示例:GET /api/user/list?name=张三&page=1&size=10

/** * 用户条件分页查询 * @param name 用户名(非必填) * @param page 页码(默认1) * @param size 每页条数(默认10) * @return 分页数据 */@GetMapping("/list")publicResultgetUserList(@RequestParam(value="name",required=false,defaultValue="")Stringname,@RequestParam(defaultValue="1")Integerpage,@RequestParam(defaultValue="10")Integersize){Stringres=String.format("筛选用户:%s,页码:%d,条数:%d",name,page,size);returnResult.success("分页查询成功",res);}

核心参数说明

  • value:前端参数名与后端形参名不一致时做映射

  • required:是否必填,默认true

  • defaultValue:参数为空时默认值

3.3 @RequestBody JSON实体参数(POST/PUT核心)

适用场景:新增、修改接口,前端传递JSON格式请求体,最常用的传参方式

注意GET请求不支持@RequestBody,仅POST/PUT/PATCH可用

第一步:创建实体接收类

importlombok.Data;@DatapublicclassUserDTO{// 用户名privateStringusername;// 手机号privateStringphone;// 年龄privateIntegerage;}

第二步:编写新增接口

/** * 新增用户(JSON请求体传参) * @param userDTO 用户信息 * @return 新增结果 */@PostMappingpublicResultaddUser(@RequestBodyUserDTOuserDTO){returnResult.success("新增用户成功",userDTO);}

常见报错:415 Unsupported Media Type,原因:前端未设置Content-Type: application/json

3.4 @RequestHeader 请求头参数

适用场景:获取Token、请求设备信息、自定义请求头等

/** * 获取请求头中的Token * @param token 登录令牌 * @return 校验结果 */@GetMapping("/token")publicResultgetToken(@RequestHeader("Authorization")Stringtoken){returnResult.success("获取Token成功","令牌:"+token);}

3.5 普通表单参数(无注解接收)

适用场景:form表单提交,Content-Type: application/x-www-form-urlencoded

无需任何注解,直接通过形参接收,参数名与前端一致即可

@PostMapping("/form")publicResultformSubmit(Stringusername,Stringpassword){returnResult.success("表单提交成功","账号:"+username+",密码:"+password);}

3.6 统一响应结果封装(规范REST返回值)

为满足RESTful接口统一返回规范,封装通用Result工具类,所有接口统一返回格式:

importlombok.Data;@DatapublicclassResult<T>{// 响应码:200成功 500失败privateIntegercode;// 响应信息privateStringmsg;// 响应数据privateTdata;// 成功响应publicstatic<T>Result<T>success(Stringmsg,Tdata){Result<T>result=newResult<>();result.setCode(200);result.setMsg(msg);result.setData(data);returnresult;}// 失败响应publicstatic<T>Result<T>error(Stringmsg){Result<T>result=newResult<>();result.setCode(500);result.setMsg(msg);returnresult;}}

四、CORS跨域原理与报错原因

4.1 什么是跨域?

浏览器同源策略限制:协议、域名、端口三者任意一个不同,即为跨域,浏览器会拦截响应,抛出跨域报错。

同源判定规则:http://localhost:8080(后端)与 http://localhost:3000(前端)端口不同 = 跨域

4.2 常见跨域报错

Access to fetch at ‘xxx’ from origin ‘xxx’ has been blocked by CORS policy: No ‘Access-Control-Allow-Origin’ header is present on the requested resource.

核心原因:后端接口未配置跨域许可,未返回对应的跨域响应头。


五、三种生产级全局CORS配置方案(推荐收藏)

SpringBoot中跨域配置分为局部注解配置全局配置,局部配置仅对单个接口生效,企业项目统一使用全局配置,下面提供三种主流全局配置方案,适配不同场景。

5.1 方案一:实现WebMvcConfigurer(最推荐、轻量化)

适用场景:绝大多数SpringBoot项目,不影响SpringSecurity、拦截器等配置,优先级适中

核心优势:代码简洁、侵入性低、适配SpringBoot3

importorg.springframework.context.annotation.Configuration;importorg.springframework.web.servlet.config.annotation.CorsRegistry;importorg.springframework.web.servlet.config.annotation.WebMvcConfigurer;/** * 全局跨域配置(方案一:WebMvc配置) * 生产推荐:精准配置域名,禁止直接使用* */@ConfigurationpublicclassCorsConfigimplementsWebMvcConfigurer{@OverridepublicvoidaddCorsMappings(CorsRegistryregistry){// 匹配所有接口路径registry.addMapping("/**")// 允许跨域的前端域名(生产环境替换为真实前端地址,多个域名用逗号分隔).allowedOrigins("http://localhost:3000","http://127.0.0.1:3000")// 允许所有请求方法.allowedMethods("GET","POST","PUT","DELETE","OPTIONS")// 允许所有请求头.allowedHeaders("*")// 允许携带Cookie、Token凭证.allowCredentials(true)// 预检请求有效期1小时,减少OPTIONS请求次数.maxAge(3600);}}

5.2 方案二:注册CorsFilter过滤器(优先级最高、全局拦截)

适用场景:需要优先执行跨域配置、整合SpringSecurity、高并发项目

核心优势:过滤器层级最高,可解决拦截器、权限框架导致的跨域失效问题

importorg.springframework.context.annotation.Bean;importorg.springframework.context.annotation.Configuration;importorg.springframework.web.cors.CorsConfiguration;importorg.springframework.web.cors.UrlBasedCorsConfigurationSource;importorg.springframework.web.filter.CorsFilter;importjava.util.Arrays;/** * 全局跨域配置(方案二:CorsFilter过滤器) * 优先级高于WebMvc配置,适合整合权限框架的项目 */@ConfigurationpublicclassCorsFilterConfig{@BeanpublicCorsFiltercorsFilter(){CorsConfigurationconfig=newCorsConfiguration();// 允许的前端域名config.setAllowedOrigins(Arrays.asList("http://localhost:3000","http://127.0.0.1:3000"));// 允许请求方法config.setAllowedMethods(Arrays.asList("GET","POST","PUT","DELETE","OPTIONS"));// 允许请求头config.setAllowedHeaders(Arrays.asList("*"));// 允许携带凭证config.setAllowCredentials(true);// 预检请求缓存时间config.setMaxAge(3600L);// 匹配所有接口UrlBasedCorsConfigurationSourcesource=newUrlBasedCorsConfigurationSource();source.registerCorsConfiguration("/**",config);returnnewCorsFilter(source);}}

5.3 方案三:yml配置文件极简配置(快速开发)

适用场景:本地开发、快速测试,不推荐生产使用(灵活性差)

在application.yml中直接添加配置:

# 全局跨域配置spring:web:cors:allowed-origins:http://localhost:3000allowed-methods:GET,POST,PUT,DELETE,OPTIONSallowed-headers:*allow-credentials:truemax-age:3600

5.4 局部跨域配置(了解即可)

通过@CrossOrigin注解,作用于类或方法,仅对当前接口生效:

@RestController@RequestMapping("/api/user")@CrossOrigin(origins="http://localhost:3000")publicclassUserRestController{// 所有接口自动跨域}

六、生产环境CORS核心避坑指南(必看)

6.1 禁止使用 allowedOrigins(“*”)

致命错误:开启allowCredentials(true)时,不能配置*通配符,会直接报错!

原因:浏览器安全机制,允许携带Cookie时,必须指定具体域名,不允许全局开放

生产方案:枚举所有前端合法域名,或通过配置文件动态读取

6.2 OPTIONS预检请求403报错

复杂请求(带Token、自定义请求头)会先发OPTIONS预检请求,必须手动放行OPTIONS方法,否则权限框架会拦截

6.3 配置优先级规则

CorsFilter过滤器 > @CrossOrigin注解 > WebMvc全局配置 > yml配置

项目中只保留一种全局配置,多配置共存会导致跨域失效、冲突报错

6.4 跨域失效常见原因

  • SpringSecurity未放行OPTIONS请求

  • 自定义拦截器在跨域过滤器之前执行

  • 配置类未加@Configuration注解,未生效

  • 前后端端口、域名匹配错误

  • URL拼写格式错误:配置前端跨域域名时,禁止出现多余引号、空格、非法字符(如 `http://127.0.0.1:3000"` 错误格式),URL末尾不能带双引号、逗号等冗余字符,会直接导致跨域配置解析失败、前端请求跨域报错

  • 域名协议不匹配:后端配置http协议,前端使用https协议,或反之,引发跨域拦截

  • SpringSecurity未放行OPTIONS请求

  • 自定义拦截器在跨域过滤器之前执行

  • 配置类未加@Configuration注解,未生效

  • 前后端端口、域名匹配错误


七、完整项目测试流程

  1. 启动SpringBoot项目,端口8080

  2. 使用Postman/Apifox测试所有RESTful接口

  3. 启动前端项目(3000端口),调用后端接口,跨域问题彻底解决

  4. 所有参数接收场景均可正常解析,返回统一JSON格式


八、总结与下期预告

本文总结

  1. 掌握RESTful标准化接口设计,告别杂乱接口风格

  2. 吃透5种请求参数接收方式,覆盖100%业务传参场景

  3. 掌握3种生产级全局CORS配置,解决所有跨域问题

  4. 熟悉生产环境跨域避坑要点,规避线上故障

下期预告

SpringBoot系列07:全局异常处理+统一返回结果封装,彻底消灭接口杂乱报错


💡 博主寄语

RESTful接口开发和跨域配置是SpringBoot前后端分离的基础必修课,看似简单但极易踩坑。建议大家收藏本文,项目中直接复用配置,规范代码风格,提升开发效率。

码字不易,点赞关注持续更新SpringBoot干货!有问题评论区交流,秒回!

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询