在本教程中,我们将创建一个简单的 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.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
创建的。
application.yml
server:
port: 8086
contextPath: /rest
application.yml
文件包含 Spring Boot 应用的各种配置设置。 我们具有服务器端口和上下文路径(应用名称)的映射。 该文件位于src/main/resources
目录中。
countries.csv
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
包含我们的应用中使用的数据。
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;
@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
对象的列表。
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;
@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 控制器仅返回对象,并且对象数据以 JSON 或 XML 格式直接写入 HTTP 响应。
@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。
Application.java
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
添加到依赖项。
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;
@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 数据。
在本教程中,我们创建了一个 Spring Boot RESTful 应用,该应用以 JSON 和 XML 返回数据。