原文: http://zetcode.com/springboot/responsebody/

在 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 响应主体。

Spring @ResponseBody示例

以下示例创建一个 Spring Boot Web 应用,该应用将 JSON 数据返回到客户端。 主页是通过 MVC 机制处理的; FreeMarker 用于创建主页的模板。 主页包含一个按钮,该按钮发送获取 JSON 数据的请求。 Spring Boot Web 应用在@ResponseBody注解的帮助下以 JSON 格式发送数据。

  1. pom.xml
  2. src
  3. ├── main
  4. ├── java
  5. └── com
  6. └── zetcode
  7. ├── Application.java
  8. ├── model
  9. └── City.java
  10. ├── controller
  11. └── MyController.java
  12. └── service
  13. ├── CityService.java
  14. └── ICityService.java
  15. └── resources
  16. └── templates
  17. └── index.ftl
  18. └── test
  19. └── java

这是应用的项目结构。

pom.xml

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <project xmlns="http://maven.apache.org/POM/4.0.0"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
  5. http://maven.apache.org/xsd/maven-4.0.0.xsd">
  6. <modelVersion>4.0.0</modelVersion>
  7. <groupId>com.zetcode</groupId>
  8. <artifactId>springbootresponsebodyex</artifactId>
  9. <version>1.0-SNAPSHOT</version>
  10. <packaging>jar</packaging>
  11. <properties>
  12. <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  13. <maven.compiler.source>11</maven.compiler.source>
  14. <maven.compiler.target>11</maven.compiler.target>
  15. </properties>
  16. <parent>
  17. <groupId>org.springframework.boot</groupId>
  18. <artifactId>spring-boot-starter-parent</artifactId>
  19. <version>2.1.1.RELEASE</version>
  20. </parent>
  21. <dependencies>
  22. <dependency>
  23. <groupId>org.springframework.boot</groupId>
  24. <artifactId>spring-boot-starter-web</artifactId>
  25. </dependency>
  26. <dependency>
  27. <groupId>org.springframework.boot</groupId>
  28. <artifactId>spring-boot-starter-freemarker</artifactId>
  29. </dependency>
  30. <dependency>
  31. <groupId>org.webjars</groupId>
  32. <artifactId>jquery</artifactId>
  33. <version>3.3.1</version>
  34. </dependency>
  35. <dependency>
  36. <groupId>org.webjars</groupId>
  37. <artifactId>webjars-locator</artifactId>
  38. <version>0.34</version>
  39. </dependency>
  40. </dependencies>
  41. <build>
  42. <plugins>
  43. <plugin>
  44. <groupId>org.springframework.boot</groupId>
  45. <artifactId>spring-boot-maven-plugin</artifactId>
  46. </plugin>
  47. </plugins>
  48. </build>
  49. </project>

spring-boot-starter-freemarker是建立使用 FreeMarker 的观点 Spring MVC 的 Web 应用的启动。 我们将 Webjar 用于 JQuery。 webjars-locator自动解析任何 WebJars 资产的版本。 该应用打包到 JAR 文件中,并使用 Tomcat 作为嵌入式 Web 服务器。

com/zetcode/model/City.java

  1. package com.zetcode.model;
  2. import java.util.Objects;
  3. public class City {
  4. private Long id;
  5. private String name;
  6. private int population;
  7. public City() {
  8. }
  9. public City(Long id, String name, int population) {
  10. this.id = id;
  11. this.name = name;
  12. this.population = population;
  13. }
  14. public Long getId() {
  15. return id;
  16. }
  17. public void setId(Long id) {
  18. this.id = id;
  19. }
  20. public String getName() {
  21. return name;
  22. }
  23. public void setName(String name) {
  24. this.name = name;
  25. }
  26. public int getPopulation() {
  27. return population;
  28. }
  29. public void setPopulation(int population) {
  30. this.population = population;
  31. }
  32. @Override
  33. public boolean equals(Object o) {
  34. if (this == o) return true;
  35. if (o == null || getClass() != o.getClass()) return false;
  36. City city = (City) o;
  37. return population == city.population &&
  38. Objects.equals(id, city.id) &&
  39. Objects.equals(name, city.name);
  40. }
  41. @Override
  42. public int hashCode() {
  43. return Objects.hash(id, name, population);
  44. }
  45. @Override
  46. public String toString() {
  47. final StringBuilder sb = new StringBuilder("City{");
  48. sb.append("id=").append(id);
  49. sb.append(", name='").append(name).append('\'');
  50. sb.append(", population=").append(population);
  51. sb.append('}');
  52. return sb.toString();
  53. }
  54. }

这是City bean。 它具有idnamepopulation属性。

com/zetcode/service/ICityService.java

  1. package com.zetcode.service;
  2. import com.zetcode.model.City;
  3. import java.util.List;
  4. public interface ICityService {
  5. List<City> findAll();
  6. }

ICityService包含获取所有城市的契约方法。

com/zetcode/service/CityService.java

  1. package com.zetcode.service;
  2. import com.zetcode.model.City;
  3. import org.springframework.stereotype.Service;
  4. import java.util.ArrayList;
  5. import java.util.List;
  6. @Service
  7. public class CityService implements ICityService {
  8. @Override
  9. public List<City> findAll() {
  10. var cities = new ArrayList<City>();
  11. cities.add(new City(1L, "Bratislava", 432000));
  12. cities.add(new City(2L, "Budapest", 1759000));
  13. cities.add(new City(3L, "Prague", 1280000));
  14. cities.add(new City(4L, "Warsaw", 1748000));
  15. cities.add(new City(5L, "Los Angeles", 3971000));
  16. cities.add(new City(6L, "New York", 8550000));
  17. cities.add(new City(7L, "Edinburgh", 464000));
  18. cities.add(new City(8L, "Berlin", 3671000));
  19. return cities;
  20. }
  21. }

CityService返回八个城市对象。

com/zetcode/controller/MyController.java

  1. package com.zetcode.controller;
  2. import com.zetcode.bean.City;
  3. import com.zetcode.service.ICityService;
  4. import java.util.List;
  5. import org.springframework.beans.factory.annotation.Autowired;
  6. import org.springframework.stereotype.Controller;
  7. import org.springframework.web.bind.annotation.RequestMapping;
  8. import org.springframework.web.bind.annotation.ResponseBody;
  9. @Controller
  10. public class MyController {
  11. @Autowired
  12. ICityService cityService;
  13. @RequestMapping(path = "/")
  14. public String index() {
  15. return "index";
  16. }
  17. @RequestMapping(path = "/GetCities", produces = "application/json; charset=UTF-8")
  18. @ResponseBody
  19. public List<City> findCities() {
  20. var cities = (List<City>) cityService.findAll();
  21. return cities;
  22. }
  23. }

控制器有两种方法。 index()方法返回主页视图。 findCities()方法返回城市列表作为 JSON 数据。

  1. @Controller
  2. public class MyController {

@Controller注解表示我们有一个控制器类。

  1. @RequestMapping(path = "/")
  2. public String index() {
  3. return "index";
  4. }

index()方法返回index字符串,该字符串被解析为index.ftl视图。 该视图位于src/main/resources/templates目录中。 当 Spring 在 POM 文件中找到spring-boot-starter-freemarker工件时,它将自动配置 FreeMarker。

  1. @RequestMapping(path = "/GetCities", produces = "application/json; charset=UTF-8")
  2. @ResponseBody
  3. public List<City> findCities() {
  4. var cities = (List<City>) cityService.findAll();
  5. return cities;
  6. }

对于GetCities路径,将调用findCities()方法。 produces参数指示该方法返回 JSON 数据; Spring RequestResponseBodyMethodProcessor通过使用HttpMessageConverter写入响应主体来处理用@ResponseBody注解的方法的返回值。 在我们的例子中,消息转换器是MappingJackson2HttpMessageConverter,它使用 Jackson 的ObjectMapper读取和写入 JSON。 (Jackson 是一个流行的 Java JSON 库。)

resources/templates/index.ftl

  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <title>Home Page</title>
  5. <meta charset="UTF-8">
  6. <meta name="viewport" content="width=device-width, initial-scale=1.0">
  7. <script src="webjars/jquery/jquery.min.js"></script>
  8. </head>
  9. <body>
  10. <button id="mybtn">Get cities</button>
  11. <div>
  12. <ul id="output">
  13. </ul>
  14. </div>
  15. <script>
  16. $('#mybtn').click(function () {
  17. $.getJSON('GetCities', function (data) {
  18. $("ul#output > li").remove();
  19. $.each(data, function (key, value) {
  20. $("#output").append('<li>' + value['name'] + " " + value['population'] + '</li>');
  21. });
  22. });
  23. });
  24. </script>
  25. </body>
  26. </html>

index.ftl文件是主页的模板。 它包含一个按钮,该按钮对 Web 应用执行异步请求。 它将加载城市列表并将其写入 HTML 列表。

  1. <script src="webjars/jquery/jquery.min.js"></script>

我们包括 JQuery 库。 多亏webjars-locator,我们可以包括一个版本无关的 JQuery 库。 因此,如果 JQuery 的版本发生更改,我们不必更新链接。

  1. <script>
  2. $('#mybtn').click(function () {
  3. $.getJSON('GetCities', function (data) {
  4. $("ul#output > li").remove();
  5. $.each(data, function (key, value) {
  6. $("#output").append('<li>' + value['name'] + " " + value['population'] + '</li>');
  7. });
  8. });
  9. });
  10. </script>

通过$.getJSON()方法,我们使用 HTTP GET 请求以 JSON 格式加载数据。 数据用$.each()遍历并写入 HTML 列表。

在本教程中,我们在 Spring Boot Web 应用中使用了@ResponseBody注解。 您可能也对相关教程感兴趣: Spring Boot ResponseEntity教程Spring Boot @PathVariable教程Spring Boot 上传文件Spring Boot @RequestParam教程独立的 Spring 应用Java 教程或列出所有 Spring Boot 教程