SpringCloud應(yīng)用骨架開(kāi)發(fā)詳解
我們每做一個(gè)新項(xiàng)目,通常都是從另一個(gè)項(xiàng)目把代碼拷貝過(guò)來(lái),然后在其上做開(kāi)發(fā)。但是這種模式的一個(gè)比較大的問(wèn)題就是會(huì)有很多上個(gè)項(xiàng)目的遺留代碼。因此,開(kāi)發(fā)一個(gè)公共的應(yīng)用骨架系統(tǒng),在開(kāi)始其他新項(xiàng)目時(shí),從這個(gè)骨架系統(tǒng)開(kāi)始開(kāi)發(fā),是一個(gè)很好的選擇。
我們首先需要?jiǎng)?chuàng)建一個(gè)SpringBoot工程,我們可以使用:https://start.spring.io/
如下所所:
上圖中比較關(guān)鍵的是從頁(yè)面右側(cè)“Add Dependencies”按鈕彈出的列表中選擇“Spring Web”。網(wǎng)站上的工具會(huì)生成一個(gè)基本的SpringBoot工程,并自動(dòng)將zip文件下載到本地。
將該文件解壓,以idea community版本打開(kāi)(也可以使用商業(yè)版,但是該版本是收費(fèi)版,出于尊重知識(shí)產(chǎn)權(quán)的原因,使用免費(fèi)的社區(qū)版)。
我們首先將系統(tǒng)自帶的src/main/resources下面的application.properties文件刪除,添加application.yaml文件,添加如下內(nèi)容:
server: port: ${port:2208} spring: application: name: first-service logging: pattern: console: "%d{HH:mm:ss.SSS} %-5level %logger{36} - %msg%n" file: "%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n" level: org.springframework.web: DEBUG file: app.log
下面我們以Person對(duì)象的增、刪、改、查操作為例,創(chuàng)建一個(gè)REST風(fēng)格的API。
我們首先在repository包中創(chuàng)建Person對(duì)象:
public class Person { private Long personId; private String firstName; private String lastName; private int age; // getter and setters //...... }
接下來(lái)我們來(lái)創(chuàng)建REST服務(wù)端,在controller包中創(chuàng)建DemoController類:
@RestController @RequestMapping("/person") public class DemoController { private List<Person> persons = new ArrayList<>(); @GetMapping public List<Person> findAll() { return persons; } @GetMapping("/{personId}") public Person findById(@PathVariable("personId") Long personId, HttpServletRequest request) { String mode = request.getParameter("mode"); System.out.println("mode=" + mode + "!"); return persons.stream().filter(item -> item.getPersonId().equals(personId)).findFirst().get(); } @PostMapping public Person add(@RequestBody Person p) { p.setPersonId((long)(persons.size()+1)); persons.add(p); return p; } @DeleteMapping("/{personId}") public void delete(@PathVariable("personId") Long personId) { List<Person> ps = persons.stream().filter(item -> item.getPersonId(). equals(personId)).collect(Collectors.toList()); persons.removeAll(ps); } @PutMapping public void update(@RequestBody Person p) { Optional<Person> person = persons.stream().filter(item -> item.getPersonId(). equals(p.getPersonId())).findFirst(); person.ifPresent(po->persons.set(persons.indexOf(po), p)); } }
由于用到了Jdk8以后的一些特性,這里稍做一些解釋:
- 第1行:代表其是一個(gè)REST風(fēng)格服務(wù)的類;
- 第2行:規(guī)定所有/person開(kāi)頭的請(qǐng)求,都由本類來(lái)進(jìn)行處理;
- 第4行:使用泛型技術(shù)定義Person列表對(duì)象屬性;
- 第6~9行:定義http://server/person請(qǐng)求,返回Json格式Person列表;
- 第11行:定義http://server/person/101?mode=2形式的請(qǐng)求,首先定義路徑中包含的參數(shù)101為personId,分別在GetMapping和函數(shù)參數(shù)中用@RequestParam來(lái)定義,其次請(qǐng)求中的queryString使用函數(shù)形參中的第二個(gè)參數(shù)HttpServletRequest來(lái)獲??;
- 第14、15行:獲取QueryString中的mode參數(shù);
- 第16行:在過(guò)去,我們?nèi)缫雽?duì)List對(duì)象進(jìn)行查找,需要自己遍歷List對(duì)象,在Jdk8之后,提供了Stream API,可以幫助我們更加高效的進(jìn)行查找。首先創(chuàng)建stream,這里其實(shí)還可以指定是否使用.parellel()并行技術(shù)來(lái)利用CPU的多核特性。然后在filter中定義查詢條件,該查詢條件是一個(gè)Lambda表達(dá)式,也是Jdk8之后引入的新特性,就是對(duì)列表中的每個(gè)元素item,首先獲取personId屬性,然后與personId參數(shù)進(jìn)行比較,取相等的記錄,由于相等的記錄可能存在多條,我們用findFirst來(lái)取第一條,其返回結(jié)果為Optional類型,Optional同樣是Jdk8之后引入的新特性,專門用于避免空指針異常。我們這里,我們非常確信其一定包括Person對(duì)象,所以通過(guò).get函數(shù)獲取出Person對(duì)象,并返回;
- 第19行:在REST風(fēng)格中,POST請(qǐng)求用于添加新對(duì)象;
- 第20行:在缺省情況下,POST請(qǐng)求的內(nèi)容通過(guò)application/json傳遞,即客戶端需要將內(nèi)容轉(zhuǎn)換為Json格式,放入POST的請(qǐng)求體中,SpringBoot會(huì)自動(dòng)將請(qǐng)求體的Json內(nèi)容轉(zhuǎn)化為@RequestBody指定的值對(duì)象;
- 第26行:在REST風(fēng)格中,DELETE請(qǐng)求用于刪除對(duì)象,即當(dāng)用戶發(fā)送的請(qǐng)求為DELETE /person/101 HTTP/1.0時(shí),代表刪除personId=101的對(duì)象;
- 第27行:定義delete函數(shù),獲取請(qǐng)求路徑上的personId參數(shù);
- 第28、29行:求出符合查詢條件的Person對(duì)象列表,同樣是先用成stream,在filter中定義查詢條件,最后通過(guò)collect函數(shù)將查詢結(jié)果轉(zhuǎn)換為列表;
- 第30行:從persons列表中刪除符合條件記錄;
- 第33行:在REST風(fēng)格中,用PUT請(qǐng)求來(lái)進(jìn)行對(duì)象更新;
- 第34行:通過(guò)請(qǐng)求體中的Json字符串,由SpringBoot自動(dòng)創(chuàng)建Person值對(duì)象;
- 第35、36行:查詢出符合條件的記錄,類型為Optional,在這里我們雖然可以使用if (ps.ifPresent()) {…},但是這和過(guò)去null的處理方式?jīng)]有什么區(qū)別,我們采用更Jdk8的形式,在ifPresent函數(shù)中提供了Lambda表達(dá)式,這義了對(duì)象更新邏輯;
我們下面需要對(duì)REST服務(wù)進(jìn)行測(cè)試,我們可以通過(guò)PostMan來(lái)進(jìn)行測(cè)試,但是在這里,我們將采用Swagger來(lái)進(jìn)行測(cè)試。這樣做主要好處是可以同時(shí)生成REST服務(wù)的文檔。
我們首先在項(xiàng)目根目錄下的pom.xml中添加如下內(nèi)容:
<!-- 開(kāi)始:添加Swagger支持 --> <dependency> <groupId>io.springfox</groupId> <artifactId>springfox-swagger2</artifactId> <version>2.7.0</version> </dependency> <dependency> <groupId>io.springfox</groupId> <artifactId>springfox-swagger-ui</artifactId> <version>2.7.0</version> </dependency> <!-- 結(jié)束:添加Swagger支持 --> <!-- 開(kāi)始:讀取maven pox.xml文件 --> <dependency> <groupId>org.apache.maven</groupId> <artifactId>maven-model</artifactId> <version>3.0</version> </dependency> <!-- 結(jié)束:讀取maven pox.xml文件 -->
同時(shí)給應(yīng)用類StpApplication添加如下標(biāo)注:
@EnableSwagger2 @SpringBootApplication public class StpApplication { ...... @Bean public Docket api() throws IOException, XmlPullParserException { MavenXpp3Reader reader = new MavenXpp3Reader(); Model model = reader.read(new FileReader("pom.xml")); ApiInfoBuilder builder = new ApiInfoBuilder() .title("智慧交通平臺(tái)") .description("智慧交通平臺(tái)API接口文檔") .version(model.getVersion()) .contact(new Contact("最老程序員", "www.abc.com", "ua@")); return new Docket(DocumentationType.SWAGGER_2).select(). apis(RequestHandlerSelectors.basePackage("com.zhuanjingkj.stp.demo.controller")) .paths(PathSelectors.any()).build() .apiInfo(builder.build()); } }
就是添加@EnableSwagger2標(biāo)注信息。在瀏覽器中輸入如下地址:http://localhost:2208/swagger-ui.html
會(huì)顯示如下圖所示頁(yè)面:
我們可以點(diǎn)擊進(jìn)入對(duì)應(yīng)的接口,可以看到接口的調(diào)用方法,同時(shí)可以填寫真實(shí)的數(shù)據(jù),對(duì)接口進(jìn)行測(cè)試。
到此這篇關(guān)于SpringCloud應(yīng)用骨架開(kāi)發(fā)詳解的文章就介紹到這了,更多相關(guān)SpringCloud應(yīng)用骨架 內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
springboot使用logback文件查看錯(cuò)誤日志過(guò)程詳解
這篇文章主要介紹了springboot使用logback文件查看錯(cuò)誤日志過(guò)程詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2019-09-09

在已有spring的基礎(chǔ)上集成hibernate的實(shí)例講解

Java使用正則表達(dá)式判斷字符串是否以字符開(kāi)始

java監(jiān)聽(tīng)器的實(shí)現(xiàn)和原理詳解

Java中繼承thread類與實(shí)現(xiàn)Runnable接口的比較