在SpringBoot中使用HATEOAS的方法
簡(jiǎn)介
HATEOAS是實(shí)現(xiàn)REST規(guī)范的一種原則,通過(guò)遵循HATEOAS規(guī)范,可以解決我們實(shí)際代碼實(shí)現(xiàn)的各種個(gè)問(wèn)題。作為java最流行的框架Spring
當(dāng)然也會(huì)不缺席HATEOAS的集成。
本文將會(huì)通過(guò)一個(gè)具體的例子來(lái)講解如何在SpringBoot中使用HATEOAS。
文章目標(biāo)
HATEOAS規(guī)則中,返回的數(shù)據(jù)會(huì)帶有鏈接。我們以熟悉的Book為例,來(lái)展示這次的HATEOAS,首先創(chuàng)建一個(gè)Book entity:
@Data @Entity public class Book { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; private String title; }
我們希望能夠通過(guò)下面的鏈接來(lái)獲取到Book的詳細(xì)數(shù)據(jù):
GET /book/1
返回的數(shù)據(jù)如下:
{ "content": { "id": 1, "title": "The Hobbit" }, "_links": { "self": { "href": "http://localhost:8080/book/1" } } }
可以看到在返回的數(shù)據(jù)中除了content包含了book的信息之外,還有一個(gè)_links屬性,表示和該Book相關(guān)的資源鏈接。
構(gòu)建Entity和Repository
在做任何數(shù)據(jù)之前,我們都需要構(gòu)建相應(yīng)的數(shù)據(jù),也就是entity和對(duì)應(yīng)的數(shù)據(jù)操作,為了簡(jiǎn)便起見(jiàn),我們使用H2的內(nèi)存數(shù)據(jù)庫(kù)。
我們需要在application.properties中配置如下:
spring.jpa.hibernate.ddl-auto=validate spring.datasource.url=jdbc:h2:mem:testdb spring.datasource.driverClassName=org.h2.Driver spring.datasource.username=sa spring.datasource.password=password spring.jpa.database-platform=org.hibernate.dialect.H2Dialect
然后配置對(duì)應(yīng)的repository :
public interface BookRepository extends CrudRepository<Book, Long> { long deleteByTitle(String title); @Modifying @Query("delete from Book b where b.title=:title") void deleteBooks(@Param("title") String title); }
同時(shí),需要在resources中放置創(chuàng)建table的schema.sql和插入數(shù)據(jù)的data.sql。這樣在程序啟動(dòng)的時(shí)候就可以自動(dòng)創(chuàng)建相應(yīng)的數(shù)據(jù)。
構(gòu)建HATEOAS相關(guān)的RepresentationModel
如果要讓自己來(lái)實(shí)現(xiàn),也可以實(shí)現(xiàn)添加鏈接的操作,但是這樣就太復(fù)雜了,還好我們有Spring。
要在Spring中使用HATEOAS,需要進(jìn)行如下配置:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-hateoas</artifactId> </dependency>
如果我們想要對(duì)Book進(jìn)行HATEOAS的構(gòu)建,那么可以構(gòu)建一個(gè)類,繼承RepresentationModel即可:
public class BookModel extends RepresentationModel<BookModel> { private final Book content; @JsonCreator public BookModel(@JsonProperty("content") Book content) { this.content = content; } public Book getContent() { return content; } }
上面的例子中,我們用RepresentationModel
封裝了一個(gè)Book對(duì)象,并將其設(shè)置為json的content屬性。
構(gòu)建Controller
有了RepresentationModel,我們就可以使用它來(lái)構(gòu)建HATEOAS的響應(yīng)了。
我們看下面的例子:
@RequestMapping("/book/{id}") public HttpEntity<Book> getBook(@PathVariable("id") Long id) { Book book= bookRepository.findById(id).get(); BookModel bookModel = new BookModel(book); bookModel.add(linkTo(methodOn(BookController.class).getBook(id)).withSelfRel()); return new ResponseEntity(bookModel, HttpStatus.OK); }
上面的例子中,我們使用@RequestMapping來(lái)構(gòu)建了一個(gè)HTTP請(qǐng)求,通過(guò)傳入book的id來(lái)從數(shù)據(jù)庫(kù)中查找相應(yīng)的Book數(shù)據(jù)。
然后將其傳入BookModel中,構(gòu)建好RepresentationModel。這時(shí)候可以直接返回這個(gè)對(duì)象。但是我們還需要向其添加一些links。
我們使用bookModel.add來(lái)添加相應(yīng)的link。并且使用linkTo方法來(lái)生成相應(yīng)的link。最后將RepresentationModel返回。當(dāng)我們請(qǐng)求/book/1的時(shí)候,就會(huì)得到最前面我們想要得到的json值。使用HATEOAS是不是很簡(jiǎn)單?
HATEOAS的意義
HATEOAS帶有相應(yīng)的資源鏈接,通過(guò)一個(gè)資源就可以得到從這個(gè)資源可以訪問(wèn)的其他的資源,就像是一個(gè)訪問(wèn)到一個(gè)頁(yè)面,可以再通過(guò)這個(gè)頁(yè)面去訪問(wèn)其他的頁(yè)面一樣。所以HATEOAS的意義就在于我們只需要訪問(wèn)一個(gè)資源就可以遍歷所有的資源。我們通過(guò)測(cè)試來(lái)體驗(yàn)一下資源的訪問(wèn)。
首先,我們直接訪問(wèn)/book/1這個(gè)資源,來(lái)確認(rèn)下得到的結(jié)果:
@Test void envEndpointNotHidden() throws Exception { mockMvc.perform(get("/book/1")) .andExpect(jsonPath("$.content.title").value("The Hobbit")); }
然后再通過(guò)Spring HATEOAS提供的Traverson類來(lái)進(jìn)行鏈接的遍歷:
@Test void envEndpointNotHidden() throws Exception { Traverson traverson = new Traverson(new URI("http://localhost:" + this.port + "/book/1"), MediaTypes.HAL_JSON); String bookTitle = traverson.follow("self").toObject("$.content.title"); assertThat(bookTitle).isEqualTo("The Hobbit"); }
到此這篇關(guān)于在SpringBoot中使用HATEOAS的方法的文章就介紹到這了,更多相關(guān)SpringBoot使用HATEOAS內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Java AQS中ReentrantReadWriteLock讀寫鎖的使用
ReentrantReadWriteLock稱為讀寫鎖,它提供一個(gè)讀鎖,支持多個(gè)線程共享同一把鎖。這篇文章主要講解一下ReentrantReadWriteLock的使用和應(yīng)用場(chǎng)景,感興趣的可以了解一下2023-02-02解析SpringBoot項(xiàng)目開(kāi)發(fā)之Gzip壓縮過(guò)程
這篇文章主要介紹了SpringBoot項(xiàng)目開(kāi)發(fā)之Gzip壓縮過(guò)程,本文給大家分享幾種Gzip壓縮方式,通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-07-07Spring相關(guān)知識(shí)點(diǎn)的總結(jié)與梳理
今天小編就為大家分享一篇關(guān)于Spring相關(guān)知識(shí)點(diǎn)的總結(jié)與梳理,小編覺(jué)得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來(lái)看看吧2019-02-02Java開(kāi)發(fā)之內(nèi)部類對(duì)象的創(chuàng)建及hook機(jī)制分析
這篇文章主要介紹了Java開(kāi)發(fā)之內(nèi)部類對(duì)象的創(chuàng)建及hook機(jī)制,結(jié)合實(shí)例形式分析了java基于hook機(jī)制內(nèi)部類對(duì)象的創(chuàng)建與使用,需要的朋友可以參考下2018-01-01Java?synchronized關(guān)鍵字性能考量及優(yōu)化探索
這篇文章主要為大家介紹了Java?synchronized關(guān)鍵字性能考量及優(yōu)化探索示例分析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-12-12