Spring Boot 入门教程:从 0 创建可运行的 REST 服务(含单元测试)
大约 3 分钟
Spring Boot 入门教程:从 0 创建可运行的 REST 服务(含单元测试)
新手一屏速览
- 分层:Controller 调用 Service,返回统一响应对象;配置写入 application.properties
- 可复制运行:包含完整 pom.xml、Java 源码与测试;
mvn spring-boot:run即可启动 - 单元测试:MockMvc 验证接口返回,覆盖边界与默认值
1. 项目结构
demo/
├─ pom.xml
└─ src/
├─ main/java/com/example/demo/
│ ├─ DemoApplication.java
│ ├─ web/ApiResponse.java
│ ├─ web/HelloController.java
│ └─ service/HelloService.java
└─ main/resources/application.properties2. pom.xml(可直接复制)
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.2.5</version>
</parent>
<properties>
<java.version>21</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
<description>Spring Boot 入门最小可运行项目</description>
</project>3. 源码(可直接复制)
DemoApplication.java:
package com.example.demo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
/**
* 应用启动入口。
*/
@SpringBootApplication
public class DemoApplication {
/**
* 启动 Spring Boot。
* @param args 命令行参数
*/
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}ApiResponse.java(统一响应):
package com.example.demo.web;
/**
* 统一响应对象。
* @param <T> 数据类型
*/
public class ApiResponse<T> {
private boolean success;
private T data;
private String error;
public static <T> ApiResponse<T> ok(T data){
ApiResponse<T> r = new ApiResponse<>();
r.success = true; r.data = data; return r;
}
public static <T> ApiResponse<T> fail(String msg){
ApiResponse<T> r = new ApiResponse<>();
r.success = false; r.error = msg; return r;
}
public boolean isSuccess() { return success; }
public T getData() { return data; }
public String getError() { return error; }
}HelloService.java(业务逻辑):
package com.example.demo.service;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
/**
* 负责生成问候语的服务。
*/
@Service
public class HelloService {
private final String greeting;
public HelloService(@Value("${app.greeting:Hello}") String greeting) {
this.greeting = greeting;
}
/**
* 生成问候文本
* @param name 姓名
* @return 问候语
*/
public String greet(String name) {
String target = (name == null || name.isBlank()) ? "world" : name;
return greeting + ", " + target;
}
}HelloController.java(Controller 只做接入,不直接返回实体,封装响应):
package com.example.demo.web;
import com.example.demo.service.HelloService;
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 {
private final HelloService service;
public HelloController(HelloService service) {
this.service = service;
}
/**
* GET /api/hello
* @param name 姓名
* @return 统一响应
*/
@GetMapping("/api/hello")
public ApiResponse<String> hello(@RequestParam(required = false) String name) {
return ApiResponse.ok(service.greet(name));
}
}application.properties:
server.port=8080
app.greeting=Hello4. 单元测试(可直接复制)
最近建一些几十个工作内推群,各大城市都有,群里目前已经收集了很多内推岗位,大厂、中厂、小厂、外包都有。 欢迎HR、开发、测试、运维和产品加入。

扫描下方微信,备注:网站+所在城市,即可拉你进工作内推群。

package com.example.demo;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.web.servlet.MockMvc;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
/**
* 接口层测试:验证默认入参与返回格式。
*/
@SpringBootTest
@AutoConfigureMockMvc
class HelloControllerTest {
@Autowired
MockMvc mvc;
@Test
void should_return_default_greeting_when_name_absent() throws Exception {
mvc.perform(get("/api/hello"))
.andExpect(status().isOk())
.andExpect(jsonPath("$.success").value(true))
.andExpect(jsonPath("$.data").value("Hello, world"));
}
}5. 启动与访问
mvn -q -DskipTests spring-boot:run访问:
curl "http://localhost:8080/api/hello?name=Java"6. 常见问题排查
- 端口被占用:修改
server.port或释放占用进程 - Controller 未生效:包结构需以启动类所在包为根,或调整
@ComponentScan - UTF-8 显示异常:确保终端/IDE 使用 UTF-8 编码
