Spring Boot RESTful 应用程序
最后修改于 2020 年 7 月 13 日
在本教程中,我们将创建一个简单的 Spring Boot RESTful 应用程序。我们的应用程序将部署在嵌入式 Tomcat 服务器上。
我们展示了如何从我们的 Web 服务中以 JSON 和 XML 格式返回数据。
Spring Boot
Spring 是一个流行的 Java 应用程序框架,用于创建企业应用程序。Spring Boot 是一种以最小的努力创建独立、生产级别的 Spring 应用程序的方式。
RESTful 应用程序
RESTful 应用程序创建一个遵循 REST 架构风格的系统(API),REST 架构风格用于设计网络应用程序。RESTful 应用程序使用 HTTP 请求对资源执行 CRUD(创建/读取/更新/删除)操作。
Spring Boot RESTful 简单示例
以下代码示例创建了一个 Web 服务,该服务从 CSV 文件读取数据并以 JSON 格式将其返回给客户端。
$ tree
.
├── pom.xml
└── src
├── main
│ ├── java
│ │ └── com
│ │ └── zetcode
│ │ ├── Application.java
│ │ ├── bean
│ │ │ └── Country.java
│ │ ├── controller
│ │ │ └── MyController.java
│ │ └── service
│ │ ├── CountryService.java
│ │ └── ICountryService.java
│ └── resources
│ ├── application.yml
│ └── countries.csv
└── test
└── java
这是项目结构。
<?xml version="1.0" encoding="UTF-8"?>
<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.zetcode</groupId>
<artifactId>SpringBootRest</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<name>SpringBootRest</name>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.3.RELEASE</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.opencsv</groupId>
<artifactId>opencsv</artifactId>
<version>3.8</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
这是 Maven 构建文件。opencsv 用于处理 CSV 数据。spring-boot-starter-web 是用于构建 Web 和 RESTful 应用程序的启动器。应用程序被打包成一个可执行的 JAR 文件。可执行 JAR 是使用 spring-boot-maven-plugin 创建的。
server: port: 8086 contextPath: /rest
application.yml 文件包含 Spring Boot 应用程序的各种配置设置。我们为服务器端口和上下文路径(应用程序名称)进行了映射。该文件位于 src/main/resources 目录中。
Country, Population Slovakia,5429000 Norway,5271000 Croatia,4225000 Russia,143439000 Mexico,122273000 Vietnam,95261000 Sweden,9967000 Iceland,337600 Israel,8622000 Hungary,9830000 Germany,82175700 Japan,126650000
位于 src/main/resources 目录中的 countries.csv 包含我们应用程序中使用的数据。
package com.zetcode.bean;
public class Country {
private String name;
private int population;
public Country() {
}
public Country(String name, int population) {
this.name = name;
this.population = population;
}
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;
}
}
countries.csv 文件中的字段映射到 Country 类。
package com.zetcode.service;
import com.zetcode.bean.Country;
import java.util.ArrayList;
public interface ICountryService {
public ArrayList<Country> findAll();
}
这是 ICountryService 接口。它包含一个名为 findAll 的方法。
package com.zetcode.service;
import com.opencsv.CSVReader;
import com.zetcode.bean.Country;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.springframework.stereotype.Service;
@Service
public class CountryService implements ICountryService {
private final ArrayList<Country> countries;
public CountryService() {
countries = new ArrayList();
}
@Override
public ArrayList<Country> findAll() {
FileInputStream fis = null;
try {
String fileName = "src/main/resources/countries.csv";
fis = new FileInputStream(new File(fileName));
CSVReader reader = new CSVReader(new InputStreamReader(fis));
String[] nextLine;
reader.readNext();
while ((nextLine = reader.readNext()) != null) {
Country newCountry = new Country(nextLine[0],
Integer.valueOf(nextLine[1]));
countries.add(newCountry);
}
} catch (FileNotFoundException ex) {
Logger.getLogger(CountryService.class.getName()).log(Level.SEVERE, null, ex);
} catch (IOException ex) {
Logger.getLogger(CountryService.class.getName()).log(Level.SEVERE, null, ex);
} finally {
try {
if (fis != null) {
fis.close();
}
} catch (IOException ex) {
Logger.getLogger(CountryService.class.getName()).log(Level.SEVERE, null, ex);
}
}
return countries;
}
}
这是 ICountryService 合约的实现。它包含 findAll 方法,该方法从 countries.csv 文件读取数据并返回 Country 对象列表。
package com.zetcode.controller;
import com.zetcode.bean.Country;
import com.zetcode.service.ICountryService;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class MyController {
@Autowired
private ICountryService countryService;
@RequestMapping("/countries")
public List<Country> listCountries() {
return countryService.findAll();
}
}
这是 Spring Boot RESTful 应用程序的控制器类。@RestController 注解创建了一个 RESTful 控制器。而传统的 MVC 控制器使用 ModelAndView,RESTful 控制器直接返回对象,对象数据直接写入 HTTP 响应中的 JSON 或 XML 格式。
@Autowired private ICountryService countryService;
我们将 CountryService 注入到 countryService 变量中。
@RequestMapping("/countries")
public List<Country> listCountries() {
return countryService.findAll();
}
@RequestMapping 注解用于将 Web 请求映射到 Spring 控制器方法。在这里,我们将 /countries 路径的请求映射到控制器的 listCountries 方法。默认请求是 GET 请求。
我们不需要手动将 Country 域对象转换为 JSON。因为 Jackson 2 在类路径中,Spring 会自动选择 MappingJackson2HttpMessageConverter 将 Country 实例转换为 JSON。
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 应用程序。@SpringBootApplication 启用了自动配置和组件扫描。
$ mvn package
使用 mvn package 命令,我们构建应用程序。
$ mvn spring-boot:run
使用 mvn spring-boot:run 命令,我们运行应用程序。应用程序部署在嵌入式 Tomcat 服务器上。
$ curl localhost:8086/rest/countries
[{"name":"Slovakia","population":5429000},{"name":"Norway","population":5271000},
{"name":"Croatia","population":4225000},{"name":"Russia","population":143439000},
{"name":"Mexico","population":122273000},{"name":"Vietnam","population":95261000},
{"name":"Sweden","population":9967000},{"name":"Iceland","population":337600},
{"name":"Israel","population":8622000},{"name":"Hungary","population":9830000},
{"name":"Germany","population":82175700},{"name":"Japan","population":126650000}]
使用 curl 命令,我们测试应用程序。
返回 XML 数据
要返回 XML 数据而不是 JSON,我们需要添加一个依赖项并修改控制器。
<dependency>
<groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-xml</artifactId>
</dependency>
我们将 jackson-dataformat-xml 添加到依赖项中。
package com.zetcode.controller;
import com.zetcode.bean.Country;
import com.zetcode.service.ICountryService;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class MyController {
@Autowired
private ICountryService countryService;
@RequestMapping(value="/countries", method=RequestMethod.GET,
produces=MediaType.APPLICATION_XML_VALUE)
public List<Country> listCountries() {
return countryService.findAll();
}
}
我们选择 MediaType.APPLICATION_XML_VALUE 类型来告知控制器返回 XML 数据。
在本教程中,我们创建了一个返回 JSON 和 XML 数据的 Spring Boot RESTful 应用程序。