在本教程中,我们将创建一个简单的 Spring Boot RESTful 应用。 我们的应用将部署在嵌入式 Tomcat 服务器上。
我们展示了如何从 Web 服务中以 JSON 和 XML 格式返回数据。
Spring Boot
Spring 是用于创建企业应用的流行 Java 应用框架。 Spring Boot 是一种以最少的精力创建独立的,基于生产级别的基于 Spring 的应用的方法。
RESTFul 应用
RESTFul 应用创建遵循 REST 架构样式的系统(API),该系统用于设计联网应用。 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
这是项目结构。
pom.xml
<?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.0http://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创建的。
application.yml
server:port: 8086contextPath: /rest
application.yml文件包含 Spring Boot 应用的各种配置设置。 我们具有服务器端口和上下文路径(应用名称)的映射。 该文件位于src/main/resources目录中。
countries.csv
Country, PopulationSlovakia,5429000Norway,5271000Croatia,4225000Russia,143439000Mexico,122273000Vietnam,95261000Sweden,9967000Iceland,337600Israel,8622000Hungary,9830000Germany,82175700Japan,126650000
src/main/resources目录中的countries.csv包含我们的应用中使用的数据。
Country.java
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类。
ICountryService.java
package com.zetcode.service;import com.zetcode.bean.Country;import java.util.ArrayList;public interface ICountryService {public ArrayList<Country> findAll();}
这是ICountryService接口。 它包含一种称为findAll()的方法。
CountryService.java
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;@Servicepublic class CountryService implements ICountryService {private final ArrayList<Country> countries;public CountryService() {countries = new ArrayList();}@Overridepublic 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对象的列表。
MyController.java
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;@RestControllerpublic class MyController {@Autowiredprivate ICountryService countryService;@RequestMapping("/countries")public List<Country> listCountries() {return countryService.findAll();}}
这是 Spring Boot RESTful 应用的控制器类。 @RestController注解创建一个 RESTful 控制器。 传统的 MVC 控制器使用ModelAndView,而 RESTful 控制器仅返回对象,并且对象数据以 JSON 或 XML 格式直接写入 HTTP 响应。
@Autowiredprivate 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。
Application.java
package com.zetcode;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;@SpringBootApplicationpublic 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添加到依赖项。
MyController.java
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;@RestControllerpublic class MyController {@Autowiredprivate 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 数据。
在本教程中,我们创建了一个 Spring Boot RESTful 应用,该应用以 JSON 和 XML 返回数据。 您可能也对相关教程感兴趣: Spring Boot H2 REST 教程, Spring Web 应用简介,独立的 Spring 应用, OpenCSV 教程 ,在经典的 Spring 应用中使用 HikariCP 连接池,JdbcTemplate。
