Spring Boot @RestController
最后修改于 2023 年 7 月 18 日
Spring Boot @RestController 教程展示了如何在 Spring 应用程序中使用 @RestController 注解来构建一个 Restful 控制器。
Spring 是一个流行的 Java 应用程序框架,而 Spring Boot 是 Spring 的一个演进,它有助于轻松创建独立的、生产级的基于 Spring 的应用程序。
Spring MVC
Spring MVC 是基于 Servlet API 构建的主要 Web 框架。它是基于流行的 MVC 设计模式构建的。MVC (Model-View-Controller) 是一种软件架构模式,它将应用程序分为三个区域:模型、视图和控制器。模型表示一个携带数据的 Java 对象。视图表示模型包含的数据的可视化。控制器控制数据流到模型对象中,并在数据更改时更新视图。它分离了视图和模型。
Spring Framework 5.0 引入了一个并行的响应式栈 Web 框架,名为 Spring WebFlux。
@RestController
@RestController 是用于创建 Restful 控制器的便捷注解。它是 @Component 的一个特例,并通过类路径扫描自动检测。它添加了 @Controller 和 @ResponseBody 注解。它将响应转换为 JSON 或 XML。它不适用于视图技术,因此方法不能返回 ModelAndView。它通常与基于 @RequestMapping 注解的注解处理程序方法结合使用。
ResponseEntity 类表示一个 HTTP 响应,包括标头、主体和状态。它用于返回数据。
@Controller 注解与视图技术一起使用。
Restful 应用程序
一个 RESTFul 应用程序 遵循 REST 架构风格,该风格用于设计网络应用程序。RESTful 应用程序生成 HTTP 请求,对资源执行 CRUD(创建/读取/更新/删除)操作。RESTFul 应用程序通常以 JSON 或 XML 格式返回数据。
Spring Boot @RestController 示例
在以下应用程序中,我们演示了 @RestController 的用法。该应用程序以 JSON 数据的形式返回城市列表。
build.gradle ... src ├── main │ ├── java │ │ └── com │ │ └── zetcode │ │ ├── Application.java │ │ ├── controller │ │ │ └── MyController.java │ │ ├── model │ │ │ └── City.java │ │ └── service │ │ ├── CityService.java │ │ └── ICityService.java │ └── resources │ └── application.properties └── test
这是项目结构。
plugins {
id 'org.springframework.boot' version '3.1.1'
id 'io.spring.dependency-management' version '1.1.0'
id 'java'
}
group = 'com.zetcode'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '17'
repositories {
mavenCentral()
}
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-web'
}
这是 Gradle 构建文件。spring-boot-starter-web 是用于构建 Web 应用程序(包括 RESTful 应用程序)的启动器,使用 Spring MVC。
spring.main.banner-mode=off
这是主属性文件。
package com.zetcode.model;
public record City(Long id, String name, Integer population) {}
这是一个 City bean。它具有 id、name 和 population 属性。
package com.zetcode.controller;
import com.zetcode.model.City;
import com.zetcode.service.ICityService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
@RestController
public class MyController {
private final ICityService cityService;
@Autowired
public MyController(ICityService cityService) {
this.cityService = cityService;
}
@GetMapping(value = "/cities")
public ResponseEntity<List<City>> getCities() {
return cityService.findAll();
}
@GetMapping(value = "/cities/{id}")
public ResponseEntity<City> getCity(@PathVariable("id") int id) {
return cityService.findById(id);
}
}
这是 MyController。它以 JSON 格式返回城市列表。
@RestController
public class MyController {
MyController 使用 @RestController 注解进行注解。
private final ICityService cityService;
@Autowired
public MyController(ICityService cityService) {
this.cityService = cityService;
}
我们将 CityService 注入到 cityService 字段中。
@GetMapping(value = "/cities")
public ResponseEntity<List<City>> getCities() {
return cityService.findAll();
}
getCities 方法映射到 /cities URL 模式;它返回一个城市列表,该列表由消息转换器转换为 JSON。
@GetMapping(value = "/cities/{id}")
public ResponseEntity<City> getCity(@PathVariable("id") int id) {
return cityService.findById(id);
}
getCity 方法返回单个城市。
package com.zetcode.service;
import java.util.List;
import com.zetcode.model.City;
import org.springframework.http.ResponseEntity;
public interface ICityService {
ResponseEntity<List<City>> findAll();
ResponseEntity<City> findById(int id);
}
ICityService 包含 findAll 和 findById 契约方法。
package com.zetcode.service;
import com.zetcode.model.City;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.List;
@Service
public class CityService implements ICityService {
private final List<City> cities = new ArrayList<>();
public CityService() {
cities.add(new City(1L, "Bratislava", 432000));
cities.add(new City(2L, "Budapest", 1759000));
cities.add(new City(3L, "Prague", 1280000));
cities.add(new City(4L, "Warsaw", 1748000));
cities.add(new City(5L, "Los Angeles", 3971000));
cities.add(new City(6L, "New York", 8550000));
cities.add(new City(7L, "Edinburgh", 464000));
cities.add(new City(8L, "Berlin", 3671000));
}
@Override
public ResponseEntity<List<City>> findAll() {
return ResponseEntity.ok(cities);
}
public ResponseEntity<City> findById(int id) {
if (id < 0 || id >= cities.size()) {
return ResponseEntity.notFound().build();
}
return ResponseEntity.ok(cities.get(id));
}
}
CityService 包含 findAll 和 findById 方法的实现。
package com.zetcode;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
Application 是设置 Spring Boot 应用程序的入口点。
$ ./gradlew bootRun
我们运行应用程序。
$ curl localhost:8080/cities/2 -i
HTTP/1.1 200
Content-Type: application/json
Transfer-Encoding: chunked
Date: Wed, 19 Jul 2023 14:25:22 GMT
{"id":3,"name":"Prague","population":1280000}
$ curl localhost:8080/cities
[{"id":1,"name":"Bratislava","population":432000},{"id":2,"name":"Budapest","population":1759000},
{"id":3,"name":"Prague","population":1280000},{"id":4,"name":"Warsaw","population":1748000},
{"id":5,"name":"Los Angeles","population":3971000},{"id":6,"name":"New York","population":8550000},
{"id":7,"name":"Edinburgh","population":464000},{"id":8,"name":"Berlin","population":3671000}]
$ curl localhost:8080/cities/26 -i HTTP/1.1 404 Content-Length: 0 Date: Wed, 19 Jul 2023 14:26:24 GMT