1. 程式人生 > >微框架spark--api開發利器

微框架spark--api開發利器

spark簡介

Spark(注意不要同Apache Spark混淆)的設計初衷是,可以簡單容易地建立REST API或Web應用程式。它是一個靈活、簡潔的框架,大小隻有1MB。Spark允許使用者自己選擇設計應用程式的模板引擎以及選擇最適合他們專案的庫,比如,HTML解析功能就有Freemarker、Mustaches、Velocity、Jade、Handlebars、Pebble或Water等選項可供選擇,而且很少需要配置或樣板檔案。不過,靈活簡單的代價是,使用者可選的功能減少。總之,Spark剔除了許多Java的臃腫之物,提供了一個最小化的、靈活的Web框架。但由於精簡程度較高,它缺少了一些功能,不適合用於大型Web應用程式的開發。

使用示例

1.在pom.xml檔案上加入依賴:

<dependency>
    <groupId>com.sparkjava</groupId>
    <artifactId>spark-core</artifactId>
    <version>2.2</version>
</dependency>

2. 編寫程式碼

import static spark.Spark.*;

    public class HelloWorld {
        public
static void main(String[] args) { get("/hello", (req, res) -> "Hello World"); } }

3.允許程式碼且檢視結果

http://localhost:4567/hello

是不是很簡單?spark是最容易建立一個java web應用的開發框架,但它提供了對大多數型別的專案來說足夠的功能。

停止伺服器

  通過呼叫stop()方法,服務將關閉且會清理掉所有的路由資訊。

路由

  一個spark應用的主要模組就是一組路由。路由有三部分組成:

     一個方法。(get,post,put,delete,head,trace,connect,options).

    一個路徑。(例如/hello, /users/:name)

    一個回撥。(request,response)->{}

   路由的匹配是按照路由的定義順序匹配的。請求會觸發第一個匹配的路由。

get("/", (request, response) -> {
// .. Show something ..
});

post("/", (request, response) -> {
// .. Create something ..
});

put("/", (request, response) -> {
// .. Update something ..
});

delete("/", (request, response) -> {
// .. annihilate something ..
});

options("/", (request, response) -> {
// .. appease something ..
});

路由匹配模式可以包含命名引數,根據請求物件的引數方法來訪問:

// matches "GET /hello/foo" and "GET /hello/bar"
// request.params(":name") is 'foo' or 'bar'
get("/hello/:name", (request, response) -> {
    return "Hello: " + request.params(":name");
});

路由匹配模式也可以包含萬用字元引數。可以根據請求物件的萬用字元方法來訪問:

// matches "GET /say/hello/to/world"
// request.splat()[0] is 'hello' and request.splat()[1] 'world'
get("/say/*/to/*", (request, response) -> {
    return "Number of splat parameters: " + request.splat().length;
});

請求

  在處理方法中,請求引數提供了請求資訊和功能:

request.body();               // request body sent by the client
request.cookies();            // request cookies sent by the client
request.contentLength();      // length of request body
request.contentType();        // content type of request.body
request.headers();            // the HTTP header list
request.headers("BAR");       // value of BAR header
request.attributes();         // the attributes list
request.attribute("foo");     // value of foo attribute
request.attribute("A", "V");  // sets value of attribute A to V
request.host();               // "example.com"
request.ip();                 // client IP address
request.pathInfo();           // the path info
request.params("foo");        // value of foo path parameter
request.params();             // map with all parameters
request.port();               // the server port
request.queryMap();           // the query map
request.queryMap("foo");      // query map for a certain parameter
request.queryParams("FOO");   // value of FOO query param
request.queryParams();        // the query param list
request.raw();                // raw request handed in by Jetty
request.requestMethod();      // The HTTP method (GET, ..etc)
request.scheme();             // "http"
request.session();            // session management
request.splat();              // splat (*) parameters
request.url();                // "http://example.com/foo"
request.userAgent();          // user agent

響應

  在處理方法中,響應引數提供了響應引數和功能:

response.body("Hello");        // sets content to Hello
response.header("FOO", "bar"); // sets header FOO with value bar
response.raw();                // raw response handed in by Jetty
response.redirect("/example"); // browser redirect to /example
response.status(401);          // set status code to 401
response.type("text/xml");     // set content type to text/xml

查詢引數Map

  查詢引數Map支援根據字首將引數分組到map中。這可以對兩組引數進行分組,如user[name]和user[age]一樣。

request.queryMap().get("user", "name").value();
request.queryMap().get("user").get("name").value();
request.queryMap("user").get("age").integerValue();
request.queryMap("user").toMap()

Cookie

request.cookies();                              // get map of all request cookies
request.cookie("foo");                          // access request cookie by name
response.cookie("foo", "bar");                  // set cookie with a value
response.cookie("foo", "bar", 3600);            // set cookie with a max-age
response.cookie("foo", "bar", 3600, true);      // secure cookie
response.removeCookie("foo");                   // remove cookie

Session

  每個請求可以訪問在服務端建立的session,提供了下面的方法來訪問:

request.session(true)                            // create and return session
request.session().attribute("user")              // Get session attribute 'user'
request.session().attribute("user", "foo")       // Set session attribute 'user'
request.session().removeAttribute("user", "foo") // Remove session attribute 'user'
request.session().attributes()                   // Get all session attributes
request.session().id()                           // Get session id
request.session().isNew()                        // Check is session is new
request.session().raw()                          // Return servlet objec

停止

  一個過濾器或者路由中快速停止一個請求的方法是:

        halt();

  你也可以在停止時,指定一個狀態。

        halt(401);
 或者:
  halt("This is the body");
  或者
  halt(401, "Go away!");
過濾器
  前置過濾器在請求處理前進行處理,可以讀取請求,讀取/修改響應。
  停止執行,使用halt方法:
before((request, response) -> {
    boolean authenticated;
    // ... check if authenticated
    if (!authenticated) {
        halt(401, "You are not welcome here");
    }
});

  後置過濾器在請求處理後進行,可以讀取請求,讀取/修改響應:

after((request, response) -> {
    response.header("foo", "set by after filter");
});

  過濾器也可以匹配請求(可選的),此時只有當路徑匹配時才進行處理:

before("/protected/*", (request, response) -> {
    // ... check if authenticated
    halt(401, "Go Away!");
});

直接跳轉

  你可以使用redirect幫助方法將瀏覽器頁面進行跳轉。

    response.redirect("/bar");

  你可以使用狀態碼3xx進行跳轉:

    response.redirect("/bar", 301); // moved permanentl

異常對映

  處理配置的所有的過濾器和路由的異常:

get("/throwexception", (request, response) -> {
    throw new NotFoundException();
});

exception(NotFoundException.class, (e, request, response) -> {
    response.status(404);
    response.body("Resource not found");
});

靜態檔案

  使用staticFileLocation方法,你可以在classpath中指定一個資料夾為靜態檔案提供服務。

注意,公共目錄不要包含在url中。一個檔案/public/css/style.css訪問路徑為:http://{host}:{port}/css/style.css

staticFileLocation("/public"); // Static files

  還可以使用externalStaticFileLocationMethod在設定一個外部目錄(不在classpath)為靜態檔案提供服務:

externalStaticFileLocation("/var/www/public"); // Static files

響應轉換

  對映路由將處理方法轉換成外部輸出。可以通過擴充套件ResponseTransformer,傳遞它到對映方法來完成。下面是一個使用Gson將一個路由輸出轉換成json的示例:

import com.google.gson.Gson;

public class JsonTransformer implements ResponseTransformer {

    private Gson gson = new Gson();

    @Override
    public String render(Object model) {
        return gson.toJson(model);
    }

}

使用上述類(MyMessage是一個有‘message’成員變數的bean):

get("/hello", "application/json", (request, response) -> {
    return new MyMessage("Hello World");
}, new JsonTransformer());

你也可以使用java8的方法引用,因為ResponseTransformer是有一個方法的介面:

Gson gson = new Gson();
get("/hello", (request, response) -> new MyMessage("Hello World"), gson::toJson);

檢視和模板

TemplateViewRoute由一個路徑(url匹配的路徑)和一個實現了render方法的模板引擎組成。

不用呼叫toString()方法返回的結果作為模板的實體,TemplateViewRoute返回呼叫render方法作為結果。

這種型別route的主要目的是提供一個建立通用和可複用的使用模板引擎渲染輸出的元件。

Freemarker

使用Freemarkder模板引擎渲染物件到html。

maven依賴:

<dependency>
    <groupId>com.sparkjava</groupId>
    <artifactId>spark-template-freemarker</artifactId>
    <version>2.0.0</version>
</dependency>

Mustache

使用Mustache模板引擎渲染物件到html。

Maven依賴如下:

<dependency>
    <groupId>com.sparkjava</groupId>
    <artifactId>spark-template-mustache</artifactId>
    <version>1.0.0</version>
</dependency>

Velocity

使用velocity模板引擎渲染物件到html。

Maven依賴如下:

<dependency>
    <groupId>com.sparkjava</groupId>
    <artifactId>spark-template-velocity</artifactId>
    <version>2.0.0</version>
</dependency>

Handlebars

使用Handlebar模板引擎渲染物件到html。

Maven依賴如下:

<dependency>
    <groupId>com.sparkjava</groupId>
    <artifactId>spark-template-handlebars</artifactId>
    <version>1.0.0</version>
</dependency>

jada

使用jada模板引擎渲染物件到html。

Maven依賴如下:

<dependency>
    <groupId>com.sparkjava</groupId>
    <artifactId>spark-template-jade</artifactId>
    <version>1.0.0</version>
</dependency>

Pebble

使用pebble模板引擎渲染物件到html。

Maven依賴如下:

<dependency>
    <groupId>com.sparkjava</groupId>
    <artifactId>spark-template-pebble</artifactId>
    <version>1.0.0</version>
</dependency>

Water

使用water模板引擎渲染物件到html。

Maven依賴如下:

<dependency>
    <groupId>com.sparkjava</groupId>
    <artifactId>spark-template-water</artifactId>
    <version>1.0.0</version>
</dependency>

內嵌的web伺服器

  獨立的Spark執行在一個嵌入的Jetty web伺服器。

預設情況下,Spark執行在4567埠。如果你想使用別的埠,使用port方法。在使用過濾器和路由時已經完成:

port(9090); // Spark will run on port 9090

安全

你可以通過secure方法來設定connection為安全的。這必須在所有路由對映之前完成:

secure(keystoreFile, keystorePassword, truststoreFile, truststorePassword);

執行緒池

可以非常容易的設定最大的執行緒數:

int maxThreads = 8;
threadPool(maxThreads);

還可以配置最新執行緒數和空閒過期時間:

int maxThreads = 8;
int minThreads = 2;
int timeOutMillis = 30000;
threadPool(maxThreads, minThreads, timeOutMillis);

等待初始化

使用awaitInitialization() 方法來檢查伺服器是否準備好,可以處理請求了。

這通常在一個獨立的執行緒中來做,例如在伺服器啟動後執行一個健康監測模組。

這個方法將使當前執行緒處於等待狀態直至Jetty伺服器初始化完成。初始化等於的路由、過濾器。因此,若使用一個執行緒,請不要將該方法放到你定義的路由、過濾器之前。

awaitInitialization(); // Wait for server to be initialized

其它的web伺服器

  為執行叢集伺服器(不是獨立伺服器),需要實現spark.servlet.SparkApplication。必須在init方法中初始化路由,下面的過濾器也必須在web.xml中配置:

<filter>
    <filter-name>SparkFilter</filter-name>
    <filter-class>spark.servlet.SparkFilter</filter-class>
    <init-param>
        <param-name>applicationClass</param-name>
        <param-value>com.company.YourApplication</param-value>
    </init-param>
</filter>

<filter-mapping>
    <filter-name>SparkFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

壓縮

若請求/響應報文頭中有此欄位,壓縮將會自動完成。

生成Javadoc

GitHub 上獲取到原始碼後,執行下面的命令生成javadoc:

mvn javadoc:javadoc

生成結果放入到/target/site/apidocs目錄下。

示例和教程

示例可以從工程目錄中獲取GitHub

參考文獻:

【1】http://sparkjava.com/documentation.html

【2】http://www.infoq.com/cn/news/2015/06/Java-Spark-Jodd-Ninja

相關推薦

框架spark--api開發利器

spark簡介 Spark(注意不要同Apache Spark混淆)的設計初衷是,可以簡單容易地建立REST API或Web應用程式。它是一個靈活、簡潔的框架,大小隻有1MB。Spark允許使用者自己選擇設計應用程式的模板引擎以及選擇最適合他們專案的庫,比如,HTML解析功能就有Freemarker、Mus

Restful API開發利器——RestPack專案教程(統一api返回json格式)

Restful API開發利器——RestPack專案教程  目錄 專案背景 RestPack 簡介 引入 RestPack 依賴 啟用 RestPack @RestPackController 註解 RestPack 異常處理 日誌輸出 資源分享與技術交流

zookeeper框架——Java API開發

一、基本運用          org.apache.zookeeper.Zookeeper是客戶端入口主類,負責建立與server的會話。它提供了表 1 所示幾類主要方法 : 功能 描述 create

Yii2.0框架Restfull API開發攻略

美化 控制器 ict 使用 xtend member 應用 路由 extend 1、將Yii2.0 advanced版中應用主體frontend 或 backend 應用復制為api應用 2、在應用主體api目錄的controller新建SiteController.php

信公眾平臺開發教程(三) 基礎框架搭建

開發 images wxs user 設計實現 bytes trre 來源 app 上一章,我們已經初步講解了微信公眾賬號開發的基本原理,今天我們來探索設計實現。 首先我們設計了模塊層次圖,當然圖中只是給出一種實現方式,不局限於此。具體見下圖。 主要功能介紹如下: 1)請求

API開發

嘗試 講解 3.1 記錄 val 變化 哈哈 取消 應用 轉載自:http://www.myexception.cn/program/1930025.html Java調用 新浪微博API 接口發微博,逐條講解,絕對清晰最近要做個課程設計,使用微博控制樹莓派,樹莓派再控制發

CK2020信小程序入門與實戰 常用組件API開發技巧項目實戰

註冊 form 項目 pack filesize 記錄 tps http 謝謝 CK2020微信小程序入門與實戰 常用組件API開發技巧項目實戰 新年伊始,學習要趁早,點滴記錄,學習就是進步! 隨筆背景:在很多時候,很多入門不久的朋友都會問我:我是從其他語言轉到程序開發

信小程序開發框架 Wepy 的使用

pan enc 調試 獲得 我們 web開發 本地 配置 開發 一、github地址:https://github.com/Tencent/wepy 按照 README.md 的步驟進行操作: 1.在“介紹”中獲得 wepy 的開發資源匯總:https://github.c

信小程序開發——連續快速點擊按鈕調用小程序api返回後仍然自動重新調用的異常處理

顯示 按鈕 添加 shanghai 代碼 頻率 absolut out ati 前言:   小程序開發中諸如獲取用戶手機號碼、調起微信支付、領取卡券等api都是會有一定的延遲的。也就是說通過點擊按鈕調用這些api的時候,從點擊按鈕調用api,到支付頁面或者領取卡券界面展示

信小程式開發框架——WXSS(一)

    WXSS語言決定了小程式頁面的各個元素在視覺上的展示,WXSS與CSS即為相試的、為了適合微信小程式開發WXSS對CSS進行相應的修改。     width:用來設定元素'寬度' / height:用來設定元素'高度 '/

公開課:服務開發利器Spring Cloud實踐課程

原始碼時代線下免費公開課:微服務開發利器Spring Cloud實踐課程 課程介紹 本堂課主要講解 1、為什麼需要spring cloud 2、spring cloud簡介 3、spring cloud微服務實踐 學習目標 1、理解微服務架構 2、spring cloud在微服務

C#信公眾號開發 -- (四)獲取API呼叫所需的全域性唯一票據access_token

access_token是公眾號的全域性唯一票據,公眾號呼叫各介面時都需使用access_token。開發者需要進行妥善儲存。access_token的儲存至少要保留512個字元空間。access_token的有效期目前為2個小時,需定時重新整理,重複獲取將導致上次獲取的access_token失效。 獲取

信小程式開發框架——元件

    元件的概念,如圖:     小程式給我們提供的元件,如圖  八類元件:1.檢視容器元件主要控制頁面內容、檢視容器可以理解為一個盒子在這個盒子裡面可以裝入更小的盒子填滿,這裡提供有5種: &nb

信小程式入門與實戰 常用元件 API 開發技巧 專案實戰

      開始就以專案為出發點,不會講一大堆枯燥的語法再補充兩個案例了事,將帶你快速熟悉小程式基礎知識,然後直接進入實戰開發環節,將小程式的知識點貫穿在整個專案中        課程不僅僅講解小程式開發,更會通過實際的編碼來

信小程式開發框架—wepy快速入門

 小程式框架wepy文件 Github地址 wepy官網:https://tencent.github.io/wepy/index.html 專案建立與使用 安裝wepy 以下安裝都通過npm安裝 安裝 wepy 命令列工具。

信小程式API信小程式開發工具

為了讓開發者可以很方便的調起微信提供的能力,例如獲取使用者資訊、微信支付等等,小程式提供了很多 API 給開發者去使用。 要獲取使用者的地理位置時,只需要: wx.getLocation({ type: ‘wgs84’, success: (re

信企業號開發原始碼Java編寫,懶人開發一鍵式部署專案,WeChatEnterprise框架你值得擁有

幾年前無意間接觸了微信公眾平臺開發,這個在當時還是一個新鮮的事物,但現在已經很流行了,發展的型別也特別的多,比如訂閱號、服務號、小程式、微信企業號等,這些產品在人們日常的生活與開發中,都是非常常見的。 當時的博主也順應時代的變化,去嘗試著開發公眾平臺,到目前為止也算得上是得

更多免費初級中級高階大資料java視訊教程下載 加(***信((號keepper,請備註java或掃下面2二3維4碼尚矽谷Java開發利器:IntelliJ IDEA的安裝、配置與使用

更多免費初級中級高階大資料java視訊教程下載 加(微***信((號keepper,請備註java或掃下面2二3維4碼尚矽谷Java開發利器:IntelliJ IDEA的安裝、配置與使用java視訊教程1-課件java視訊教程1-課件java視訊教程~$谷_宋紅康_IntelliJIDEA的安裝、配置與使用.

【備忘】2018年最新信小遊戲開發 ES6+小遊戲api開發視訊教程下載

1) 課程介紹、環境開發搭建2) 微信小遊戲開發原理與JS面向物件3) 微信小遊戲邏輯梳理與API介紹4) 微信小遊戲主體開發5) 微信小遊戲音樂和振動API,獲取使用者資訊,設定和登入API,網路請求之HTTP,WebSocket,檔案下載等API詳解6) 課程總結與展望

信公眾平臺開發[4] —— ThinkPHP 框架信支付

    提示:文章佈局尷尬症患者,請轉移>>>MarkDown文章連結 <<<     宣告:原文主要摘自白俊遙部落格 ,部分內容針對個人事例已作修改,主要用