日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > java >内容正文

java

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

發布時間:2023/12/3 java 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Spark简介,您的下一个REST Java框架 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

希望今年您對Java的熱情很高! 今天,我們將研究一個清新,簡單,美觀且實用的框架,以Java編寫REST應用程序。 它將非常簡單,甚至根本不會看起來像Java。

我們將研究Spark Web框架。 不,它與Apache Spark不相關。 是的,很遺憾,他們使用相同的名字。

我認為理解該框架的最佳方法是構建一個簡單的應用程序,因此我們將構建一個簡單的服務來執行數學運算。

我們可以這樣使用它:

請注意,該服務正在本地主機上的端口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));}}

我現在感覺好多了:我們的測試證明了這些東西是行得通的。 當然,如果我們嘗試除以零,它將引發異常,但是事實就是這樣。

但是,這對用戶意味著什么?

這意味著:500。如果用戶嘗試使用一個不存在的操作,會發生什么?

如果值不是正確的數字怎么辦?

好的,這似乎不是很專業。 讓我們修復它。

錯誤處理,功能風格

要解決這兩種情況,我們只需要使用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 Java框架的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。