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

jax-rs jax-ws

我认为可以公平地说,作为软件开发人员,我们一直在寻找编写更少的代码的方法,这些代码可以自动地或不能自动地完成更多的工作。 考虑到这一点,作为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

jax-rs jax-ws

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

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

相关文章

python内置类型_Python内置对象类型

核心数字类型&#xff1a;数字&#xff1a;int&#xff0c;long&#xff0c;float&#xff0c;complex&#xff0c;bool字符&#xff1a;str&#xff0c;unicode列表&#xff1a;list字典&#xff1a;dict元组&#xff1a;tuple文件&#xff1a;file其他类型&#xff1a;集合(s…

【Android OpenGL ES 开发 (零)】创建一个新的工程

创建符合要求的AndroidApp 使用Android Studio开发&#xff0c;Android Studio下载地址 1.先创建Native C 2.项目相关添加 3.使用C11标准 学习使用JNI为Java提供API 1.在cpp中定义相关接口&#xff0c;格式如下 2.外部调用这个API 把so改成自己想要的名字 1.需要在cmake文件…

java方法参数类型不确定_一个Java方法能有多少个参数类型?这个好奇coder做了个实验...

选自 justinblank机器之心编译参与&#xff1a;李志伟、张倩在 JVM 中&#xff0c;一个 Java 方法&#xff0c;最多能定义多少参数呢&#xff1f;这是一个很无聊的问题&#xff0c;即使能定义一万个&#xff0c;十万个&#xff0c;谁又会真的去这么做呢。但是作为一个 coder&am…

lagom的微服务框架_您的第一个Lagom服务– Java Microservices入门

lagom的微服务框架在撰写我的下一份OReilly报告时&#xff0c;我一直很沮丧&#xff0c;并且一段时间内没有足够的时间来撰写博客。 是时候赶快来这里&#xff0c;让您真正快速地开始使用名为Lagom的新微服务框架。 它与您从Java EE或其他应用程序框架中可能了解到的有所不同。…

【Android OpenGL ES 开发 (一)】使用c++开发opengles 与 日志功能 及 加载assets

创建OpenGLES视口 1.App窗口改成OpenGL窗口,是通过java调用C&#xff0c;在以下位置修改如下内容 package com.example.learnogles;import androidx.appcompat.app.AppCompatActivity;import android.content.Context; import android.opengl.GLSurfaceView; import android.o…

水印相机定位不准确怎么办_禄来的广角双反相机(2020版)

点击上方胶卷迷俱乐部快速关注&#xff0c;胶卷迷们坚实的阵地内容主要原创&#xff0c;配图来自群友和网络&#xff0c;所有水印保留最下方为微信自带广告&#xff0c;支持请点击(本号可获微量收入)4.0德国禄来公司以双反相机名震天下&#xff0c;其中的2.8&#xff0c;3.5两个…

【Android OpenGL ES 开发 (二)】渲染管线与Shader

计算出每一帧耗费的时间 1.在头文件中加入time.h,cpp中实现如下计算时间接口 float GetFrameTime(){static unsigned long long lastTime0,currentTime0;timeval current;gettimeofday(&current, nullptr);//取当前时间currentTime current.tv_sec * 1000 current.tv…

tibco汉化包6.3.0_TIBCO BusinessWorks 6和Container Edition与BW5的比较

tibco汉化包6.3.0[本文已于一段时间前发布在TIBCO博客上 。 我还在适当的地方添加了一些有关BusinessWorks Container Edition&#xff08;BW CE&#xff09;的信息 。 下面定义的大多数特征对于BW6和BW CE都是正确的] TIBCO ActiveMatrix BusinessWorks 6&#xff08;BW6&…

python地图散点图_Python中基于Basemap的三维散点图

我正在尝试绘制一个三维散点图&#xff0c;图中是Python身上的烟羽&#xff0c;下面是北美的地图。我试过各种方法&#xff0c;但似乎都有缺点。我现在的代码是&#xff1a;fig plt.figure(figsize(22,4))ax Axes3D(fig)M Basemap(llcrnrlon-140,llcrnrlat10,urcrnrlon-40,u…

【Android OpenGL ES 开发 (三)】Shader 扩展

编译Shader代码 1.封装一个编译shader的接口 GLuint CompileShader(GLenum shaderType,const char *shaderCode){GLuint shaderglCreateShader(shaderType);glShaderSource(shader,1,&shaderCode,NULL);glCompileShader(shader);GLint compileResultGL_TRUE;glGetShaderi…

css阴影属性_第三场阴影场与属性访问器接口

css阴影属性这是“ 影子字段与属性访问器”界面的 第3轮 。 如果您是新手&#xff0c;但不确定要怎么做&#xff0c;请查看我以前的文章或关于开发JavaFX应用程序时节省内存的第一篇文章 。 作为Java开发人员&#xff0c;我主要关心的是在开发JavaFX域模型时在性能 &#xff0c…

js if判断多个条件_JS条件判断小技巧(一)

经常code review&#xff0c;我发现JS newbie很容易写出一堆冗长的代码。今天就列几个比较常见的“解决之道”&#xff0c;看看如何减少JS里的条件判断。提前返回&#xff0c;少用if...else“if...else是编程语言的精华。——鲁迅”但是过多的嵌套&#xff0c;还是挺令人抓狂的…

【Android OpenGL ES 开发 (四)】纹理相关(一)

纹理贴图的原理 1.作用&#xff1a;可以用来渲染视频。 2.纹理坐标 生成OpenGL中的纹理对象 1.像素数据想要绘制出来需要先变成纹理 2.创建纹理放在GPU上 GLuint CreateTexture2D(unsigned char *pixelData,int width,int height,GLenum type) {GLuint texture;glGenTextu…

python selenium循环判断元素是否存在_检查Python Selenium是否存在元素

我有一个问题-我正在使用Selenium(firefox)Web驱动程序打开网页&#xff0c;单击一些链接等&#xff0c;然后捕获屏幕截图。我的脚本可以从CLI正常运行&#xff0c;但是通过cronjob运行时&#xff0c;它并没有通过第一个find_element()测试。我需要添加一些调试&#xff0c;或一…

jmx 替代_使用JMX作为Ganglia的现代替代品进行CLDB监视

jmx 替代有许多选项可用于监视MapR集群的性能和运行状况。 在本文中&#xff0c;我将介绍使用Java管理扩展&#xff08;JMX&#xff09;监视CLDB的鲜为人知的方法。 据最受尊敬的MapR数据工程师之一&#xff0c;Akihiko Kusanagi称&#xff0c;与使用Ganglia相比&#xff0c;使…

WPScan安全建议和防护

加固WordPress安全性 保护WordPress网站的安全性至关重要&#xff0c;因为它是全球最受欢迎的内容管理系统之一&#xff0c;也是攻击者经常瞄准的目标。本文将深入探讨如何加固WordPress安全性&#xff0c;包括实施强密码策略、保持更新、使用可靠的主题和插件、限制登录尝试、…

red hat安装宝塔_如何在几分钟内安装Red Hat Container Development Kit(CDK)

red hat安装宝塔作为负责开发容器化应用程序提供的可能性的应用程序开发人员或架构师&#xff0c;将所有工具组合在一起以帮助您入门时几乎没有帮助。 到现在。 红帽容器开发套件&#xff08;CDK&#xff09; 安装变得简单&#xff01; 红帽提供了一个容器开发套件&#xf…

python收集数据程序_用Python挖掘Twitter数据:数据采集

原标题&#xff1a;用Python挖掘Twitter数据&#xff1a;数据采集作者&#xff1a;Marco Bonzanini 翻译&#xff1a;数盟这是7部系列中的第1部分&#xff0c;注重挖掘Twitter数据以用于各种案例。这是第一篇文章&#xff0c;专注于数据采集&#xff0c;起到奠定基础的作用。Tw…

【FFMPEG中PTS与DTS统一转换为毫秒】

对于PTS和DTS 是两个非常重要的参数&#xff0c;在音视频同步时是必要的&#xff0c;为了方便使用&#xff0c;将二者统一为毫秒级别 static double r2d(AVRational r) {return r.den 0 ? 0 : (double)r.num / (double)r.den; } //转换为毫秒&#xff0c;方便做同步 AVPacke…