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