极端懒惰:使用Spring Boot开发JAX-RS服务

我认为可以公平地说,作为软件开发人员,我们一直在寻找编写较少代码的方法,这些方法可以自动完成或不能自动完成更多工作。 考虑到这一点,作为Spring产品组合的骄傲成员的Spring Boot项目破坏了传统方法,极大地加快了并简化了基于Spring的应用程序的开发。

关于Spring Boot ,还有很多要说的东西 ,关于它如何工作以及如何与大多数(即使不是全部) Spring项目无缝集成的固有细节。 但是它的功能远不止于此,它支持与流行的Java框架进行一流的集成。

在本文中,我们将研究如何将Spring Boot与Apache CXF项目结合使用,以进行快速的REST(ful)Web服务开发。 我们很快就会看到, Spring Boot会处理很多样板,让我们专注于真正有价值的应用程序部分。 希望在本文结尾处,为您的项目采用Spring Boot的好处显而易见。

这样,我们就可以开始开发一个简单的人员管理REST(ful)Web服务 ,并将其包装到熟悉的PeopleRestService JAX-RS资源中:

@Path("/people")
@Component
public class PeopleRestService {@GET@Produces({MediaType.APPLICATION_JSON})public Collection<Person> getPeople() {return Collections.singletonList(new Person("a@b.com", "John", "Smith"));}
}

此处添加的内容不多,是非常简单的实现,它返回人员的硬编码集合。 我们可以通过多种方式打包和部署此JAX-RS服务,但可以说最简单的方法是将其托管在嵌入式servlet容器(例如Tomcat , Jetty或Undertow)中 。 随之而来的是例程:容器初始化,配置Spring上下文位置,注册侦听器,……让我们看看Spring Boot如何通过剖析下面的Spring上下文配置来提供帮助。

@Configuration
@EnableAutoConfiguration
@ComponentScan(basePackageClasses = PeopleRestService.class)
public class AppConfig {@Autowired private PeopleRestService peopleRestService;@Bean(destroyMethod = "shutdown")public SpringBus cxf() {return new SpringBus();}@Bean(destroyMethod = "destroy") @DependsOn("cxf")public Server jaxRsServer() {final JAXRSServerFactoryBean factory = new JAXRSServerFactoryBean();factory.setServiceBean(peopleRestService);factory.setProvider(new JacksonJsonProvider());factory.setBus(cxf());factory.setAddress("/");return factory.create();}@Beanpublic ServletRegistrationBean cxfServlet() {final ServletRegistrationBean servletRegistrationBean = new ServletRegistrationBean(new CXFServlet(), "/api/*");servletRegistrationBean.setLoadOnStartup(1);return servletRegistrationBean;}
}

AppConfig类看起来像一个典型的基于Spring Java的配置,除了这个异常的@EnableAutoConfiguration批注,毫无疑问 ,它来自Spring Boot模块。 在幕后,使用此注释可以进行复杂且智能的猜测,尤其是猜测我们将要运行哪种应用程序以及我们的应用程序可能需要哪种Spring Bean。 有了此配置后,我们只需要为我们的应用程序提供一个运行程序,同时也要具有一些Spring Boot风格:

@SpringBootApplication
public class Application {public static void main(String[] args) {SpringApplication.run(AppConfig.class, args);}
}

有了@SpringBootApplication元注释,并使用SpringApplication初始化我们的Spring上下文,我们有了一个成熟的可运行Java应用程序,可以使用Spring Boot插件从Apache Maven运行该应用程序:

mvn spring-boot:run

或打包为单个可运行的uber- JAR并从命令行调用:

mvn package
java -jar target/jax-rs-2.0-cxf-spring-boot-0.0.1-SNAPSHOT.jar

就是这样,仅需几个注释以及一行代码( main方法)。 一旦运行了应用程序,就可以确保我们的人员管理REST(ful)Web服务已正确部署并且可以正常运行:

$ curl -i http://localhost:8080/api/peopleHTTP/1.1 200 OK
Content-Type: application/json;charset=utf-8
Transfer-Encoding: chunked
Server: Jetty(9.3.8.v20160314)[{"email":"a@b.com","firstName":"John","lastName":"Smith"}]

在这一点上,您可能想知道它是如何工作的? 我们没有在任何地方处理servlet容器,所以Jetty如何满足我们的请求? 事实是,我们只需要包含选择的容器作为依赖项即可,例如使用Apache Maven的pom.xml文件:

<dependency><groupId>org.eclipse.jetty</groupId><artifactId>jetty-server</artifactId><version>9.3.8.v20160314</version>
</dependency>

Spring Boot与@ EnableAutoConfiguration / @ SpringBootApplication一起完成其余工作:它检测到类路径中是否存在Jetty ,得出一个有效的结论,即我们的意图是运行Web应用程序并用必要的内容补充Spring上下文。 这不只是辉煌吗?

如果不涵盖Spring Boot项目的另一个重要功能,那就是不公平的完成:集成测试支持。 在这方面, Spring Boot采用相同的方法,并提供了一些注释,以消除所有我们不得不另外编写的脚手架。 例如:

@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = AppConfig.class)
@WebIntegrationTest(randomPort = true)
public class PeopleRestServiceIntegrationTest {@Value("${local.server.port}") private int port;@Beforepublic void setUp() {RestAssured.port = port;}@Testpublic void testListOfPersonsIsBeingReturnedSuccessfuly() {given().when() .contentType(ContentType.JSON).get("/api/people").then().statusCode(200).log().ifValidationFails();}
}

@SpringApplicationConfiguration (请注意,我们在测试中使用的配置与主应用程序相同)和@WebIntegrationTest这两个注解,它们将Web应用程序测试的细节考虑在内并在随机端口上运行嵌入式servlet容器,并且我们已经针对人员管理JAX-RS服务进行了全面的集成测试。 可通过local.server.port环境属性获得运行servlet容器的端口,因此我们可以在测试背景中配置REST保证的端口。 简单容易。

在本文中,我们仅研究了使用Spring Boot来提高JAX-RS项目的开发速度的一种特定用例。 Spring Boot带来了许多琐碎的事情,每个发行版中都添加了越来越多的智能,更不用说与所选IDE的出色集成。 我希望您真的对Spring Boot感到兴奋,并渴望了解更多有关Spring Boot的信息。 值得花费时间和精力。

完整的项目可以在Github上找到 。

翻译自: https://www.javacodegeeks.com/2016/05/laziness-extreme-developing-jax-rs-services-spring-boot.html

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

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

相关文章

透明怎么弄_最新版微信如何设置透明背景?这样设置,效果令人惊喜

微信叒更新了&#xff0c;你的微信有更新吗&#xff1f;听说这次更新是安卓端的先更新&#xff0c;苹果端的还不能更新。今天小编要跟大家分享的是新版微信应该如何设置透明背景&#xff0c;不清楚微信透明背景长什么样子的&#xff1f;没关系&#xff0c;给你看看设置透明背景…

QueryRunner使用

在相继学习了JDBC和数据库操作之后&#xff0c;我们明显感到编写JDBC代码并非一件轻松的事儿。为了帮助我们更高效的学习工作&#xff0c;从JDBC的繁重代码中解脱出来&#xff0c;老佟给我们详尽介绍了一个简化JDBC操作的组件——DBUtils。我们今天主要学习了它所提供的两个类和…

基于vue的UI框架集锦(移动端+pc端)

1. vonic 一个基于 vue.js 和 ionic 样式的 UI 框架&#xff0c;用于快速构建移动端单页应用&#xff0c;很简约&#xff0c;是我喜欢的风格 star 2.3k 中文文档 在线预览 2.vux 基于WeUI和Vue(2.x)开发的移动端UI组件库 star 10k 基于webpackvue-loadervux可以快速开发移动端页…

com技术内幕 代码_CFan科学院:零门槛极速抠图技术探秘

将照片中的人或物从背景中分离出来&#xff0c;俗称抠图。要实现完美的抠图&#xff0c;没有一定的PS(Photoshop)基础是根本无法实现的&#xff0c;不过现在有个名为Remove.bg的网站&#xff0c;号称5秒钟就可以完成复杂的抠图&#xff0c;彻底将抠图难度降到了零门槛&#xff…

关于级联删除和级联修改

曾经因为级联删除的问题浪费了N多时间&#xff0c;顾此在这里写下小小心得&#xff0c;供大家借鉴。在数据库分别建立表t_food&#xff08;菜单&#xff09;和表t_book(订单)&#xff0c;如下所示&#xff1a;t_food:————————————————————————————…

python:数据库连接操作入门

模块 1 import pymssql,pyodbc 模块说明 pymssql和pyodbc模块都是常用的用于SQL Server、MySQL等数据库的连接及操作的模块&#xff0c;当然一些其他的模块也可以进行相应的操作&#xff0c;类似adodbapi、mssql、mxODBC等&#xff0c;我们在实际用的时候选择其中一个模块就好&…

java面试题:集合_Java:选择正确的集合

java面试题:集合这是在您的应用程序中选择Set &#xff0c; List或Map的正确实现的快速指南。 最好的通用或“主要”实现可能是ArrayList&#xff0c;LinkedHashMap和LinkedHashSet。 它们的整体性能更好&#xff0c;除非您需要其他实现提供的特殊功能&#xff0c;否则应使用它…

c:forEach

简介 <c:forEach>为循环控制&#xff0c;它可以将集合(Collection)中的成员循序浏览一遍。运作方式为当条件符合时&#xff0c;就会持续重复执行<c:forEach>的本体内容。 语法 语法1&#xff1a;迭代一集合对象之所有成员 <c:forEach [var"varName"] …

b500k带开关电位器内部构造_R138带开关大功率大电流电位器 B10K B500K

全阻值 :500Ω-1MΩ全阻值公差:20%阻抗特性型式:A,B,C,D杂音:Less than 100mV at 20 mmc.绝缘阻抗:More than 10MΩat DC 250V耐电压:1 minute at AC 250V残留阻值:Term.1~2:Less than 10Ω Term.2~3:Less than 10Ω同步误差(双联):-40dB~0dB3dB额定电压B线性:10mm,15mm:AC 100…

Java 8:将匿名类转换为Lambda表达式

将匿名类&#xff08;实现一种方法&#xff09;重构为lambda表达式&#xff0c;可使您的代码更简洁明了。 例如&#xff0c;这是Runnable及其lambda等效项的匿名类&#xff1a; // using an anonymous class Runnable r new Runnable() {Overridepublic void run() {System.o…

如何去掉a标签的下划线

首先来了解下<a>标签的一些样式&#xff1a; <a>标签的伪类样式 一组专门的预定义的类称为伪类&#xff0c;主要用来处理超链接的状态。超链接文字的状态可以通过伪类选择符&#xff0b;样式规则来控制。伪类选择符包括&#xff1a; 总: a 表示所有状态下的连接 …

Android.os.SystemClock

https://www.linuxidc.com/Linux/2011-11/48325p2.htm 文档中对System.currentTimeMillis()进行了相应的描述&#xff0c;就是说它不适合用在需要时间间隔的地方&#xff0c;如Thread.sleep, Object.wait等&#xff0c;因为可以通过System.setCurrentTimeMillis来改变它的值。要…

批量修改数据_#泰Q头条#065期 四步搞定Excel表中的批量数据修改

『闻道有先后 术业有专攻』又到每周五我们Offcie小课堂时间&#xff0c;每周学一点儿&#xff0c;知识从未如此简单&#xff0c;也真诚的希望各位能在留言板写下你们宝贵的建议&#xff0c;给您带来更具价值的分享。这期跟大家带来的Excel表数据整理功能——统一数值变动的实用…

列表与for循环

列表(list)&#xff1a; python基础数据类型之一&#xff1a;其他语言中也有列表的概念。可索引&#xff0c;可切片&#xff0c;可加长。 列表可以储存大量数据。 #作用&#xff1a;多个装备&#xff0c;多个爱好&#xff0c;多门课程&#xff0c;多个女朋友等#定义&#xff1a…

html用a标签怎么提交表单?

html用a标签怎么提交表单&#xff1f; 2011-03-08 10:55MeACrazy | 分类&#xff1a;Html/Css |浏览10003次如下代码请 帮忙完善 function judgeDelete(){if(confirm("确定要删除吗&#xff1f;")){window.location.href"doDelete.jsp";}}<form action&…

python 读取geotiff_科学网—利用python GDAL库读写geotiff格式的遥感影像方法 - 张伟的博文...

(1)利用python GDAL库读写geotiff格式的遥感影像方法&#xff0c;具有很好的参考价值&#xff0c;不错&#xff01;from osgeo import gdalimport numpy as npdef read_tiff(inpath):dsgdal.Open(inpath)rowds.RasterXSizecolds.RasterYSizebandds.RasterCountgeoTransformds.G…

滑动拼图验证码操作步骤:_拼图项目:延期的后果

滑动拼图验证码操作步骤&#xff1a;Mark Reinhold先生于2012年7月宣布 &#xff0c;他们计划从Java 8撤消Jigsaw项目 &#xff0c;因为Jigsaw计划于2013年9月&#xff08;从现在开始一年&#xff09;推迟其发布。 这个日期是众所周知的&#xff0c;因为Oracle已决定实施Java的…

Vue页面骨架屏(一)

在开发webapp的时候总是会受到首屏加载时间过长的影响&#xff0c;主流的解决方法是在载入完成之前显示loading图效果&#xff0c;而一些大公司会配置一套服务端渲染的架构来解决这个问题。考虑到ssr所要解决的一系列问题&#xff0c;越来越多的APP采用了“骨架屏”的方式去提升…

mysql中数据定义和数据控制语言_MySQL 数据定义语言(DDL)

SQL 包含以下 4部分&#xff1a;1数据定义语言(DDL)&#xff1a;DROP、CREATE、ALTER 等语句。2数据操作语言(DML)&#xff1a;INSERT(插入)、UPDATE(修改)、DELETE(删除)语句。3数据查询语言(DQL)&#xff1a;SELECT 语句。4 数据控制语言(DCL): GRANT、REVOKE、COMMIT、ROLLB…

Page directive: illegal to have multiple occurrences of contentType with different values

org.apache.jasper.JasperException: /commons/meta.jsp(1,1) PWC5988: Page directive: illegal to have multiple occurrences of contentType with different values (old: text/html; charsetutf-8, new: text/html;charsetUTF-8) 问题&#xff1a;contentType 有多个值 解…