spark rest_Spark简介,您的下一个REST Java框架

spark rest

我希望您今年Java来了! 今天,我们将研究一个清新,简单,美观且实用的框架,以Java编写REST应用程序。 它将非常简单,甚至根本不会看起来像Java。

我们将研究Spark Web框架。 不,它与Apache Spark不相关。 是的,很遗憾,他们使用相同的名字。

我认为理解该框架的最佳方法是构建一个简单的应用程序,因此我们将构建一个简单的服务来执行数学运算。

我们可以这样使用它:

火花1

请注意,该服务正在本地主机上的端口4567上运行,并且请求的资源为“ / 10 / add / 8”。

使用Gradle设置项目(

apply plugin: "java"
apply plugin: "idea"sourceCompatibility = 1.8repositories {mavenCentral()maven { url "https://oss.sonatype.org/content/repositories/snapshots/" }maven { url "https://oss.sonatype.org/content/repositories/releases/" }     
}dependencies {compile "com.javaslang:javaslang:2.0.0-RC1"compile "com.sparkjava:spark-core:2.3"compile "com.google.guava:guava:19.0-rc2"compile "org.projectlombok:lombok:1.16.6"testCompile group: 'junit', name: 'junit', version: '4.+'
}task launch(type:JavaExec) {main = "me.tomassetti.javaadvent.SparkService"classpath = sourceSets.main.runtimeClasspath
}

现在我们可以运行:

  • / gradlew想法来生成IntelliJ IDEA项目
  • / gradlew测试以运行测试
  • / gradlew组装以构建项目
  • / gradlew启动以启动我们的服务

现在,让我们认识Spark

您认为我们可以编写一个功能齐全的Web服务,用不到25行Java代码执行基本的数学运算吗? 没门? 好吧,再想想:

// imports omittedclass Calculator implements Route {private Map<String, Function2<Long, Long, Long>> functions = ImmutableMap.of("add", (a, b) -> a + b,"mul", (a, b) -> a * b,"div", (a, b) -> a / b,"sub", (a, b) -> a - b);@Overridepublic Object handle(Request request, Response response) throws Exception {long left = Long.parseLong(request.params(":left"));String operatorName = request.params(":operator");long right = Long.parseLong(request.params(":right"));return functions.get(operatorName).apply(left, right);}
}public class SparkService {public static void main(String[] args) {get("/:left/:operator/:right", new Calculator());}
}

在我们的主要方法中,我们只是说,当我们得到一个包含三个部分(用斜杠分隔)的请求时,我们应该使用计算器路线,这是我们唯一的路线。 Spark中的路由是接收请求,处理请求并产生响应的单元。

我们的计算器就是神奇的地方。 它在请求中查找参数“ left”,“ operatorName”和“ right”。 左右被解析为长值,而operatorName用于查找操作。 对于每个操作,我们都有一个函数(Function2 <Long,Long>),然后将其应用于我们的值(左和右)。 酷吧?

Function2是来自Javaslang项目的接口。

您现在可以启动该服务( ./gradlew启动,还记得吗?)并进行播放。

我上次检查Java时比较冗长,冗长,缓慢……好吧,它现在正在恢复。

好的,但是测试呢?

因此Java实际上可以非常简洁,作为软件工程师,我会庆祝一两分钟,但是不久之后我就开始感到不安……这些东西没有经过测试! 更糟糕的是,它看起来根本无法测试。 逻辑在我们的计算器类中,但是它接受一个Request并生成一个Response。 我不想实例化一个请求只是为了检查我的计算器是否按预期工作。 让我们重构一下:

class TestableCalculator implements Route {private Map<String, Function2<Long, Long, Long>> functions = ImmutableMap.of("add", (a, b) -> a + b,"mul", (a, b) -> a * b,"div", (a, b) -> a / b,"sub", (a, b) -> a - b);public long calculate(String operatorName, long left, long right) {return functions.get(operatorName).apply(left, right);}@Overridepublic Object handle(Request request, Response response) throws Exception {long left = Long.parseLong(request.params(":left"));String operatorName = request.params(":operator");long right = Long.parseLong(request.params(":right"));return calculate(operatorName, left, right);}
}

我们只是将管道(从请求中取出值)与逻辑分开,并将其放入自己的方法中: calculate 。 现在我们可以测试计算了。

public class TestableLogicCalculatorTest {@Testpublic void testLogic() {assertEquals(10, new TestableCalculator().calculate("add", 3, 7));assertEquals(-6, new TestableCalculator().calculate("sub", 7, 13));assertEquals(3, new TestableCalculator().calculate("mul", 3, 1));assertEquals(0, new TestableCalculator().calculate("div", 0, 7));}@Test(expected = ArithmeticException.class)public void testInvalidInputs() {assertEquals(0, new TestableCalculator().calculate("div", 0, 0));}}

我现在感觉好多了:我们的测试证明了这些东西是行得通的。 当然,如果我们尝试除以零,它将引发异常,但是事实就是这样。

但是,这对用户意味着什么?

星火2

这意味着:500。如果用户尝试使用一个不存在的操作,会发生什么?

星火3

如果值不是正确的数字怎么办?

星火4

好的,这似乎不是很专业。 让我们修复它。

错误处理,功能风格

要解决这两种情况,我们只需要使用Spark的一项功能即可:我们可以将特定的异常与特定的路线进行匹配。 我们的路由将产生有意义的HTTP状态代码和正确的消息。

public class SparkService {public static void main(String[] args) {exception(NumberFormatException.class, (e, req, res) -> res.status(404));exception(ArithmeticException.class, (e, req, res) -> {res.status(400);res.body("This does not seem like a good idea");});get("/:left/:operator/:right", new ReallyTestableCalculator());}
}

我们仍然要处理不存在的操作的情况,这是我们将在ReallyTestableCalculator中进行的操作

为此,我们将使用典型的函数模式:我们将返回Either Either是可以具有left或right值的集合。 左侧通常表示有关错误的某种信息,例如错误代码或错误消息。 如果没有任何问题,Either都将包含一个正确的值,可能是各种各样的东西。 在本例中,如果无法执行操作,则将返回错误(我们定义的类),否则将以Long形式返回操作的结果。 因此,我们将返回Either <Error,Long>。

package me.tomassetti.javaadvent.calculators;import javaslang.Function2;
import javaslang.Tuple2;
import javaslang.collection.Map;
import javaslang.collection.HashMap;
import javaslang.control.Either;
import spark.Request;
import spark.Response;
import spark.Route;public class ReallyTestableCalculator implements Route {private static final int NOT_FOUND = 404;private Map<String, Function2<Long, Long, Long>> functions = HashMap.ofAll(new Tuple2<>("add", (a, b) -> a + b),new Tuple2<>("mul", (a, b) -> a * b),new Tuple2<>("div", (a, b) -> a / b),new Tuple2<>("sub", (a, b) -> a - b));public Either<Error, Long> calculate(String operatorName, long left, long right) {Either<Error, Long> unknownOp = Either.<Error, Long>left(new Error(NOT_FOUND, "Unknown math operation"));return functions.get(operatorName).map(f -> Either.<Error, Long>right(f.apply(left, right))).orElse(unknownOp);}@Overridepublic Object handle(Request request, Response response) throws Exception {long left = Long.parseLong(request.params(":left"));String operatorName = request.params(":operator");long right = Long.parseLong(request.params(":right"));Either<Error, Long> res =  calculate(operatorName, left, right);if (res.isRight()) {return res.get();} else {response.status(res.left().get().getHttpCode());return null;}}
}

让我们测试一下:

package me.tomassetti.javaadvent;import javaslang.control.Either;
import me.tomassetti.javaadvent.calculators.ReallyTestableCalculator;
import org.junit.Test;import static org.junit.Assert.assertEquals;public class ReallyTestableLogicCalculatorTest {@Testpublic void testLogic() {assertEquals(Either.right(10L), new ReallyTestableCalculator().calculate("add", 3, 7));assertEquals(Either.right(-6L), new ReallyTestableCalculator().calculate("sub", 7, 13));assertEquals(Either.right(3L), new ReallyTestableCalculator().calculate("mul", 3, 1));assertEquals(Either.right(0L), new ReallyTestableCalculator().calculate("div", 0, 7));}@Test(expected = ArithmeticException.class)public void testInvalidOperation() {Either<me.tomassetti.javaadvent.calculators.Error, Long> res = new ReallyTestableCalculator().calculate("div", 0, 0);assertEquals(true, res.isLeft());assertEquals(400, res.left().get().getHttpCode());}@Testpublic void testUnknownOperation() {Either<me.tomassetti.javaadvent.calculators.Error, Long> res = new ReallyTestableCalculator().calculate("foo", 0, 0);assertEquals(true, res.isLeft());assertEquals(404, res.left().get().getHttpCode());}}

结果

我们提供了可以轻松测试的服务。 它执行数学运算。 它支持四个基本操作,但可以轻松扩展以支持更多操作。 处理错误并使用适当的HTTP代码:400(错误输入)和404(未知操作或值)。

结论

当我第一次看到Java 8时,我对新功能感到满意,但并不十分兴奋。 但是,几个月后,我看到了基于这些新功能的新框架,它们有可能真正改变我们用Java编程的方式。 Spark和Javaslang之类的东西正在发挥作用。 我认为现在Java可以保持简单而可靠,同时变得更加敏捷和高效。

  • 您可以在Spark教程网站或我的博客tomassetti.me上找到更多教程。

翻译自: https://www.javacodegeeks.com/2015/12/introduction-spark-next-rest-framework-java.html

spark rest

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

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

相关文章

oracle 授权 增删改查权限_Oracle增删改查与函数

SQL -- 结构化查询语言 关系型数据库分类&#xff1a; DDL DML DCL DQL TCL Oracle 的数据类型&#xff1a;字符 char() varchar2()数字 number(p,s)时间 date timestamp 文件 clob blob 二维表 table 创建表 CREATE create table 表名 ( 列名 数据类型 [约束], 列名 类型 ... …

_用WSL,MobaXterm,Cmder配置linux开发环境

离不开Windows的理由很多,作为后端开发需要使用linux的情况也很多,双系统总归是不方便,而且linux下的GUI体验也没用Win 10好. 如果使用虚拟机,那么文件交换和网络等各种问题也需要解决,对系统的内存要求也更高一些.微软为了让更多的开发人员留在Win10上面,开发了WSL功能.目前的…

php中上传图片怎么显示出来,PHP上传图片类显示缩略图功能

有缩略图功能 但是 感觉不全面&#xff0c;而且有点问题&#xff0c;继续学习&#xff0c;将来以后修改下/*** Created by PhpStorm.* User: Administrator* Date: 2016/6/28* Time: 21:04*/class upload{protected $fileMine;//文件上传类型protected $filepath;//文件上传路径…

javaparser_JavaParser入门:以编程方式分析Java代码

javaparser我最喜欢的事情之一是解析代码并对其执行自动操作。 因此&#xff0c;我开始为JavaParser做出贡献&#xff0c;并创建了两个相关项目&#xff1a; java-symbol-solver和Effectivejava 。 作为JavaParser的贡献者&#xff0c;我反复阅读了一些有关从Java源代码提取信…

wps xml转换表格_这功能WPS卖近百元?教你免费将PDF转成Word

[PConline 应用]PDF文件如何转换成为Word&#xff1f;很多朋友研究这个问题已经很久了&#xff0c;PDF更利于统一格式传播&#xff0c;Word更便于编辑&#xff0c;因此收到PDF文件后、想要修改时要如何将PDF转换成Word可谓是一个刚需。当然&#xff0c;不少办公软件提供了这样的…

睡眠 应该用 a加权 c加权_在神经网络中提取知识:学习用较小的模型学得更好...

在传统的机器学习中&#xff0c;为了获得最先进的(SOTA)性能&#xff0c;我们经常训练一系列整合模型来克服单个模型的弱点。 但是&#xff0c;要获得SOTA性能&#xff0c;通常需要使用具有数百万个参数的大型模型进行大量计算。 SOTA模型(例如VGG16 / 19&#xff0c;ResNet50)…

gpu编程如何一步步学习_如何学习贴片机编程

学习贴片机编程首选要对贴片机有所熟悉了解&#xff0c;另外对常用的电脑编辑软件要会使用。目前通常学习贴片机编程有专门的培训学校&#xff0c;或者跟着生产线上现有的贴片机编程师傅学习熟练后再进行编程操作。下面深圳智驰科技就来分享一下如何学习贴片机编程。对贴片机编…

plotcylinder matlab,Matlab在任意两点之间绘制三维圆柱

Matlab在任意两点之间绘制三维圆柱Matlab在任意两点之间绘制三维圆柱此函数可能存在一些不足&#xff0c;请多多指教&#xff01;function plotcylinder(u1,u2,color_a,r)Lnorm(u1-u2);RODu2-u1;[X,Y,Z]cylinder(r,100);x1X*0;y1Y*0;z1Z*0;ZL*Z-L/2;ROD_midpoint(u1u2)/2;xROD_…

jdk8和hotspot_HotSpot的-XshowSettings标志的简单性和价值

jdk8和hotspot一个方便的HotSpot JVM标志 &#xff08; 选项为Java启动 java &#xff09;是-XshowSettings选项。 Oracle Java启动器描述页面中对此选项进行了如下描述 &#xff1a; -XshowSettings &#xff1a; category显示设置并继续。 该选项的可能类别参数包括&#xf…

matlab信号分割与比对,matlab测量计算信号的相似度

本示例说明如何测量信号相似度。将回答以下问题&#xff1a;如何比较具有不同长度或不同采样率的信号&#xff1f;如何确定测量中是否存在信号或仅有噪声&#xff1f;有两个信号相关吗&#xff1f;如何测量两个信号之间的延迟&#xff1f;比较具有不同采样率的信号考虑一个音频…

Spring Bootstrap中具有配置元数据的高级配置

在简要介绍了配置元数据并涵盖了我之前的文章《 在Spring Boot中使用配置元数据Pimp您的配置》中的基础知识之后&#xff0c;现在该看看如何进一步执行此步骤并进一步自定义配置。 在这篇文章中&#xff0c;我计划提出对配置属性的弃用&#xff0c;并讨论各种值提供程序&#x…

ssh 与 telnet 有何不同?_采用创新面料Nike Infinalon的全新瑜珈系列究竟有何不同?...

采用创新面料Nike Infinalon的全新瑜珈系列究竟有何不同&#xff1f;无拘无束自由运动——这是耐克瑜伽系列新品的核心设计理念。全新系列为你提供垫上瑜伽时毫无束缚的舒适感&#xff0c;采用了耐克创新型面料&#xff1a;Nike Infinalon。Nike Infinalon应用于耐克最新瑜伽系…

matlab中的导函数驻点,Matlab用导数作定性分析

Matlab用导数作定性分析5.1知识要点&#xff1a;函数作图 —用导数定性描述函数【 clf,xlinspace(-8,8,30);f(x-3).^2./(4*(x-1)); plot(x,f) 】【 fplot((x-3)^2/(4*(x-1)),[-8,8])) 】【 clf,xsym(x); f(x-3)^2/(4*(x-1)); ezplot(f,[-8,8]) ,ti…

原生态基于OpenCV图像处理软件开发

部分功能效果图 GitHub:https://github.com/CnYiXiaoNaiHe/OpenCV- 持续更新

git.exe 启动 慢_四川成都surface电脑启动到一半黑屏维修服务地址电话

联系人&#xff1a;刘工 欢迎来电 地址&#xff1a;成都市一环路南二段1号(磨子桥口)数码科技大厦(新世纪电脑城对面)4楼413专业surface全系列维修因为专注&#xff0c;所以专注&#xff0c;所以surface配件都有现货。微软电脑&#xff0c;微软平板电脑专业维修服务点surface R…

【FFMPEG应用篇】基于C++使用ffmpeg和QT开发播放器

音视频基础知识 1.MPEG-4是一套用于音频&#xff0c;视频信息的亚索编码标准。 2.常见的封装格式 MP4 MOV AVI&#xff1a;压缩标准可以任意选择 FLV &#xff1a;FLV封装格式详细参考 TS&#xff1a;直播流媒体使用&#xff1b; 3.常用视频编码格式 H264&#xff0…

java代码自动生成的插件_如何使用插件生成自定义Java 8代码

java代码自动生成的插件大多数程序员讨厌的一件事就是编写样板代码。 无休止的时间花费在设置实体类和配置数据库连接上。 为了避免这种情况&#xff0c;您可以让Speedment Open Source之类的程序为您生成所有这些代码。 这样可以很容易地以最少的人工就可以启动和运行数据库项…

PHP在Tomcat中CSS出错,tomcat找不到css怎么办

tomcat找不到css怎么办Tomcat找不到WEB下的Css文件&#xff0c;一般可以通过以下方式解决&#xff1a;将路径相对位置修改为域相对位置&#xff0c;如下&#xff1a;备注&#xff1a;WEB-INF不是公共访问目录&#xff0c;只有在Servlets的RequestDispatcher或JSPS的可以访问&am…

eve模拟器_《Re:从零开始的新伊甸征程》一步到位教你下载EVE手游

自从小生发布了《「EVE Echoes」萌新向完全入门指南》后有小伙伴回应不懂怎样下载游戏的问题&#xff0c;小生作为殷郡中的一名闲云野鹤也尽一点绵薄之力帮助各位&#xff0c;尽量为各位扫清前往新伊甸的“石头”吧。[酷]在开篇前小生可以大致明确告诉你&#xff0c;不要问小生…