☰
SpringBoot入门实战:STS从零搭建REST接口与避坑指南
2026/10/15 1:21:35 网站建设 项目流程

1. 为什么一个老框架还值得从头搭一遍

SpringBoot 这个名词在 Java 后端圈子里已经不算新鲜了,但每年仍然有大量新入行的开发者、从其他语言转过来的工程师、以及需要维护遗留系统的同学,需要重新走一遍"从零搭建一个能跑起来的 SpringBoot 工程"这条路。我见过太多人卡在第一步——不是卡在代码逻辑上,而是卡在"工具装好了,项目建不出来"这种环境层面的问题上。尤其是用 STS(Spring Tool Suite)这套 IDE 的人,网上教程要么版本太老,要么跳步严重,照着做十有八九会报错。

这篇内容就是来解决这个问题的。我会把 SpringBoot 的核心定位讲清楚,然后手把手带你在 STS 里建出一个能返回 JSON 数据的 REST 接口,最后把新手最容易踩的那几个坑一个个拆开讲。适合谁看?如果你刚接触 Java Web 开发,或者之前用传统 SSM 框架被 XML 配置折磨过,又或者你只是想把 STS 这个工具用顺手,那这篇内容对你有直接帮助。关键词就三个:SpringBoot、STS、入门案例,但我会把这三个词背后的东西讲透,而不是给你一堆复制粘贴的代码就完事。

先说一个反直觉的结论:SpringBoot 最大的价值不是"简化配置",而是"约定了一套默认行为,让你在绝大多数场景下不需要做选择"。传统 Spring 项目里,你要选 DispatcherServlet 怎么配、视图解析器用哪个、数据源怎么连、事务管理器怎么声明,每一个选择都要写 XML 或者 Java Config。SpringBoot 的做法是:我替你选好了,你如果没意见就直接用,有意见再覆盖。这个思路听起来简单,但它直接决定了你搭项目的方式——你不需要从零配置,你只需要在默认基础上做减法或加法。

STS 这个工具,本质上是 Eclipse 加了一堆 Spring 相关的插件。它的好处是对 SpringBoot 的支持是原生的,新建项目向导里直接有 Spring Starter Project 这个选项,依赖勾选界面也比手动改 pom.xml 直观。坏处是它基于 Eclipse,很多 IDEA 用户转过来会不适应,而且 STS 的版本和 SpringBoot 版本之间有兼容性要求,选错了就是一堆红叉。下面我从环境准备开始,一步步来。

2. STS 环境准备里那些没人告诉你的细节

2.1 JDK 版本的选择不是越新越好

SpringBoot 2.x 和 3.x 对 JDK 的要求完全不同。2.x 最低 JDK 8,3.x 最低 JDK 17。你在 STS 里建项目之前,先确认自己机器上装的是哪个版本的 JDK。命令行敲java -version看一眼,输出里如果显示 1.8 开头,那就是 JDK 8;显示 17 或者 21,那就是高版本。

这里有个坑:STS 本身也是一个 Java 程序,它启动的时候用的 JDK 和你项目编译用的 JDK 可以是两个。很多人装了 JDK 17,但 STS 启动时用的还是内置的 JRE,结果建项目的时候编译器合规级别对不上,代码里全是红波浪线。解决办法是在 STS 的偏好设置里,找到 Java 下面的 Installed JREs,把你自己装的 JDK 加进去并设为默认。这一步不做,后面编译报错你都不知道去哪查。

我个人的建议是:如果你是新学,直接用 JDK 17 加 SpringBoot 3.x,这是当前的主流组合,社区支持最好。如果你是要维护老项目,那就 JDK 8 加 SpringBoot 2.7.x,别混着来。版本对应关系搞错了,不是改一行配置能解决的,是整个依赖树都要重来。

2.2 STS 下载与安装的版本匹配问题

STS 的下载页面会列出多个版本,每个版本对应不同的 Eclipse 基础版本。你不需要追最新,但要注意一点:STS 4.x 系列从某个版本开始只支持 SpringBoot 2.5 以上。如果你要建 SpringBoot 2.3 的项目,就得用老一点的 STS。这个信息在下载页面的 release notes 里有,但很多人不看,装完了发现新建项目向导里选不了低版本,又回来重装。

安装过程本身没什么好说的,解压就能用,不需要安装程序。但 Windows 上如果解压路径里有中文或者空格,启动可能会出问题。我一般建议解压到类似D:\devtools\sts这种纯英文无空格的路径下。Mac 用户直接把 app 拖到 Applications 里就行,但第一次打开可能会提示"无法验证开发者",去安全性与隐私里允许一下就好。

启动之后,STS 会问你工作空间放哪。工作空间路径同样建议纯英文,而且不要放在 C 盘用户目录下,因为那个目录有时候会有权限问题,导致 Maven 下载依赖的时候写不进去。我自己的习惯是在 D 盘建一个workspace-sts目录专门放项目。

2.3 Maven 配置:别用默认的中央仓库

STS 内置了 Maven,但默认用的是 Maven 中央仓库。国内访问中央仓库的速度,用过的人都知道,下载一个 SpringBoot 项目的基础依赖可能要等十几分钟,有时候还会超时失败。所以第一件事是配置国内镜像。

找到 Maven 的 settings.xml 文件。如果你用的是 STS 内置的 Maven,位置在 STS 安装目录下的plugins/org.apache.maven...里面,具体路径每个版本不太一样。更简单的做法是自己装一个独立 Maven,然后在 STS 里指定用这个外部 Maven。在偏好设置里找到 Maven 下面的 Installations,Add 一个你自己的 Maven 目录,勾选上。

然后在 settings.xml 的<mirrors>标签里加一个国内镜像。具体用哪家我就不点名了,你搜"maven 国内镜像"能找到一堆,选一个稳定的就行。配置完之后在 STS 里右键项目,Maven 下面有个 Update Project,强制更新一下,依赖下载速度会有质的提升。

注意:镜像配置改完之后,如果之前已经下载了一半的依赖,最好把本地仓库里对应的目录删掉重新下,否则可能出现 jar 包不完整的情况,编译时报 ClassNotFound 但你又找不到原因。

3. 用 Spring Starter Project 向导建工程的完整流程

3.1 新建向导里每一项到底在填什么

在 STS 里点 File -> New -> Spring Starter Project,会弹出一个向导。第一页要填的东西看起来多,其实就几类:项目基本信息、构建方式、语言、打包方式、Java 版本、依赖选择。

Name 就是项目名,我一般用全小写加连字符,比如demo-springboot。Type 选 Maven 还是 Gradle,新手直接用 Maven,资料多,出问题好搜。Packaging 选 Jar,SpringBoot 内置了 Tomcat,不需要打成 War 包部署到外部容器。Java Version 选你 JDK 对应的版本,前面确认过了就按那个填。

Group 和 Artifact 是 Maven 坐标,Group 一般填公司或组织的反向域名,个人项目随便填个com.example就行。Artifact 和 Name 保持一致。Package 是基础包名,SpringBoot 的自动扫描是从这个包往下扫的,所以你的所有代码都要放在这个包或者它的子包下面,放到外面就不会被扫描到,这是新手最常见的错误之一。

3.2 依赖勾选:只选你真正需要的

向导第二页是依赖选择。左边按类别分,右边是你选中的。新手最容易犯的错是"全选",觉得多选点没坏处。实际上依赖选多了,项目启动变慢,而且不同依赖之间可能有版本冲突,报错信息你根本看不懂。

一个最基础的 REST 接口项目,只需要勾两个:Spring Web 和 Spring Boot DevTools。Spring Web 提供了内嵌 Tomcat 和 Spring MVC 的全部能力,DevTools 提供了热部署,改完代码不用手动重启。如果你后面要连数据库,再加 Spring Data JPA 和对应的数据库驱动。要用模板引擎渲染页面,再加 Thymeleaf。要用安全控制,再加 Spring Security。按需加,别贪多。

选完之后点 Finish,STS 会开始生成项目结构并下载依赖。第一次建项目,依赖下载可能要几分钟,看你的网络和镜像配置。下载过程中底部进度条会动,如果卡住不动了,大概率是镜像没配好或者网络有问题。

3.3 生成出来的项目结构逐层解读

项目建好之后,在 Package Explorer 里展开,你会看到这样的结构:

demo-springboot ├── src/main/java │ └── com.example.demo │ └── DemoSpringbootApplication.java ├── src/main/resources │ ├── static │ ├── templates │ └── application.properties ├── src/test/java │ └── com.example.demo │ └── DemoSpringbootApplicationTests.java ├── target ├── mvnw ├── mvnw.cmd └── pom.xml

DemoSpringbootApplication.java是启动类,里面有一个main方法,直接右键 Run As -> Spring Boot App 就能启动整个项目。这个类上面的@SpringBootApplication注解是核心,它其实是三个注解的组合:@Configuration声明这是一个配置类,@EnableAutoConfiguration开启自动配置,@ComponentScan开启组件扫描。三个合在一起,才有了"一个注解启动整个应用"的效果。

application.properties是全局配置文件,你后面要改端口、配数据库连接、设日志级别,都在这里改。static目录放静态资源,比如 HTML、CSS、JS 文件,SpringBoot 会自动把它们映射到根路径下。templates目录放模板文件,配合 Thymeleaf 这类模板引擎使用。pom.xml是 Maven 的依赖配置文件,你后面加依赖、改版本,都在这里操作。

mvnw和mvnw.cmd是 Maven Wrapper,作用是让你在没装 Maven 的机器上也能构建项目。这两个文件可以不管,但别删,有些 CI 环境会用到。

4. 第一个 REST 接口:从写代码到验证的完整链路

4.1 控制器类的写法与注解含义

在com.example.demo包下面新建一个包叫controller,然后在里面新建一个类叫HelloController。代码长这样:

package com.example.demo.controller; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; @RestController public class HelloController { @GetMapping("/hello") public String sayHello(@RequestParam(value = "name", defaultValue = "World") String name) { return "Hello, " + name + "!"; } }

@RestController这个注解等于@Controller加@ResponseBody。它的意思是:这个类里所有方法的返回值都直接作为 HTTP 响应体返回,而不是被当成视图名称去解析模板。如果你只想返回 JSON 数据,就用这个注解。如果你要返回一个 HTML 页面,那就用@Controller,然后在方法里返回视图名。

@GetMapping("/hello")声明了这个方法处理的是 GET 请求,路径是/hello。SpringBoot 启动后,内嵌的 Tomcat 默认监听 8080 端口,所以你访问的完整地址是http://localhost:8080/hello。

@RequestParam用来接收 URL 上的查询参数。value = "name"表示参数名叫 name,defaultValue = "World"表示如果请求里没带这个参数,就用 "World" 作为默认值。所以你不带参数访问,返回的是 "Hello, World!";带上?name=张三,返回的就是 "Hello, 张三!"。

4.2 启动类的运行方式与端口修改

回到DemoSpringbootApplication.java,右键 -> Run As -> Spring Boot App。控制台会输出一堆日志,最后看到类似这样的行,就说明启动成功了:

Tomcat started on port(s): 8080 (http) with context path '' Started DemoSpringbootApplication in 2.345 seconds (JVM running for 3.123)

如果 8080 端口被占用了,启动会报Port 8080 was already in use。解决办法有两个:一是把占用端口的程序关掉,二是改 SpringBoot 的端口。改端口在application.properties里加一行:

server.port=8081

改完保存,DevTools 会自动重启应用,新端口就生效了。这个属性是 SpringBoot 自动配置提供的,你不需要写任何 Java 代码去读它,框架自己会处理。

4.3 用浏览器和命令行两种方式验证接口

启动成功后,打开浏览器访问http://localhost:8080/hello,页面上应该显示Hello, World!。再访问http://localhost:8080/hello?name=SpringBoot,显示Hello, SpringBoot!。

命令行验证用 curl:

curl http://localhost:8080/hello curl "http://localhost:8080/hello?name=SpringBoot"

注意第二个命令里的 URL 带了查询参数,在有些 shell 里?和&有特殊含义,所以要用引号包起来。Windows 的 cmd 里 curl 的引号处理不太一样,建议用 PowerShell 或者 Git Bash。

如果你返回的是一个对象而不是字符串,SpringBoot 会自动用 Jackson 把对象序列化成 JSON。比如你把返回值改成Map<String, Object>,浏览器里看到的就是 JSON 格式的数据。这个自动序列化的能力是 SpringBoot 自动配置里HttpMessageConverters提供的,你不需要手动配 Jackson 的 ObjectMapper。

5. 新手最容易踩的五个坑及排查思路

5.1 包扫描不到:控制器写了但访问 404

这是最高频的问题。现象是:代码明明写了,启动也没报错,但访问接口就是 404。原因几乎只有一个——控制器类不在启动类所在包或者其子包下面。SpringBoot 的@ComponentScan默认只扫描启动类所在包及其子包。如果你的启动类在com.example.demo,控制器在com.example.controller,那就扫不到。

排查方法很简单:看一眼两个类的 package 声明,确认控制器包是启动类包的子包。比如启动类在com.example.demo,控制器在com.example.demo.controller,这是对的。如果控制器在com.example.demo的兄弟包下面,那就扫不到。解决办法是把控制器移到正确的包下面,或者在启动类上手动加@ComponentScan(basePackages = {"com.example.demo", "com.example.controller"})。但后者不推荐,包结构混乱后面会越来越难维护。

5.2 依赖冲突:NoSuchMethodError 和 ClassNotFoundException

SpringBoot 的依赖管理是通过spring-boot-starter-parent里的dependencyManagement来统一版本的。你引入的第三方库如果和 SpringBoot 管理的版本不一致,就可能出现运行时找不到方法或者找不到类的错误。

排查这类问题的第一步是看pom.xml里有没有手动指定版本号。如果你引入了一个 Spring 生态的库,但手动写了 version,而这个 version 和 SpringBoot 管理的版本不一致,就会冲突。解决办法是把 version 去掉,让 SpringBoot 的父 POM 来管理。如果必须指定版本,那就要确认这个版本和当前 SpringBoot 版本兼容。

第二步是用mvn dependency:tree命令打印依赖树,看看同一个 artifact 是不是出现了多个版本。如果有,用<exclusions>把不需要的那个版本排除掉。这个命令在 STS 里也可以跑:右键项目 -> Run As -> Maven build,在 Goals 里填dependency:tree。

5.3 配置文件不生效:application.properties 改了没反应

有时候你改了application.properties里的配置,但应用启动后行为没变。原因可能是:文件位置不对、文件名拼错了、或者有多个配置文件优先级搞混了。

SpringBoot 默认加载src/main/resources/application.properties或者application.yml。如果你把文件放在了src/main/java下面,那肯定不生效。文件名必须是application,后缀是.properties或.yml,写成application.properties.txt这种也不行,Windows 默认隐藏扩展名,很容易犯这个错。

另外,SpringBoot 支持多环境配置,比如application-dev.properties、application-prod.properties。如果你在application.properties里写了spring.profiles.active=dev,那实际生效的是application-dev.properties里的配置。如果你改的是application.properties但激活的是 dev,那改了也没用。排查的时候先确认当前激活的是哪个 profile。

5.4 热部署不生效:改了代码还要手动重启

DevTools 的热部署不是万能的。它的原理是监测 classpath 下的文件变化,如果有变化就触发一次快速重启。但有两种情况它不会生效:一是你改的是pom.xml里的依赖,这需要完整重启;二是你改的是静态资源以外的配置文件,有时候也需要手动重启。

另外,DevTools 在 IDEA 里需要额外配置才能生效,但在 STS 里默认就是开着的。如果你在 STS 里发现改了代码没反应,先确认 DevTools 依赖加上了,然后看控制台有没有输出 "Restarting due to..." 这样的日志。如果没有,可能是自动构建没开。在 Project 菜单里勾上 Build Automatically,这样保存文件的时候 STS 会自动编译,DevTools 才能监测到变化。

5.5 启动报错但日志太长找不到重点

SpringBoot 启动失败的时候,控制台会打印一大堆日志,新手往往不知道从哪看起。我的经验是:直接翻到最下面,找APPLICATION FAILED TO START这个标题,下面会有一段Description和一段Action。Description 告诉你出了什么问题,Action 告诉你该怎么解决。

比如最常见的Port 8080 was already in use,Description 会写 "The Tomcat connector configured to listen on port 8080 failed to start",Action 会写 "Verify the connector's configuration, identify and stop any process that's listening on port 8080, or configure this application to listen on another port"。照着 Action 做就行了。

如果日志里没有这个标题,那就往上翻,找第一个Caused by开头的行,那才是真正的错误原因。前面的异常信息往往只是包装,真正的根因在Caused by后面。

6. 从入门案例延伸到实际开发的几个方向

6.1 把返回字符串改成返回 JSON 对象

实际开发中,接口几乎不会直接返回字符串,而是返回结构化的 JSON。你只需要把控制器方法的返回值改成一个对象或者 Map,SpringBoot 会自动序列化。比如定义一个简单的响应类:

public class ApiResponse { private int code; private String message; private Object data; public ApiResponse(int code, String message, Object data) { this.code = code; this.message = message; this.data = data; } // getter 和 setter 省略 }

然后控制器方法返回new ApiResponse(200, "success", someData),浏览器里看到的就是{"code":200,"message":"success","data":...}。这个过程中你不需要引入任何额外的 JSON 库,SpringBoot 的 web starter 里已经包含了 Jackson。

6.2 用 application.yml 替代 properties 的取舍

application.properties是键值对形式,application.yml是缩进层级形式。两者功能完全一样,选哪个看个人习惯。yml 的好处是层级关系直观,配置多的时候看起来更清晰;坏处是缩进敏感,多一个空格少一个空格都可能出错,而且从其他地方复制配置过来容易格式错乱。

我的建议是:配置项少的时候用 properties,简单直接;配置项多、有嵌套结构的时候用 yml,可读性更好。但一个项目里最好只用一种,不要两个文件同时存在,否则优先级问题会让你很头疼。SpringBoot 默认 properties 的优先级高于 yml,两个文件同时存在时,properties 里的配置会覆盖 yml 里的同名配置。

6.3 日志配置:别再用 System.out.println

入门阶段用System.out.println打印信息没问题,但实际项目里一定要用日志框架。SpringBoot 默认集成了 Logback,你只需要在类里声明一个 logger 就能用:

import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class HelloController { private static final Logger logger = LoggerFactory.getLogger(HelloController.class); @GetMapping("/hello") public String sayHello(@RequestParam(value = "name", defaultValue = "World") String name) { logger.info("收到请求,name={}", name); return "Hello, " + name + "!"; } }

日志级别可以在application.properties里调整,比如logging.level.com.example.demo=DEBUG把指定包的日志级别调到 DEBUG。生产环境一般用 INFO 级别,开发环境用 DEBUG 级别,排查问题的时候可以临时调到 TRACE。

6.4 打包部署:jar 包和 war 包的选择

SpringBoot 默认打包成可执行 jar,里面内嵌了 Tomcat,直接用java -jar xxx.jar就能运行。这是最推荐的方式,部署简单,不依赖外部容器。如果你必须部署到外部的 Tomcat 里,那就改成 war 包,但需要修改启动类继承SpringBootServletInitializer并重写configure方法,同时把spring-boot-starter-tomcat的 scope 改成provided。

打包命令是mvn clean package,在 STS 里可以右键项目 -> Run As -> Maven build,Goals 填clean package。打出来的 jar 包在target目录下,文件名一般是项目名-版本号.jar。运行的时候如果内存不够,可以加 JVM 参数:java -Xms256m -Xmx512m -jar xxx.jar。

7. 我在这套流程里积累的几个实操心得

第一个心得是关于 STS 的工作空间。很多人喜欢把所有项目放在一个工作空间里,时间长了工作空间里几十个项目,STS 启动越来越慢,有时候还会因为某个项目的编译错误导致整个工作空间卡死。我的做法是:一个工作空间只放当前正在开发的项目,做完一个换一个工作空间。切换工作空间在 File -> Switch Workspace 里操作,虽然麻烦一点,但能保持 IDE 的响应速度。

第二个心得是关于 Maven 的本地仓库。默认的本地仓库在用户目录下的.m2/repository,时间长了会积累大量旧版本的 jar 包,占用几个 G 的空间。我一般会定期清理,把那些明显不再使用的版本删掉。但注意不要全删,删了之后重新下载很费时间。可以按最后修改时间排序,把半年前以上的旧版本清理掉。

第三个心得是关于启动类的放置位置。我见过有人把启动类放在src/main/java根目录下,没有 package 声明,结果所有控制器都扫不到。启动类一定要放在一个有明确包名的包下面,而且这个包应该是你项目的基础包。比如你的项目叫order-system,那基础包可以是com.example.order,启动类放在这个包下,控制器放在com.example.order.controller,服务层放在com.example.order.service,这样结构清晰,扫描也不会出问题。

第四个心得是关于错误信息的搜索技巧。SpringBoot 的报错信息有时候很长,直接复制整段去搜往往搜不到有用的结果。我的做法是:只复制Caused by后面那一行,去掉具体的类名和路径,保留异常类型和关键描述。比如Caused by: java.lang.ClassNotFoundException: com.mysql.cj.jdbc.Driver,搜索的时候搜 "ClassNotFoundException com.mysql.cj.jdbc.Driver" 就能找到一堆解决方案,基本都是缺少 MySQL 驱动依赖或者驱动版本不对。

第五个心得是关于版本升级。SpringBoot 的版本迭代很快,但不要盲目追新。新版本发布后,至少等一两个小版本再升级,因为刚发布的大版本往往有兼容性问题。升级之前先看官方发布的 migration guide,里面会列出所有不兼容的变更点。升级的时候先在一个分支上做,跑通所有测试再合并到主分支。我见过太多人直接在主分支上升级,结果项目跑不起来,回滚又回不干净,折腾半天。

这套从 STS 建项目到跑通 REST 接口的流程,看起来步骤不多,但每一步都有细节。环境准备阶段把 JDK、Maven、STS 三者的版本关系理顺,建项目阶段把包结构和依赖选对,写代码阶段把注解含义搞清楚,排查问题阶段学会看日志和搜索,这四件事做到位,SpringBoot 的入门就算真正过了。后面要深入的话,方向很多——数据访问、安全控制、微服务、消息队列,但那些都是在这个基础之上叠加的。基础不牢,后面每加一个东西都是新的坑。

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

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

立即咨询