查看: 243|回复: 0

[Java代码] 详解spring boot rest例子

发表于 6 天前

简介:本文将帮助您使用 Spring Boot 创建简单的 REST 服务。

你将学习

  1. 什么是 REST 服务?
  2. 如何使用 Spring Initializr 引导创建 Rest 服务应用程序?
  3. 如何创建获取 REST 服务以检索学生注册的课程?
  4. 如何为学生注册课程创建 Post REST 服务?
  5. 如何利用 postman 执行 rest 服务?

本教程使用的 rest 服务

在本教程中,我们将使用适当的 URI 和 HTTP 方法创建三个服务:

@GetMapping(“/ students / {studentId} / courses”):您可以使用请求方法 Get 和示例 uri / students / Student1 / courses 来查询特定学生已注册的课程。

@GetMapping(“/students/{studentId}/courses/{courseId}”):您可以使用请求方法 Get 和示例 uri / students / Student1 / courses / Course1 获取特定学生的特定课程。

@PostMapping(“/students/{studentId}/courses”) :您可以通过向 UURI /students/Student1/courses 发送 POST 请求来为学生注册一门课程

您将需要的工具

  1. Maven 3.0+ 是您的构建工具
  2. 你最喜欢的 IDE。我们使用 Eclipse。
  3. JDK 1.8+

完整的 spring booot rest Maven 项目代码示例子

我们的 Github 存储库包含所有代码示例 - https://github.com/in28minutes/in28minutes.github.io/tree/master/code-zip-files

带有单元和集成测试的 REST 服务

Website-springbootrestservices-simplerestserviceswithunitandintegrationtests.zip

什么是 REST?

REST 代表 REpresentational State Transfer。REST 指定了一组体系结构约束。任何满足以下这些条件的服务都称为 RESTful 服务。

RESTful Web Service 的五个重要条件:

  1. 客户端 - 服务器:应该有一个服务生产者和一个服务使用者。
  2. 接口(URL)是统一的并且暴露资源。
  3. 该服务是无状态的。
  4. 服务结果应该是可缓存的。例如 HTTP 缓存。
  5. 服务应该采用分层架构。客户端不应该直接连接到服务器 - 它可能从中间层获取信息 - 缓存。

理查森成熟度模型

Richardson 成熟度模型用于识别 Restful Web Service 的成熟度级别。以下是不同级别和特点:

级别 0:以 REST 风格公开 SOAP Web 服务。公开的操作使用 REST 服务(http:// server / getPosts,http:// server / deletePosts,http:// server / doThis,http:// server / doThat 等)。

级别 1:使用正确的 URI(使用名词)公开资源。例如:http:// server / accounts,http:// server / accounts / 10。但是,HTTP 方法并未使用。

级别 2:资源使用正确的 URI + HTTP 方法。例如,要更新一个账户,你需要做一个 PUT。创建一个帐户,你做一个 POST。Uri 看起来像 posts/1/comments/5 和 accounts/1/friends/1.

等级 3:HATEOAS (Hypermedia as the engine of application state)。您不仅可以了解所请求的信息,还可以了解服务消费者可以采取的下一个可能的操作。当请求有关 Facebook 用户的信息时,REST 服务可以返回用户详细信息以及有关如何获取他最近的帖子,如何获取他最近的评论以及如何检索他朋友的列表的信息。

使用适当的请求方法

始终使用 HTTP 方法。有关每种 HTTP 方法的最佳做法如下所述:

GET:不应该更新任何东西。应该是幂等的(多次调用相同的结果)。可能的返回码 200(OK)+ 404(NOT FOUND)+400(BAD REQUEST)

POST:应该创建新的资源。理想情况下返回 JSON 和链接到新创建的资源。尽可能使用相同的返回码。另外:返回码 201(创建)是可能的。

PUT:更新已知资源。例如:更新客户详细信息。可能的返回码:200(OK)

DELETE:用于删除资源。

项目结构

以下屏幕截图显示了我们将创建的项目的结构。

一些细节:

  1. StudentController.java - rest 控制器提供上面讨论的所有三种服务方法。
  2. Course.java, Student.java, StudentService.java - 应用程序的业务逻辑。StudentService 提供了一些我们从 Rest 控制器中消耗的方法。
  3. StudentControllerIT.java - rest 服务的集成测试。
  4. StudentControllerTest.java - test 服务的单元测试。
  5. StudentServicesApplication.java - Spring Boot 应用程序的启动器。要运行该应用程序,只需将该文件作为 Java 应用程序启动。
  6. pom.xml - 包含构建此项目所需的所有依赖。我们将使用 Spring Boot Starter Web。

使用 Spring Initializr 引导创建 REST 服务

用 Spring Initializr 创建一个 REST 服务是非常的容易小菜一碟。我们将使用 Spring Web MVC 作为我们的 web 层框架。

Spring Initializr http://start.spring.io/ 是引导创建 Spring Boot 项目的好工具。

如上图所示,必须执行以下步骤

启动 Spring Initializr 并选择以下内容

选择 com.in28minutes.springboot 为 Group

选择 student-services 为 Artifact

选择以下依赖项

  1. Web
  2. Actuator
  3. DevTools

点击生成项目。

将项目导入 Eclipse。文件 - > 导入 - > 现有的 Maven 项目。

如果你想了解这个项目的所有文件,你可以继续向下阅读。

应用业务层实现

所有应用都需要数据。我们将使用 ArrayList 这种内存数据存储,而不是与真实数据库交互。

一名学生可以参加多门课程。课程有一个 ID,名称,说明和完成课程需要完成的步骤列表。学生有一个身份证,姓名,说明和他 / 她目前注册的课程列表。StudentService 提供以下公开方法

public List retrieveAllStudents() - 检索所有学生的详细信息

public Student retrieveStudent(String studentId) - 检索特定的学生详细信息

public List retrieveCourses(String studentId) - 检索学生注册的所有课程

public Course retrieveCourse(String studentId, String courseId) - 检索学生注册的特定课程的详细信息

public Course addCourse(String studentId, Course course) - 为现有学生添加课程

请参阅下面这些文件,具体的实现服务类 StudentService 和模型类 Course 和 Student。

  1. src/main/java/com/in28minutes/springboot/model/Course.java
  2. src/main/java/com/in28minutes/springboot/model/Student.java
  3. src/main/java/com/in28minutes/springboot/service/StudentService.java

添加几个 GET Rest 服务

Rest 服务 StudentController 暴露了几个 get 服务。

  1. @Autowired private StudentService studentService :我们使用 Spring Autowiring 将 student 服务自动注入到 StudentController。
  2. @GetMapping(“/students/{studentId}/courses”):以 studentId 作为路径变量公开获取服务
  3. @GetMapping(“/students/{studentId}/courses/{courseId}”):公开获取服务以检索学生的特定课程。
  4. @PathVariable String studentId:来自 uri 的 studentId 的值将映射到此参数。
  1. package com.in28minutes.springboot.controller;
  2. import java.util.List;
  3. import org.springframework.beans.factory.annotation.Autowired;
  4. import org.springframework.web.bind.annotation.GetMapping;
  5. import org.springframework.web.bind.annotation.PathVariable;
  6. import org.springframework.web.bind.annotation.RestController;
  7. import com.in28minutes.springboot.model.Course;
  8. import com.in28minutes.springboot.service.StudentService;
  9. @RestController
  10. public class StudentController {
  11. @Autowired
  12. private StudentService studentService;
  13. @GetMapping("/students/{studentId}/courses")
  14. public List<Course> retrieveCoursesForStudent(@PathVariable String studentId) {
  15. return studentService.retrieveCourses(studentId);
  16. }
  17. @GetMapping("/students/{studentId}/courses/{courseId}")
  18. public Course retrieveDetailsForCourse(@PathVariable String studentId,
  19. @PathVariable String courseId) {
  20. return studentService.retrieveCourse(studentId, courseId);
  21. }
  22. }
复制代码

使用 Postman 执行获取服务

我们将向 http:// localhost:8080 / students / Student1 / courses / Course1 发起请求以测试该服务。回应如下所示。

  1. {
  2. "id": "Course1",
  3. "name": "Spring",
  4. "description": "10 Steps",
  5. "steps": [
  6. "Learn Maven",
  7. "Import Project",
  8. "First Example",
  9. "Second Example"
  10. ]
  11. }
复制代码

下面的图片显示了我们如何执行 Postman 的 Get Service - 我最喜欢的运行 rest 服务的工具。

添加 POST Rest 服务

当资源创建成功时,POST 服务应该返回创建的状态(201)。

  1. @PostMapping(“/students/{studentId}/courses”):为 POST 请求映射 URL
  2. @RequestBody Course newCourse:使用绑定将请求正文绑定到课程对象。
  3. ResponseEntity.created(location).build():返回已创建的状态。还将创建资源的位置作为响应标题返回。
  1. @PostMapping("/students/{studentId}/courses")
  2. public ResponseEntity<Void> registerStudentForCourse(
  3. @PathVariable String studentId, @RequestBody Course newCourse) {
  4. Course course = studentService.addCourse(studentId, newCourse);
  5. if (course == null)
  6. return ResponseEntity.noContent().build();
  7. URI location = ServletUriComponentsBuilder.fromCurrentRequest().path(
  8. "/{id}").buildAndExpand(course.getId()).toUri();
  9. return ResponseEntity.created(location).build();
  10. }
复制代码

执行 POST Rest 服务

示例请求如下所示。它包含了学生注册课程的所有细节。

  1. {
  2. "name": "Microservices",
  3. "description": "10 Steps",
  4. "steps": [
  5. "Learn How to Break Things Up",
  6. "Automate the hell out of everything",
  7. "Have fun"
  8. ]
  9. }
复制代码

下图显示了我们如何从 Postman 执行 Post 服务 - 我最喜欢的运行 rest 服务的工具。确保你去 Body 选项卡并选择 raw。从下拉菜单中选择 JSON。将上述请求复制到 body 中。

我们使用的 URL 是 http:// localhost:8080 / students / Student1 / courses。

完整的代码示例

pom.xml

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  3. xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  4. <modelVersion>4.0.0</modelVersion>
  5. <groupId>com.in28minutes.springboot</groupId>
  6. <artifactId>student-services</artifactId>
  7. <version>0.0.1-SNAPSHOT</version>
  8. <packaging>jar</packaging>
  9. <name>student-services</name>
  10. <description>Demo project for Spring Boot</description>
  11. <parent>
  12. <groupId>org.springframework.boot</groupId>
  13. <artifactId>spring-boot-starter-parent</artifactId>
  14. <version>1.4.4.RELEASE</version>
  15. <relativePath/> <!-- lookup parent from repository -->
  16. </parent>
  17. <properties>
  18. <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  19. <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
  20. <java.version>1.8</java.version>
  21. </properties>
  22. <dependencies>
  23. <dependency>
  24. <groupId>org.springframework.boot</groupId>
  25. <artifactId>spring-boot-starter-actuator</artifactId>
  26. </dependency>
  27. <dependency>
  28. <groupId>org.springframework.boot</groupId>
  29. <artifactId>spring-boot-starter-web</artifactId>
  30. </dependency>
  31. <dependency>
  32. <groupId>org.springframework.boot</groupId>
  33. <artifactId>spring-boot-devtools</artifactId>
  34. <scope>runtime</scope>
  35. </dependency>
  36. <dependency>
  37. <groupId>org.springframework.boot</groupId>
  38. <artifactId>spring-boot-starter-test</artifactId>
  39. <scope>test</scope>
  40. </dependency>
  41. </dependencies>
  42. <build>
  43. <plugins>
  44. <plugin>
  45. <groupId>org.springframework.boot</groupId>
  46. <artifactId>spring-boot-maven-plugin</artifactId>
  47. </plugin>
  48. </plugins>
  49. </build>
  50. </project>
复制代码

src/main/java/com/in28minutes/springboot/controller/StudentController.java

  1. import java.net.URI;
  2. import java.util.List;
  3. import org.springframework.beans.factory.annotation.Autowired;
  4. import org.springframework.http.ResponseEntity;
  5. import org.springframework.web.bind.annotation.GetMapping;
  6. import org.springframework.web.bind.annotation.PathVariable;
  7. import org.springframework.web.bind.annotation.PostMapping;
  8. import org.springframework.web.bind.annotation.RequestBody;
  9. import org.springframework.web.bind.annotation.RestController;
  10. import org.springframework.web.servlet.support.ServletUriComponentsBuilder;
  11. import com.in28minutes.springboot.model.Course;
  12. import com.in28minutes.springboot.service.StudentService;
  13. @RestController
  14. public class StudentController {
  15. @Autowired
  16. private StudentService studentService;
  17. @GetMapping("/students/{studentId}/courses")
  18. public List<Course> retrieveCoursesForStudent(@PathVariable String studentId) {
  19. return studentService.retrieveCourses(studentId);
  20. }
  21. @GetMapping("/students/{studentId}/courses/{courseId}")
  22. public Course retrieveDetailsForCourse(@PathVariable String studentId,
  23. @PathVariable String courseId) {
  24. return studentService.retrieveCourse(studentId, courseId);
  25. }
  26. @PostMapping("/students/{studentId}/courses")
  27. public ResponseEntity<Void> registerStudentForCourse(
  28. @PathVariable String studentId, @RequestBody Course newCourse) {
  29. Course course = studentService.addCourse(studentId, newCourse);
  30. if (course == null)
  31. return ResponseEntity.noContent().build();
  32. URI location = ServletUriComponentsBuilder.fromCurrentRequest().path(
  33. "/{id}").buildAndExpand(course.getId()).toUri();
  34. return ResponseEntity.created(location).build();
  35. }
  36. }
复制代码

src/main/java/com/in28minutes/springboot/model/Course.java

  1. import java.util.List;
  2. public class Course {
  3. private String id;
  4. private String name;
  5. private String description;
  6. private List<String> steps;
  7. // Needed by Caused by: com.fasterxml.jackson.databind.JsonMappingException:
  8. // Can not construct instance of com.in28minutes.springboot.model.Course:
  9. // no suitable constructor found, can not deserialize from Object value
  10. // (missing default constructor or creator, or perhaps need to add/enable
  11. // type information?)
  12. public Course() {
  13. }
  14. public Course(String id, String name, String description, List<String> steps) {
  15. super();
  16. this.id = id;
  17. this.name = name;
  18. this.description = description;
  19. this.steps = steps;
  20. }
  21. public String getId() {
  22. return id;
  23. }
  24. public void setId(String id) {
  25. this.id = id;
  26. }
  27. public String getDescription() {
  28. return description;
  29. }
  30. public String getName() {
  31. return name;
  32. }
  33. public List<String> getSteps() {
  34. return steps;
  35. }
  36. @Override
  37. public String toString() {
  38. return String.format(
  39. "Course [id=%s, name=%s, description=%s, steps=%s]", id, name,
  40. description, steps);
  41. }
  42. @Override
  43. public int hashCode() {
  44. final int prime = 31;
  45. int result = 1;
  46. result = prime * result + ((id == null) ? 0 : id.hashCode());
  47. return result;
  48. }
  49. @Override
  50. public boolean equals(Object obj) {
  51. if (this == obj)
  52. return true;
  53. if (obj == null)
  54. return false;
  55. if (getClass() != obj.getClass())
  56. return false;
  57. Course other = (Course) obj;
  58. if (id == null) {
  59. if (other.id != null)
  60. return false;
  61. } else if (!id.equals(other.id))
  62. return false;
  63. return true;
  64. }
  65. }
复制代码

src/main/java/com/in28minutes/springboot/model/Student.java

  1. package com.in28minutes.springboot.model;
  2. import java.util.List;
  3. public class Student {
  4. private String id;
  5. private String name;
  6. private String description;
  7. private List<Course> courses;
  8. public Student(String id, String name, String description,
  9. List<Course> courses) {
  10. super();
  11. this.id = id;
  12. this.name = name;
  13. this.description = description;
  14. this.courses = courses;
  15. }
  16. public String getId() {
  17. return id;
  18. }
  19. public void setId(String id) {
  20. this.id = id;
  21. }
  22. public String getName() {
  23. return name;
  24. }
  25. public void setName(String name) {
  26. this.name = name;
  27. }
  28. public String getDescription() {
  29. return description;
  30. }
  31. public void setDescription(String description) {
  32. this.description = description;
  33. }
  34. public List<Course> getCourses() {
  35. return courses;
  36. }
  37. public void setCourses(List<Course> courses) {
  38. this.courses = courses;
  39. }
  40. @Override
  41. public String toString() {
  42. return String.format(
  43. "Student [id=%s, name=%s, description=%s, courses=%s]", id,
  44. name, description, courses);
  45. }
  46. }
复制代码

src/main/java/com/in28minutes/springboot/service/StudentService.java

  1. package com.in28minutes.springboot.service;
  2. import java.math.BigInteger;
  3. import java.security.SecureRandom;
  4. import java.util.ArrayList;
  5. import java.util.Arrays;
  6. import java.util.List;
  7. import org.springframework.stereotype.Component;
  8. import com.in28minutes.springboot.model.Course;
  9. import com.in28minutes.springboot.model.Student;
  10. @Component
  11. public class StudentService {
  12. private static List<Student> students = new ArrayList<>();
  13. static {
  14. //Initialize Data
  15. Course course1 = new Course("Course1", "Spring", "10 Steps", Arrays
  16. .asList("Learn Maven", "Import Project", "First Example",
  17. "Second Example"));
  18. Course course2 = new Course("Course2", "Spring MVC", "10 Examples",
  19. Arrays.asList("Learn Maven", "Import Project", "First Example",
  20. "Second Example"));
  21. Course course3 = new Course("Course3", "Spring Boot", "6K Students",
  22. Arrays.asList("Learn Maven", "Learn Spring",
  23. "Learn Spring MVC", "First Example", "Second Example"));
  24. Course course4 = new Course("Course4", "Maven",
  25. "Most popular maven course on internet!", Arrays.asList(
  26. "Pom.xml", "Build Life Cycle", "Parent POM",
  27. "Importing into Eclipse"));
  28. Student ranga = new Student("Student1", "Ranga Karanam",
  29. "Hiker, Programmer and Architect", new ArrayList<>(Arrays
  30. .asList(course1, course2, course3, course4)));
  31. Student satish = new Student("Student2", "Satish T",
  32. "Hiker, Programmer and Architect", new ArrayList<>(Arrays
  33. .asList(course1, course2, course3, course4)));
  34. students.add(ranga);
  35. students.add(satish);
  36. }
  37. public List<Student> retrieveAllStudents() {
  38. return students;
  39. }
  40. public Student retrieveStudent(String studentId) {
  41. for (Student student : students) {
  42. if (student.getId().equals(studentId)) {
  43. return student;
  44. }
  45. }
  46. return null;
  47. }
  48. public List<Course> retrieveCourses(String studentId) {
  49. Student student = retrieveStudent(studentId);
  50. if (student == null) {
  51. return null;
  52. }
  53. return student.getCourses();
  54. }
  55. public Course retrieveCourse(String studentId, String courseId) {
  56. Student student = retrieveStudent(studentId);
  57. if (student == null) {
  58. return null;
  59. }
  60. for (Course course : student.getCourses()) {
  61. if (course.getId().equals(courseId)) {
  62. return course;
  63. }
  64. }
  65. return null;
  66. }
  67. private SecureRandom random = new SecureRandom();
  68. public Course addCourse(String studentId, Course course) {
  69. Student student = retrieveStudent(studentId);
  70. if (student == null) {
  71. return null;
  72. }
  73. String randomId = new BigInteger(130, random).toString(32);
  74. course.setId(randomId);
  75. student.getCourses().add(course);
  76. return course;
  77. }
  78. }
复制代码

src/main/java/com/in28minutes/springboot/StudentServicesApplication.java

  1. package com.in28minutes.springboot;
  2. import org.springframework.boot.SpringApplication;
  3. import org.springframework.boot.autoconfigure.SpringBootApplication;
  4. @SpringBootApplication
  5. public class StudentServicesApplication {
  6. public static void main(String[] args) {
  7. SpringApplication.run(StudentServicesApplication.class, args);
  8. }
  9. }
复制代码

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持程序员之家。



回复

使用道具 举报