微框架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>

示例和源码在 GitHub上。

Mustache

使用Mustache模板引擎渲染对象到html。

Maven依赖如下:

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

示例和源码在GitHub上。

Velocity

使用velocity模板引擎渲染对象到html。

Maven依赖如下:

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

示例和源码在GitHub上。

Handlebars

使用Handlebar模板引擎渲染对象到html。

Maven依赖如下:

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

示例和源码在GitHub

jada

使用jada模板引擎渲染对象到html。

Maven依赖如下:

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

示例和源码在 GitHub

Pebble

使用pebble模板引擎渲染对象到html。

Maven依赖如下:

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

示例和源码在 GitHub

Water

使用water模板引擎渲染对象到html。

Maven依赖如下:

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

示例和源码在GitHub

内嵌的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

说明书可以从Spark tutorial page获取。

参考文献:

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

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

 

  

时间: 2024-10-12 21:15:01

微框架spark--api开发利器的相关文章

java微信接口开发java SpringMVC mybatis 后台框架 集成代码生成器开发利器

获取[下载地址]   QQ: 313596790   [免费支持更新]支持三大数据库 mysql  oracle  sqlsever   更专业.更强悍.适合不同用户群体[新录针对本系统的视频教程,手把手教开发一个模块,快速掌握本系统]A 代码生成器(开发利器);      增删改查的处理类,service层,mybatis的xml,SQL( mysql   和oracle)脚本,   jsp页面 都生成   就不用写搬砖的代码了,生成的放到项目里,可以直接运行B 阿里巴巴数据库连接池druid

基于IDEA使用Spark API开发Spark程序

清明假期折腾了两天,总结了两种方式使用IDE进行spark程序,记录一下: 第一种方法比较简单,两种方式都是采用SBT进行编译的. 注意:本地不需要安装Scala程序,否则在编译程序时有版本兼容性问题. 一.基于Non-SBT方式 创建一个Scala IDEA工程 我们使用Non-SBT的方式,点击"Next" 命名工程,其他按照默认 点击"Finish"完成工程的创建 修改项目的属性 首先修改Modules选项 在src下创建两个文件夹,并把其属性改为source

Spark API编程动手实战-08-基于IDEA使用Spark API开发Spark程序-01

创建一个Scala IDEA工程: 点击“Next”: 点击“Finish”完成工程的创建: 修改项目的属性: 首先修改Modules选项: 在src下创建两个文件夹,并把其属性改为source: 再修改Libraries: 因为要开发Spark程序,所以需要把Spark的开发需要的jar包导进来: 导入包完成后,在工程的scala下面创建一个package: 创建一个Object对象: 完成初始类的创建: 首先构建Spark Driver的模板代码: 该程序是对前面的搜狗日志的处理代码,只不过

Spark API编程动手实战-08-基于IDEA使用Spark API开发Spark程序-02

接下来进行打包,使用Project  Structure的Artifacts: 使用From modules with dependencies: 选择Main Class: 点击“OK”: 把名称改为SparkDemoJar: 因为每台机器上都安装了Scala和Spark,所以可以把Scala和Spark相关的jar文件都删除掉: 接下来进行Build: 选择“Build Artifacts”: 剩下的操作,就是jar包上传到服务器上,然后执行spark-submit命令,我在之前的文章已经详

Yii2.0框架Restfull API开发攻略

1.将Yii2.0 advanced版中应用主体frontend 或 backend 应用复制为api应用 2.在应用主体api目录的controller新建SiteController.php: namespace api\controllers; use Yii; use yii\rest\ActiveController;/*SiteController测试控制器 */class SiteController extends ActiveController{public $modelCl

FF.PyAdmin 接口服务/后台管理微框架 (Flask+LayUI)

源码(有兴趣的朋友请Star一下) github: https://github.com/fufuok/FF.PyAdmin gitee: https://gitee.com/fufuok/FF.PyAdmin 初衷 运维开发中, 各类接口服务和后台管理系统必不可少, 索性写个通用的/简单易用的/支持快速开发的微框架. 一是开发时尽可能只关注业务逻辑, 快速实现, 不用再过多考虑架构/前端/布局什么的. 二是将常用业务逻辑二次封装, 使用时, 用简洁的语句即可完成复杂的事务, 并自动处理异常.

【核心API开发】Spark入门教程[3]

本教程源于2016年3月出版书籍<Spark原理.机制及应用> ,在此以知识共享为初衷公开部分内容,如有兴趣,请支持正版书籍. Spark综合了前人分布式数据处理架构和语言的优缺点,使用简洁.一致的函数式语言Scala作为主要开发语言,同时为了方便更多语言背景的人使用,还支持Java.Python和R语言.Spark因为其弹性分布式数据集(RDD)的抽象数据结构设计,通过实现抽象类RDD可以产生面对不同应用场景的子类.本章将先介绍Spark编程模型.RDD的相关概念.常用API源码及应用案例,

java框架平台 开发利器

获取[下载地址]   [免费支持更新]三大数据库 mysql  oracle  sqlsever   更专业.更强悍.适合不同用户群体[新录针对本系统的视频教程,手把手教开发一个模块,快速掌握本系统] A 集成代码生成器 [正反双向(单表.主表.明细表.树形表,开发利器)+快速构建表单; freemaker模版技术 ,0个代码不用写,生成完整的一个模块,带页面.建表sql脚本,处理类,service等完整模块B 集成阿里巴巴数据库连接池druid;  数据库连接池  阿里巴巴的 druid.Dr

Golang 微框架 Gin 简介

框架一直是敏捷开发中的利器,能让开发者很快的上手并做出应用,甚至有的时候,脱离了框架,一些开发者都不会写程序了.成长总不会一蹴而就,从写出程序获取成就感,再到精通框架,快速构造应用,当这些方面都得心应手的时候,可以尝试改造一些框架,或是自己创造一个. 曾经我以为Python世界里的框架已经够多了,后来发现相比golang简直小巫见大巫.golang提供的net/http库已经很好了,对于http的协议的实现非常好,基于此再造框架,也不会是难事,因此生态中出现了很多框架.既然构造框架的门槛变低了,

Java微框架:不可忽视的新趋势--转载

原文:http://www.infoq.com/cn/news/2015/06/Java-Spark-Jodd-Ninja?utm_campaign=infoq_content&utm_source=infoq&utm_medium=feed&utm_term=global 任何语言都有优缺点.对Java而言,它安全.经过严格测试.向后兼容,但却牺牲了部分灵活性和简洁性.于是,有人就尝试寻找方法,以便能规避Java的臃肿,同时又利用JVM的强大功能.第一波努力围绕轻量级Java框架