Spring Boot快速入門(mén)之(十一):構(gòu)建 RESTful Web 服務(wù)
【注】本文譯自:? https://www.tutorialspoint.com/spring_boot/spring_boot_building_restful_web_services.htm

? ??Spring Boot 提供了構(gòu)建企業(yè)應(yīng)用中 RESTful Web 服務(wù)的極佳支持。本文為你詳解如何使用?Spring Boot 構(gòu)建?RESTful web 服務(wù)。
注意:要構(gòu)建 RESTful Web 服務(wù),我們需要在構(gòu)建配置文件中加上 Spring Boot Starter Web 依賴(lài)。
? ? 對(duì)于 Maven 用戶(hù),使用以下的代碼在?pom.xml?文件中加入依賴(lài):
<dependency>
???<groupId>org.springframework.boot</groupId>
???<artifactId>spring-boot-starter-web</artifactId>????
</dependency>
? ? 對(duì)于 Gradle 用戶(hù),使用以下的代碼在?build.gradle?文件中加入依賴(lài):
compile('org.springframework.boot:spring-boot-starter-web')
? ? 完整的構(gòu)建配置文件?Maven build – 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.tutorialspoint</groupId>
???<artifactId>demo</artifactId>
???<version>0.0.1-SNAPSHOT</version>
???<packaging>jar</packaging>
???<name>demo</name>
???<description>Demo project for Spring Boot</description>
???
???<parent>
??????<groupId>org.springframework.boot</groupId>
??????<artifactId>spring-boot-starter-parent</artifactId>
??????<version>1.5.8.RELEASE</version>
??????<relativePath/>
???</parent>
???
???<properties>
??????<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
??????<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
??????<java.version>1.8</java.version>
???</properties>
???
???<dependencies>
??????<dependency>
?????????<groupId>org.springframework.boot</groupId>
?????????<artifactId>spring-boot-starter-web</artifactId>
??????</dependency>
??????<dependency>
?????????<groupId>org.springframework.boot</groupId>
?????????<artifactId>spring-boot-starter-test</artifactId>
?????????<scope>test</scope>
??????</dependency>
???</dependencies>
???
???<build>
??????<plugins>
?????????<plugin>
????????????<groupId>org.springframework.boot</groupId>
????????????<artifactId>spring-boot-maven-plugin</artifactId>
?????????</plugin>
??????</plugins>
???</build>
???
</project>
? ? 完整的構(gòu)建配置文件?Gradle Build – build.gradle?如下:
buildscript {
???ext {
??????springBootVersion = '1.5.8.RELEASE'
???}
???repositories {
??????mavenCentral()
???}
???dependencies {
??????classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
???}
}
apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: 'org.springframework.boot'
group = 'com.tutorialspoint'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = 1.8
repositories {
???mavenCentral()
}
dependencies {
???compile('org.springframework.boot:spring-boot-starter-web')
???testCompile('org.springframework.boot:spring-boot-starter-test')
}
? ? 在繼續(xù)構(gòu)建 RESTful web 服務(wù)前,建議你先要熟悉下面的注解:
Rest Controller
? ?@RestController 注解用于定義 RESTful web 服務(wù)。它提供 JSON、XML 和自定義響應(yīng)。語(yǔ)法如下所示:
@RestController
public class ProductServiceController {
}
Request Mapping
? ? @RequestMapping 注解用于定義請(qǐng)求 URI 以訪問(wèn) REST 端點(diǎn)。我們可以定義 Request 方法來(lái)消費(fèi) produce 對(duì)象。默認(rèn)的請(qǐng)求方法是 GET:
@RequestMapping(value = "/products")
public ResponseEntity<Object> getProducts() { }
Request Body
? ?@RequestBody 注解用于定義請(qǐng)求體內(nèi)容類(lèi)型。
public ResponseEntity<Object> createProduct(@RequestBody Product product) {
}
Path Variable
? ?@PathVariable 注解被用于定義自定義或動(dòng)態(tài)的請(qǐng)求 URI,Path variable 被放在請(qǐng)求 URI 中的大括號(hào)內(nèi),如下所示:
public ResponseEntity<Object> updateProduct(@PathVariable("id") String id) {
}
Request Parameter
? ?@RequestParam 注解被用于從請(qǐng)求?URL 中讀取請(qǐng)求參數(shù)。缺少情況下這是一個(gè)必需的參數(shù),也可以為請(qǐng)求參數(shù)設(shè)置默認(rèn)值,如下所示:
public ResponseEntity<Object> getProduct(
???@RequestParam(value = "name", required = false, defaultValue = "honey") String name) {
}
GET API
? ? ?默認(rèn)的 HTTP 請(qǐng)求方法是 GET。這個(gè)方法不需要任何請(qǐng)求體。你可以通過(guò)發(fā)送請(qǐng)求參數(shù)和路徑變量來(lái)定義自定義或動(dòng)態(tài) URL。
? ? 下面的示例代碼定義了 HTTP GET 請(qǐng)求方法。在這個(gè)例子吧,我們使用 HashMap 來(lái)在存儲(chǔ) Product。注意我們使用了 POJO 類(lèi)來(lái)存儲(chǔ)產(chǎn)品。
? ? ?在這里,請(qǐng)求?URI 是?/products,它會(huì)從?HashMap?倉(cāng)儲(chǔ)中返回產(chǎn)品列表。下面的控制器類(lèi)文件包含了 GET 方法的 REST 端點(diǎn):
package com.tutorialspoint.demo.controller;
import java.util.HashMap;
import java.util.Map;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.tutorialspoint.demo.model.Product;
@RestController
public class ProductServiceController {
???private static Map<String, Product> productRepo = new HashMap<>();
???static {
??????Product honey = new Product();
??????honey.setId("1");
??????honey.setName("Honey");
??????productRepo.put(honey.getId(), honey);
??????
??????Product almond = new Product();
??????almond.setId("2");
??????almond.setName("Almond");
??????productRepo.put(almond.getId(), almond);
???}
???@RequestMapping(value = "/products")
???public ResponseEntity<Object> getProduct() {
??????return new ResponseEntity<>(productRepo.values(), HttpStatus.OK);
???}
}
POST API
? ?HTTP POST 請(qǐng)求用于創(chuàng)建資源。這個(gè)方法包含請(qǐng)求體。我們可以通過(guò)發(fā)送請(qǐng)求參數(shù)和路徑變量來(lái)定義自定義或動(dòng)態(tài) URL。
? ?下面的示例代碼定義了?HTTP POST 請(qǐng)求方法。在這個(gè)例子中,我們使用 HashMap 來(lái)存儲(chǔ) Product,這里產(chǎn)品是一個(gè) POJO 類(lèi)。
? ?這里,請(qǐng)求 URI 是?/products,在產(chǎn)品被存入?HashMap 倉(cāng)儲(chǔ)后,它會(huì)返回字符串。
package com.tutorialspoint.demo.controller;
import java.util.HashMap;
import java.util.Map;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import com.tutorialspoint.demo.model.Product;
@RestController
public class ProductServiceController {
???private static Map<String, Product> productRepo = new HashMap<>();
???
???@RequestMapping(value = "/products", method = RequestMethod.POST)
???public ResponseEntity<Object> createProduct(@RequestBody Product product) {
??????productRepo.put(product.getId(), product);
??????return new ResponseEntity<>("Product is created successfully", HttpStatus.CREATED);
???}
}
PUT API
? ??HTTP PUT 請(qǐng)求用于更新已有的資源。這個(gè)方法包含請(qǐng)求體。我們可以通過(guò)發(fā)送請(qǐng)求參數(shù)和路徑變量來(lái)定義自定義或動(dòng)態(tài) URL。
? ? 下面的例子展示了如何定義?HTTP PUT 請(qǐng)求方法。在這個(gè)例子中,我們使用 HashMap 更新現(xiàn)存的產(chǎn)品。此處,產(chǎn)品是一個(gè) POJO 類(lèi)。
? ? 這里,請(qǐng)求 URI 是?/products/{id},在產(chǎn)品被存入?HashMap 倉(cāng)儲(chǔ)后,它會(huì)返回字符串。注意我們使用路徑變量?{id}?定義需要更新的產(chǎn)品?ID:
package com.tutorialspoint.demo.controller;
import java.util.HashMap;
import java.util.Map;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import com.tutorialspoint.demo.model.Product;
@RestController
public class ProductServiceController {
???private static Map<String, Product> productRepo = new HashMap<>();
???
???@RequestMapping(value = "/products/{id}", method = RequestMethod.PUT)
???public ResponseEntity<Object> updateProduct(@PathVariable("id") String id, @RequestBody Product product) {
??????productRepo.remove(id);
??????product.setId(id);
??????productRepo.put(id, product);
??????return new ResponseEntity<>("Product is updated successsfully", HttpStatus.OK);
???}???
}
DELETE API
? ?HTTP Delete 請(qǐng)求用于刪除存在的資源。這個(gè)方法不包含任何請(qǐng)求體。我們可以通過(guò)發(fā)送請(qǐng)求參數(shù)和路徑變量來(lái)定義自定義或動(dòng)態(tài) URL。
? ?下面的例子展示如何定義?HTTP DELETE 請(qǐng)求方法。這個(gè)例子中,我們使用 HashMap 來(lái)移除現(xiàn)存的產(chǎn)品,用 POJO 來(lái)表示。
? ?請(qǐng)求 URI 是?/products/{id}?在產(chǎn)品被從?HashMap 倉(cāng)儲(chǔ)中刪除后,它會(huì)返回字符串。?我們使用路徑變量?{id}?來(lái)定義要被刪除的產(chǎn)品?ID。
package com.tutorialspoint.demo.controller;
import java.util.HashMap;
import java.util.Map;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import com.tutorialspoint.demo.model.Product;
@RestController
public class ProductServiceController {
???private static Map<String, Product> productRepo = new HashMap<>();
???
???@RequestMapping(value = "/products/{id}", method = RequestMethod.DELETE)
???public ResponseEntity<Object> delete(@PathVariable("id") String id) {
??????productRepo.remove(id);
??????return new ResponseEntity<>("Product is deleted successsfully", HttpStatus.OK);
???}
}
? ?下面給出完整的源代碼:
Spring Boot 主應(yīng)用類(lèi) – DemoApplication.java
package com.tutorialspoint.demo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class DemoApplication {
???public static void main(String[] args) {
??????SpringApplication.run(DemoApplication.class, args);
???}
}
POJO 類(lèi) – Product.java
package com.tutorialspoint.demo.model;
public class Product {
???private String id;
???private String name;
???public String getId() {
??????return id;
???}
???public void setId(String id) {
??????this.id = id;
???}
???public String getName() {
??????return name;
???}
???public void setName(String name) {
??????this.name = name;
???}
}
Rest Controller 類(lèi) – ProductServiceController.java
package com.tutorialspoint.demo.controller;
import java.util.HashMap;
import java.util.Map;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import com.tutorialspoint.demo.model.Product;
@RestController
public class ProductServiceController {
???private static Map<String, Product> productRepo = new HashMap<>();
???static {
??????Product honey = new Product();
??????honey.setId("1");
??????honey.setName("Honey");
??????productRepo.put(honey.getId(), honey);
??????
??????Product almond = new Product();
??????almond.setId("2");
??????almond.setName("Almond");
??????productRepo.put(almond.getId(), almond);
???}
???
???@RequestMapping(value = "/products/{id}", method = RequestMethod.DELETE)
???public ResponseEntity<Object> delete(@PathVariable("id") String id) {
??????productRepo.remove(id);
??????return new ResponseEntity<>("Product is deleted successsfully", HttpStatus.OK);
???}
???
???@RequestMapping(value = "/products/{id}", method = RequestMethod.PUT)
???public ResponseEntity<Object> updateProduct(@PathVariable("id") String id, @RequestBody Product product) {
??????productRepo.remove(id);
??????product.setId(id);
??????productRepo.put(id, product);
??????return new ResponseEntity<>("Product is updated successsfully", HttpStatus.OK);
???}
???
???@RequestMapping(value = "/products", method = RequestMethod.POST)
???public ResponseEntity<Object> createProduct(@RequestBody Product product) {
??????productRepo.put(product.getId(), product);
??????return new ResponseEntity<>("Product is created successfully", HttpStatus.CREATED);
???}
???
???@RequestMapping(value = "/products")
???public ResponseEntity<Object> getProduct() {
??????return new ResponseEntity<>(productRepo.values(), HttpStatus.OK);
???}
}
? ?你可以創(chuàng)建可執(zhí)行的?JAR 文件,使用以下的?Maven 或 Gradle 命令來(lái)運(yùn)行?spring boot 應(yīng)用:
? ?Maven命令如下:
mvn clean install
? ?“構(gòu)建成功“后,可以在 target 文件夾下發(fā)現(xiàn) JAR 文件。
? ?Gradle命令如下:
gradle clean build
? ? “構(gòu)建成功“后,可以在 build/libs?文件夾下發(fā)現(xiàn) JAR 文件。
? ? 可以使用以下命令來(lái)運(yùn)行 JAR 文件:
java –jar <JARFILE>
? ? 以?Tomcat?端口號(hào)?8080?啟動(dòng)應(yīng)用,如下所示:

? ? 在?POSTMAN 應(yīng)用中點(diǎn)擊下面的 URL 可以看到相應(yīng)的輸出:
GET API URL 為:?http://localhost:8080/products

POST API URL 為:?http://localhost:8080/products

PUT API URL 為:?http://localhost:8080/products/3

DELETE API URL 為:?http://localhost:8080/products/3
