简介:本文将帮助您使用 spring boot 创建简单的 rest 服务。
你将学习
- 什么是 rest 服务?
- 如何使用 spring initializr 引导创建 rest 服务应用程序?
- 如何创建获取 rest 服务以检索学生注册的课程?
- 如何为学生注册课程创建 post rest 服务?
- 如何利用 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 请求来为学生注册一门课程
您将需要的工具
- maven 3.0+ 是您的构建工具
- 你最喜欢的 ide。我们使用 eclipse。
- 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 的五个重要条件:
- 客户端 - 服务器:应该有一个服务生产者和一个服务使用者。
- 接口(url)是统一的并且暴露资源。
- 该服务是无状态的。
- 服务结果应该是可缓存的。例如 http 缓存。
- 服务应该采用分层架构。客户端不应该直接连接到服务器 - 它可能从中间层获取信息 - 缓存。
理查森成熟度模型
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:用于删除资源。
项目结构
以下屏幕截图显示了我们将创建的项目的结构。
一些细节:
- studentcontroller.java - rest 控制器提供上面讨论的所有三种服务方法。
- course.java, student.java, studentservice.java - 应用程序的业务逻辑。studentservice 提供了一些我们从 rest 控制器中消耗的方法。
- studentcontrollerit.java - rest 服务的集成测试。
- studentcontrollertest.java - test 服务的单元测试。
- studentservicesapplication.java - spring boot 应用程序的启动器。要运行该应用程序,只需将该文件作为 java 应用程序启动。
- 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
选择以下依赖项
- web
- actuator
- 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。
- src/main/java/com/in28minutes/springboot/model/course.java
- src/main/java/com/in28minutes/springboot/model/student.java
- src/main/java/com/in28minutes/springboot/service/studentservice.java
添加几个 get rest 服务
rest 服务 studentcontroller 暴露了几个 get 服务。
- @autowired private studentservice studentservice :我们使用 spring autowiring 将 student 服务自动注入到 studentcontroller。
- @getmapping(“/students/{studentid}/courses”):以 studentid 作为路径变量公开获取服务
- @getmapping(“/students/{studentid}/courses/{courseid}”):公开获取服务以检索学生的特定课程。
- @pathvariable string studentid:来自 uri 的 studentid 的值将映射到此参数。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
|
package com.in28minutes.springboot.controller; import java.util.list; import org.springframework.beans.factory.annotation.autowired; import org.springframework.web.bind.annotation.getmapping; import org.springframework.web.bind.annotation.pathvariable; import org.springframework.web.bind.annotation.restcontroller; import com.in28minutes.springboot.model.course; import com.in28minutes.springboot.service.studentservice; @restcontroller public class studentcontroller { @autowired private studentservice studentservice; @getmapping ( "/students/{studentid}/courses" ) public list<course> retrievecoursesforstudent( @pathvariable string studentid) { return studentservice.retrievecourses(studentid); } @getmapping ( "/students/{studentid}/courses/{courseid}" ) public course retrievedetailsforcourse( @pathvariable string studentid, @pathvariable string courseid) { return studentservice.retrievecourse(studentid, courseid); } } |
使用 postman 执行获取服务
我们将向 http:// localhost:8080 / students / student1 / courses / course1 发起请求以测试该服务。回应如下所示。
1
2
3
4
5
6
7
8
9
10
11
|
{ "id" : "course1" , "name" : "spring" , "description" : "10 steps" , "steps" : [ "learn maven" , "import project" , "first example" , "second example" ] } |
下面的图片显示了我们如何执行 postman 的 get service - 我最喜欢的运行 rest 服务的工具。
添加 post rest 服务
当资源创建成功时,post 服务应该返回创建的状态(201)。
- @postmapping(“/students/{studentid}/courses”):为 post 请求映射 url
- @requestbody course newcourse:使用绑定将请求正文绑定到课程对象。
- responseentity.created(location).build():返回已创建的状态。还将创建资源的位置作为响应标题返回。
1
2
3
4
5
6
7
8
9
10
11
|
@postmapping ( "/students/{studentid}/courses" ) public responseentity< void > registerstudentforcourse( @pathvariable string studentid, @requestbody course newcourse) { course course = studentservice.addcourse(studentid, newcourse); if (course == null ) return responseentity.nocontent().build(); uri location = servleturicomponentsbuilder.fromcurrentrequest().path( "/{id}" ).buildandexpand(course.getid()).touri(); return responseentity.created(location).build(); } |
执行 post rest 服务
示例请求如下所示。它包含了学生注册课程的所有细节。
1
2
3
4
5
6
7
8
9
|
{ "name" : "microservices" , "description" : "10 steps" , "steps" : [ "learn how to break things up" , "automate the hell out of everything" , "have fun" ] } |
下图显示了我们如何从 postman 执行 post 服务 - 我最喜欢的运行 rest 服务的工具。确保你去 body 选项卡并选择 raw。从下拉菜单中选择 json。将上述请求复制到 body 中。
我们使用的 url 是 http:// localhost:8080 / students / student1 / courses。
完整的代码示例
pom.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
|
<?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.in28minutes.springboot</groupid> <artifactid>student-services</artifactid> <version> 0.0 . 1 -snapshot</version> <packaging>jar</packaging> <name>student-services</name> <description>demo project for spring boot</description> <parent> <groupid>org.springframework.boot</groupid> <artifactid>spring-boot-starter-parent</artifactid> <version> 1.4 . 4 .release</version> <relativepath/> <!-- lookup parent from repository --> </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-actuator</artifactid> </dependency> <dependency> <groupid>org.springframework.boot</groupid> <artifactid>spring-boot-starter-web</artifactid> </dependency> <dependency> <groupid>org.springframework.boot</groupid> <artifactid>spring-boot-devtools</artifactid> <scope>runtime</scope> </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> |
src/main/java/com/in28minutes/springboot/controller/studentcontroller.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
|
import java.net.uri; import java.util.list; import org.springframework.beans.factory.annotation.autowired; import org.springframework.http.responseentity; import org.springframework.web.bind.annotation.getmapping; import org.springframework.web.bind.annotation.pathvariable; import org.springframework.web.bind.annotation.postmapping; import org.springframework.web.bind.annotation.requestbody; import org.springframework.web.bind.annotation.restcontroller; import org.springframework.web.servlet.support.servleturicomponentsbuilder; import com.in28minutes.springboot.model.course; import com.in28minutes.springboot.service.studentservice; @restcontroller public class studentcontroller { @autowired private studentservice studentservice; @getmapping ( "/students/{studentid}/courses" ) public list<course> retrievecoursesforstudent( @pathvariable string studentid) { return studentservice.retrievecourses(studentid); } @getmapping ( "/students/{studentid}/courses/{courseid}" ) public course retrievedetailsforcourse( @pathvariable string studentid, @pathvariable string courseid) { return studentservice.retrievecourse(studentid, courseid); } @postmapping ( "/students/{studentid}/courses" ) public responseentity< void > registerstudentforcourse( @pathvariable string studentid, @requestbody course newcourse) { course course = studentservice.addcourse(studentid, newcourse); if (course == null ) return responseentity.nocontent().build(); uri location = servleturicomponentsbuilder.fromcurrentrequest().path( "/{id}" ).buildandexpand(course.getid()).touri(); return responseentity.created(location).build(); } } |
src/main/java/com/in28minutes/springboot/model/course.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
|
import java.util.list; public class course { private string id; private string name; private string description; private list<string> steps; // needed by caused by: com.fasterxml.jackson.databind.jsonmappingexception: // can not construct instance of com.in28minutes.springboot.model.course: // no suitable constructor found, can not deserialize from object value // (missing default constructor or creator, or perhaps need to add/enable // type information?) public course() { } public course(string id, string name, string description, list<string> steps) { super (); this .id = id; this .name = name; this .description = description; this .steps = steps; } public string getid() { return id; } public void setid(string id) { this .id = id; } public string getdescription() { return description; } public string getname() { return name; } public list<string> getsteps() { return steps; } @override public string tostring() { return string.format( "course [id=%s, name=%s, description=%s, steps=%s]" , id, name, description, steps); } @override public int hashcode() { final int prime = 31 ; int result = 1 ; result = prime * result + ((id == null ) ? 0 : id.hashcode()); return result; } @override public boolean equals(object obj) { if ( this == obj) return true ; if (obj == null ) return false ; if (getclass() != obj.getclass()) return false ; course other = (course) obj; if (id == null ) { if (other.id != null ) return false ; } else if (!id.equals(other.id)) return false ; return true ; } } |
src/main/java/com/in28minutes/springboot/model/student.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
|
package com.in28minutes.springboot.model; import java.util.list; public class student { private string id; private string name; private string description; private list<course> courses; public student(string id, string name, string description, list<course> courses) { super (); this .id = id; this .name = name; this .description = description; this .courses = courses; } 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; } public string getdescription() { return description; } public void setdescription(string description) { this .description = description; } public list<course> getcourses() { return courses; } public void setcourses(list<course> courses) { this .courses = courses; } @override public string tostring() { return string.format( "student [id=%s, name=%s, description=%s, courses=%s]" , id, name, description, courses); } } |
src/main/java/com/in28minutes/springboot/service/studentservice.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
|
package com.in28minutes.springboot.service; import java.math.biginteger; import java.security.securerandom; import java.util.arraylist; import java.util.arrays; import java.util.list; import org.springframework.stereotype.component; import com.in28minutes.springboot.model.course; import com.in28minutes.springboot.model.student; @component public class studentservice { private static list<student> students = new arraylist<>(); static { //initialize data course course1 = new course( "course1" , "spring" , "10 steps" , arrays .aslist( "learn maven" , "import project" , "first example" , "second example" )); course course2 = new course( "course2" , "spring mvc" , "10 examples" , arrays.aslist( "learn maven" , "import project" , "first example" , "second example" )); course course3 = new course( "course3" , "spring boot" , "6k students" , arrays.aslist( "learn maven" , "learn spring" , "learn spring mvc" , "first example" , "second example" )); course course4 = new course( "course4" , "maven" , "most popular maven course on internet!" , arrays.aslist( "pom.xml" , "build life cycle" , "parent pom" , "importing into eclipse" )); student ranga = new student( "student1" , "ranga karanam" , "hiker, programmer and architect" , new arraylist<>(arrays .aslist(course1, course2, course3, course4))); student satish = new student( "student2" , "satish t" , "hiker, programmer and architect" , new arraylist<>(arrays .aslist(course1, course2, course3, course4))); students.add(ranga); students.add(satish); } public list<student> retrieveallstudents() { return students; } public student retrievestudent(string studentid) { for (student student : students) { if (student.getid().equals(studentid)) { return student; } } return null ; } public list<course> retrievecourses(string studentid) { student student = retrievestudent(studentid); if (student == null ) { return null ; } return student.getcourses(); } public course retrievecourse(string studentid, string courseid) { student student = retrievestudent(studentid); if (student == null ) { return null ; } for (course course : student.getcourses()) { if (course.getid().equals(courseid)) { return course; } } return null ; } private securerandom random = new securerandom(); public course addcourse(string studentid, course course) { student student = retrievestudent(studentid); if (student == null ) { return null ; } string randomid = new biginteger( 130 , random).tostring( 32 ); course.setid(randomid); student.getcourses().add(course); return course; } } |
src/main/java/com/in28minutes/springboot/studentservicesapplication.java
1
2
3
4
5
6
7
8
9
10
11
|
package com.in28minutes.springboot; import org.springframework.boot.springapplication; import org.springframework.boot.autoconfigure.springbootapplication; @springbootapplication public class studentservicesapplication { public static void main(string[] args) { springapplication.run(studentservicesapplication. class , args); } } |
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持服务器之家。
原文链接:http://www.cnblogs.com/yangactive/p/8607427.html