Spring Data REST的实际应用

什么是春天数据休息?

spring-data-rest是spring-data项目的新增功能,它是一个框架,可帮助您将实体直接作为RESTful Web服务端点公开。 与rails,grails或roo不同,它不会生成任何实现此目标的代码。 spring data-rest支持JPA,MongoDB,JSR-303验证, HAL等。 它确实具有创新性,可让您在几分钟内设置RESTful Web服务。 在此示例中,我将简要概述spring-data-rest的功能。

初始配置

我将使用新的Servlet 3 Java Web Configuration而不是古老的web.xml。 这里没什么特别的。

public class WebAppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {@Overrideprotected Class<?>[] getRootConfigClasses() {return new Class<?>[]{AppConfiguration.class};}@Overrideprotected Class<?>[] getServletConfigClasses() {return new Class[]{WebConfiguration.class};}@Overrideprotected String[] getServletMappings() {return new String[]{"/"};}
}

GitHub上的WebAppInitializer.java

我正在将hibernate初始化为AppConfiguration类中的数据库抽象层。 我使用的是嵌入式数据库( hsql ),因为我想使此演示文稿保持简单愚蠢。 不过,这里没有什么特别的。

@Configuration
@EnableJpaRepositories
@EnableTransactionManagement
public class AppConfiguration {@Beanpublic DataSource dataSource() {EmbeddedDatabaseBuilder builder = new EmbeddedDatabaseBuilder();return builder.setType(EmbeddedDatabaseType.HSQL).build();}@Beanpublic LocalContainerEntityManagerFactoryBean entityManagerFactory() {HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();vendorAdapter.setDatabase(Database.HSQL);vendorAdapter.setGenerateDdl(true);LocalContainerEntityManagerFactoryBean factory = new LocalContainerEntityManagerFactoryBean();factory.setJpaVendorAdapter(vendorAdapter);factory.setPackagesToScan(getClass().getPackage().getName());factory.setDataSource(dataSource());return factory;}@Beanpublic PlatformTransactionManager transactionManager() {return new JpaTransactionManager();}
}

github上的AppConfiguration.java

现在到应用程序servlet配置: WebConfiguration

@Configuration
public class WebConfiguration extends RepositoryRestMvcConfiguration {
}

github上的WebConfiguration.java

哦,那有点短吧? 完整的安装程序不需要一行代码。 这是约定优于配置范式的一个非常好的应用。 现在,我们可以开始创建spring-data-jpa存储库,因为它们将自动显示为RESTful资源。 而且,如果需要,我们仍然可以将自定义配置添加到WebConfiguration类。

初始化真的很简单。 我们不必编写任何特殊的代码。 我们唯一要做的就是建立数据库连接和休眠,这显然是不可避免的。 现在,我们已经设置了“ REST Servlet”和持久性,让我们从模型开始进入应用程序本身。

该模型

我将仅创建两个相关的实体,使其保持非常简单的状态。
bookapi_model

@Entity
public class Book {@Idprivate String isbn;private String title;private String language;@ManyToManyprivate List<Author> authors;}

GitHub上的Book.java

@Entity
public class Author {@Id@GeneratedValue(strategy = GenerationType.SEQUENCE)private Integer id;private String name;@ManyToMany(mappedBy = "authors")private List<Book> books;}

github上的Author.java

为了最终使实体持久化并作为RESTful Web服务公开,我们需要spring-data存储库。 存储库基本上是DAO 。 它为我们的实体提供CRUD功能。 spring-data消除了创建此类存储库的大部分编程工作。 我们只需要定义一个空接口,spring-data即可完成其他所有工作。 尽管如此,由于其设计优于配置,因此易于定制。

实际仓库

@RestResource(path = "books", rel = "books")
public interface BookRepository extends PagingAndSortingRepository<Book, Long> {
}

GitHub上的BookRepository.java

@RestResource(path = "authors", rel = "authors")
public interface AuthorRepository extends PagingAndSortingRepository<Author, Integer> {
}

GitHub上的AuthorRepository.java

同样,几乎不需要代码。 甚至@RestResource注释也可以被忽略。 但是,如果我这样做了,路径和rel将以我不想要的实体命名。 但是,包含多个子项的REST资源应命名为复数。

访问结果

我们的RESTful Web服务现在可以部署了。 运行后,它将在根目录上列出所有可用资源,因此您可以从那里导航。

获取http:// localhost:8080 /

{"links" : [ {"rel" : "books","href" : "http://localhost:8080/books"}, {"rel" : "authors","href" : "http://localhost:8080/authors"} ],"content" : [ ]
}

精细! 现在让我们创建一个作者和一本书。

POST http:// localhost:8080 / authors

{"name":"Uncle Bob"}

响应

201 Created
Location: http://localhost:8080/authors/1

放置http:// localhost:8080 / books / 0132350882

{"title": "Clean Code","authors": [{"rel": "authors","href": "http://localhost:8080/authors/1"}]
}

响应

201 Created

注意到我是如何使用PUT创建书的? 这是因为其ID是实际的isbn。 我必须告诉服务器要使用哪个isbn,因为他无法猜测。 我为作者使用了POST,因为他的ID只是自动生成的一个增量数字。 另外,我使用了一个链接来连接这本书( / books / 0132350882 )和作者( / authors / 1 )。 基本上,这就是超媒体的全部意义:链接用于实体之间的导航和关系。

现在,让我们看看这本书是否是相应创建的。

GET http:// localhost:8080 / books

{"links" : [ ],"content" : [ {"links" : [ {"rel" : "books.Book.authors","href" : "http://localhost:8080/books/0132350882/authors"}, {"rel" : "self","href" : "http://localhost:8080/books/0132350882"} ],"title" : "Clean Code"} ],"page" : {"size" : 20,"totalElements" : 1,"totalPages" : 1,"number" : 1}
}

精细!

这是一个集成测试,将自动执行以下步骤。 它也可以在github的示例中找到。

public class BookApiIT {private final RestTemplate restTemplate = new RestTemplate();private final String authorsUrl = "http://localhost:8080/authors";private final String booksUrl = "http://localhost:8080/books";@Testpublic void testCreateBookWithAuthor() throws Exception {final URI authorUri = restTemplate.postForLocation(authorsUrl, sampleAuthor()); // create Authorfinal URI bookUri = new URI(booksUrl + "/" + sampleBookIsbn);restTemplate.put(bookUri, sampleBook(authorUri.toString())); // create Book linked to AuthorResource<Book> book = getBook(bookUri);assertNotNull(book);final URI authorsOfBookUri = new URI(book.getLink("books.Book.authors").getHref());Resource<List<Resource<Author>>> authors = getAuthors(authorsOfBookUri);assertNotNull(authors.getContent());assertFalse(authors.getContent().isEmpty()); // check if /books/0132350882/authors contains an author}private String sampleAuthor() {return "{\"name\":\"Robert C. Martin\"}";}private final String sampleBookIsbn = "0132350882";private String sampleBook(String authorUrl) {return "{\"title\":\"Clean Code\",\"authors\":[{\"rel\":\"authors\",\"href\":\"" + authorUrl + "\"}]}";}private Resource<Book> getBook(URI uri) {return restTemplate.exchange(uri, HttpMethod.GET, null, new ParameterizedTypeReference<Resource<Book>>() {}).getBody();}private Resource<List<Resource<Author>>> getAuthors(URI uri) {return restTemplate.exchange(uri, HttpMethod.GET, null, new ParameterizedTypeReference<Resource<List<Resource<Author>>>>() {}).getBody();}
}

GitHub上的BookApiIT.java

结论

我们已经创建了完整的RESTful Web服务,而无需花费很多代码。 我们只是定义了实体和数据库连接。 spring-data-rest表示,其他所有内容都只是样板,我同意。

要手动使用Web服务,请考虑rest-shell 。 它是一个命令外壳,它使您的Web服务中的导航尽可能轻松有趣。 这是屏幕截图:
rest_shell
完整的示例可以在我的github上找到 https://github.com/gregorriegler/babdev-spring/tree/master/spring-data-rest https://github.com/gregorriegler/babdev-spring

参考: “ 成为更好的开发者”博客上的JCG合作伙伴 Gregor Riegler提供的Spring Data REST in Action 。

翻译自: https://www.javacodegeeks.com/2013/08/spring-data-rest-in-action.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/367408.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

2018上半年掘金微信群日报优质文章合集:前端篇

在掘金微信交流群里的小伙伴们&#xff0c;你们每天都还在坚持读小报吗&#xff1f;如果你的回答是yes&#xff0c;那真的要给你点一万个赞了?能坚持这么久&#xff0c;真的很优秀噢&#xff01;&#xff08;嗯&#xff0c;每天坚持给大家收集文章的小饼也很优秀?&#xff09…

linux运维笔试题目,linux运维相关的笔试题目_笔试题目

一、Linux系统和shell1、写一个sed命令&#xff0c;修改/tmp/input.txt文件的内容&#xff0c;要求&#xff1a;①删除所有空行&#xff1b;②在非空行前面加一个“AAA”&#xff0c;在行尾加一个“BBB”&#xff0c;即将内容为“11111”的一行改为&#xff1a;“AAA11111BBB”…

python之路--day17-shelve,xml和re模块

shelve模块 shelve模块只有一个open函数&#xff0c;返回类似字典的对象&#xff0c;可读可写&#xff0c;key必须为字符串&#xff0c;而值可以是python所支持的数据类型 1 import shelve2 # info1{age:18,height:180,weight:80}3 # info2{age:73,height:150,weight:80}4 #5 #…

20172314 2018-2019-1《程序设计与数据结构》第一周学习总结

教材学习内容总结 概述 软件工程&#xff1a;是一门关于高质量软件开发的技术和理论的学科&#xff0c;用来控制开发过程&#xff0c;实现高质量的软件。软件工程的目标&#xff1a;正确性、可靠性、健壮性、可用性、可维护性、可重用性、可移植性、运行效率。 对于可靠性和健壮…

activiti api文档_【白银人机】Activiti 工作流从入门到入土:完整 hello world 大比拼(API 结合实例讲解)...

点击上方“好好学java”&#xff0c;选择“置顶”公众号重磅资源、干货&#xff0c;第一时间送达重磅推荐 ① 纯福利 | 公众号资源大汇总&#xff0c;一年才一次&#xff01;② 重磅&#xff01;&#xff01;2018年Java全套入门到进阶学习视频及项目实战③ 2018年java架构师学习…

前端解读控制反转(IOC)

前言 随着前端承担的职责越来越重&#xff0c;前端应用向着复杂化、规模化的方向发展。大型项目模块化是一种趋势&#xff0c;不可避免模块之间要相互依赖&#xff0c;此外还有很多第三方包。这样的话如何去管理这些繁杂的文件&#xff0c;是一个不可避免的话题。此时作为一种…

ASP.NET MVC传递参数(model), 如何保持TempData的持久性

一看到此标题&#xff0c;相信你也会。因为路由是可以从URL地址栏传过去的。但是Insus.NET不想在地址栏传递&#xff0c;还是一个条件是jQuery的Ajax进行POST的。Insus.NET不清楚别人是怎样处理的&#xff0c;但是这个让Insus.NET花上不少时间来解决。Insus.NET实现的方法也很简…

深度学习语音降噪方法对比_人工智能-关于深度学习的基础方法

深度学习概述深度学习的一些简介&#xff0c;其要点如下&#xff1a;深度学习实际上是基于具有多个隐藏层的神经网络的学习&#xff1b;深度学习的思想来源于人类处理视觉信息的方式&#xff1b;深度学习的发展得益于数据的井喷和计算力的飙升&#xff1b;深度学习的理论基础依…

通过adb巧用monkey获取android设备中所有应用的主activity

由于工作需要&#xff0c;想获取所有应用的activity(这里仅限应用的主入口Launcher activity)&#xff0c;搜索了一下&#xff0c;网上实现的方案都是基于android编程实现的&#xff0c;对于不懂开发的测试来说稍有难度&#xff0c;而且对于PC端测试工具来说可行性略差。 给大家…

PWA · 前后端协作 · Node | JTalk 掘金线下活动第七期

通知 余票仅剩 3张&#xff0c;欢迎加入活动群获取更多通知。北京的小伙伴可以关注我们的 JTalk 第八期&#xff1a;前端安全 | 美团点评技术团队专场 ? 报名 扫码报名&#xff1a; 报名链接&#xff1a;点我报名 ? 介绍 本期 JTalk 来杭州啦&#xff01; 掘金线下活动 J…

指数函数中x的取值范围_基本初等函数I: 指数函数、对数函数和幂函数

本文大约4800字, 建议学习时间1个小时.在学习过一次函数和二次函数(修改版)后, 我们知道, 一次函数ykxb当一次项系数k大于零时是增函数, 小于零时是减函数. 二次函数yax2bxc当二次项系数a大于零时图象沿x轴从左向右先减后增, a小于零时先增后减. 可以想象, 次数更高的函数, 在定…

Linux系统之TroubleShooting(启动故障排除)

尽管Linux系统非常强大&#xff0c;稳定&#xff0c;但是我们在使用过程当中&#xff0c;如果人为操作不当&#xff0c;仍然会影响系统&#xff0c;甚至可能使得系统无法开机&#xff0c;无法运行服务等等各种问题。那么这篇博文就总结一下一些常见的故障排除方法&#xff0c;但…

皮肤可配置化:变量、样式分离

之前皮肤开发了一个版本&#xff0c;抽是抽出来了&#xff0c;但是变量只抽出了几个颜色&#xff0c;没什么价值&#xff08;上个版本开发过程&#xff09;&#xff0c; 这次我又进行了一次迭代&#xff0c;现在是一个较成熟的版本了。整体理一下思路&#xff0c;可以总结为3步…

【考试记录】4.8 Path (网络流 —— 劲题)

手抄代码 学习指针 冥思苦想一晚上终于——在一瞬间开窍了。果然题目都是这样&#xff1a;突破了一个点&#xff0c;一切都是柳暗花明。 题面描述&#xff1a; 样例&#xff1a; 这道题目&#xff0c;首先注意到给定的边的性质&#xff1a;这些边在平面上构成了一棵树&#x…

Servlet 3.0概述

Servlet 3.0 –具有许多突破性的功能&#xff0c;这些功能最终将改变开发人员编写和编写JEE Web应用程序的方式–有人可能会说&#xff0c;它的约定违背了我们对事物在理论上“应该”如何工作的大多数理解&#xff0c;但这就是其中之一。创新和持续改进&#xff1b; 挑战公约并…

MySQL(介绍,安装,密码操作,权限表)

一、数据库介绍1、数据库相关概念a、支持并发b、锁的问题c、对客户端请求进行认证d、存取效率&#xff08;降低IO次数&#xff09;数据库服务器&#xff08;本质就是一个台计算机&#xff0c;该计算机之上安装有数据库管理软件的服务端&#xff09;数据库管理管理系统RDBMS&…

matlab如何测两点的角度_【邢不行|量化小讲堂系列01-Python量化入门】如何快速上手使用Python进行金融数据分析...

引言:邢不行的系列帖子“量化小讲堂”&#xff0c;通过实际案例教初学者使用python进行量化投资&#xff0c;了解行业研究方向&#xff0c;希望能对大家有帮助。【历史文章汇总】请点击此处【必读文章】&#xff1a;【邢不行|量化小讲堂系列27-Python量化入门】EOS期现套利&…

结对项目

一、【Coding.Net项目地址】https://git.coding.net/verde/Pair_Work.git 二、【对接口进行的设计】 看教科书和其它资料中关于Information Hiding, Interface Design, Loose Coupling的章节&#xff0c;说明你们在结对编程中是如何利用这些方法对接口进行设计的。 如下图SRC的…

国家开放大学形成性考核 统一资料 参考试题

试卷代号&#xff1a;1174 水工钢筋混凝土结构&#xff08;本&#xff09;参考试题 一、选择题&#xff08;每小题2分&#xff0c;共20分&#xff0c;在所列备选项中&#xff0c;选1项正确的或最好的作为答案&#xff0c;将选项号填入各题的括号中&#xff09; 1.钢筋混凝土结…

两个向量之间的夹角公式_向量的内积

向量的内积也叫向量的数量积、点积。我们定义两个向量的内积是一个数: 其中 是这两个向量的夹角。 对于向量的内积,最重要的一个结论是: 定理1:两向量垂直的充分必要条件是它们的内积为 0,即 这个定理我们几乎不用证明了,因为从定义来看,如果两个向量都不零向量,则只能…