簡介:本文將幫助您使用 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:不應該更新任何東西。應該是冪等的(多次調用相同的結果)??赡艿姆祷卮a 200(ok)+ 404(not found)+400(bad request)
post:應該創建新的資源。理想情況下返回 json 和鏈接到新創建的資源。盡可能使用相同的返回碼。另外:返回碼 201(創建)是可能的。
put:更新已知資源。例如:更新客戶詳細信息??赡艿姆祷卮a: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