zoukankan      html  css  js  c++  java
  • 微框架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

     

      

  • 相关阅读:
    apache安全—用户访问控制
    hdu 3232 Crossing Rivers 过河(数学期望)
    HDU 5418 Victor and World (可重复走的TSP问题,状压dp)
    UVA 11020 Efficient Solutions (BST,Splay树)
    UVA 11922 Permutation Transformer (Splay树)
    HYSBZ 1208 宠物收养所 (Splay树)
    HYSBZ 1503 郁闷的出纳员 (Splay树)
    HDU 5416 CRB and Tree (技巧)
    HDU 5414 CRB and String (字符串,模拟)
    HDU 5410 CRB and His Birthday (01背包,完全背包,混合)
  • 原文地址:https://www.cnblogs.com/davidwang456/p/4655090.html
Copyright © 2011-2022 走看看