Spring Boot @ResponseBody
最后修改于 2023 年 7 月 16 日
在 Spring Boot @ResponseBody 教程中,我们将使用 Spring @ResponseBody
注解在控制器中将数据写入响应对象的正文。
Spring 是一个流行的 Java 应用程序框架,而 Spring Boot 是 Spring 的一个演进,它有助于轻松创建独立的、生产级别的基于 Spring 的应用程序。
WebJars 是打包成 JAR 文件的客户端 Web 库(例如 jQuery 或 Bootstrap)。它们允许在 Java Web 应用程序中轻松管理客户端依赖项。
JQuery 是一个流行的开源 JavaScript 库,旨在简化 HTML 的客户端脚本编写。
Spring @ResponseBody
@ResponseBody 是一个 Spring 注解,它将方法返回值绑定到 Web 响应体。它不会被解释为视图名称。它使用 HTTP 消息转换器将返回值转换为 HTTP 响应体,具体取决于请求 HTTP 标头中的 content-type。
Spring @ResponseBody 示例
以下示例创建一个 Spring Boot Web 应用程序,该应用程序将 JSON 数据返回给客户端。主页由 MVC 机制处理;FreeMarker 用于创建主页的模板。主页包含一个按钮,该按钮发送一个请求以获取 JSON 数据。Spring Boot Web 应用程序借助 @ResponseBody
注解以 JSON 格式发送数据。
build.gradle ... src ├── main │ ├── java │ │ └── com │ │ └── zetcode │ │ ├── Application.java │ │ ├── controller │ │ │ └── MyController.java │ │ ├── model │ │ │ └── City.java │ │ └── service │ │ ├── CityService.java │ │ └── ICityService.java │ └── resources │ └── templates │ └── index.ftlh └── test ├── java └── resources
这是应用程序的项目结构。
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' implementation 'org.springframework.boot:spring-boot-starter-web' implementation 'org.springframework.boot:spring-boot-starter-freemarker' implementation 'org.webjars:webjars-locator:0.45' implementation 'org.webjars:jquery:3.6.0' }
spring-boot-starter-freemarker
是一个使用 FreeMarker 视图构建 Spring MVC Web 应用程序的启动器。我们使用一个 Webjar 来获取 JQuery。 webjars-locator
自动解析任何 WebJars 资产的版本。 应用程序被打包成一个 JAR 文件,并使用 Tomcat 作为嵌入式 Web 服务器。
package com.zetcode.model; import java.util.Objects; public class City { private Long id; private String name; private int population; public City() { } public City(Long id, String name, int population) { this.id = id; this.name = name; this.population = population; } public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getPopulation() { return population; } public void setPopulation(int population) { this.population = population; } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; City city = (City) o; return population == city.population && Objects.equals(id, city.id) && Objects.equals(name, city.name); } @Override public int hashCode() { return Objects.hash(id, name, population); } @Override public String toString() { final StringBuilder sb = new StringBuilder("City{"); sb.append("id=").append(id); sb.append(", name='").append(name).append('\''); sb.append(", population=").append(population); sb.append('}'); return sb.toString(); } }
这是 City
bean。它具有 id
、name
和 population
属性。
package com.zetcode.service; import com.zetcode.model.City; import java.util.List; public interface ICityService { List<City> findAll(); }
ICityService
包含获取所有城市的契约方法。
package com.zetcode.service; import com.zetcode.model.City; import org.springframework.stereotype.Service; import java.util.ArrayList; import java.util.List; @Service public class CityService implements ICityService { @Override public List<City> findAll() { var cities = new ArrayList<City>(); 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)); return cities; } }
CityService
返回八个城市对象。
package com.zetcode.controller; import com.zetcode.bean.City; import com.zetcode.service.ICityService; import java.util.List; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; @Controller public class MyController { @Autowired ICityService cityService; @RequestMapping(path = "/") public String index() { return "index"; } @RequestMapping(path = "/GetCities", produces = "application/json; charset=UTF-8") @ResponseBody public List<City> findCities() { var cities = (List<City>) cityService.findAll(); return cities; } }
控制器有两个方法。 index
方法返回主页的视图。 findCities
方法以 JSON 数据的形式返回城市列表。
@Controller public class MyController {
@Controller
注解表示我们有一个控制器类。
@RequestMapping(path = "/") public String index() { return "index"; }
index
方法返回 index
字符串,该字符串解析为 index.ftlh
视图。该视图位于 src/main/resources/templates
目录中。当 Spring 在 POM 文件中找到 spring-boot-starter-freemarker
工件时,它会自动配置 FreeMarker。
@RequestMapping(path = "/GetCities", produces = "application/json; charset=UTF-8") @ResponseBody public List<City> findCities() { var cities = (List<City>) cityService.findAll(); return cities; }
对于 GetCities
路径,将调用 findCities
方法。 produces
参数表示该方法返回 JSON 数据;Spring RequestResponseBodyMethodProcessor
通过使用 HttpMessageConverter
写入响应体来处理使用 @ResponseBody
注解的方法的返回值。在我们的例子中,消息转换器是 MappingJackson2HttpMessageConverter
,它使用 Jackson 的 ObjectMapper 读取和写入 JSON。(Jackson 是一个流行的 Java JSON 库。)
<!DOCTYPE html> <html> <head> <title>Home Page</title> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <script src="webjars/jquery/jquery.min.js"></script> </head> <body> <button id="mybtn">Get cities</button> <div> <ul id="output"> </ul> </div> <script> $('#mybtn').click(function () { $.getJSON('GetCities', function (data) { $("ul#output > li").remove(); $.each(data, function (key, value) { $("#output").append('<li>' + value['name'] + " " + value['population'] + '</li>'); }); }); }); </script> </body> </html>
index.ftl
文件是主页的模板。它包含一个按钮,该按钮执行对 Web 应用程序的异步请求。它加载城市列表并将其写入 HTML 列表中。
<script src="webjars/jquery/jquery.min.js"></script>
我们包含 JQuery 库。感谢 webjars-locator
,我们可以包含一个与版本无关的 JQuery 库。因此,如果 JQuery 的版本发生更改,我们不必更新链接。
<script> $('#mybtn').click(function () { $.getJSON('GetCities', function (data) { $("ul#output > li").remove(); $.each(data, function (key, value) { $("#output").append('<li>' + value['name'] + " " + value['population'] + '</li>'); }); }); }); </script>
使用 $.getJSON
方法,我们使用 HTTP GET 请求以 JSON 格式加载数据。数据使用 $.each
遍历并写入 HTML 列表。
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); } }
应用程序设置 Spring Boot 应用程序。
在本文中,我们使用了 Spring Boot Web 应用程序中的 @ResponseBody
注解。