跳转至

Spark Java 简介

原文:http://zetcode.com/java/spark/

这是 Spark Java Web 框架的入门教程。 我们介绍了 Spark Java 框架,并提供了三个代码示例。

Spark Java

Spark 是一个 Java 微框架,用于以最小的工作量在 Java8 中创建 Web 应用。 Spark 框架是为快速开发而构建的简单,轻量级的 Java Web 框架。 它的灵感来自流行的 Ruby 微框架 Sinatra 。

Spark 广泛使用 Java8 的 lambda 表达式,这使 Spark 应用不再那么冗长。 与其他 Java Web 框架相比,Spark 不使用大量的 XML 文件或注解。

路由

Spark 应用包含一组路由。 路由将 URL 模式映射到 Java 处理器。

路由包含三个部分:

  • 动词,包括获取,发布,放置,删除,开头,跟踪,连接和选项
  • 诸如/first/hello/:name之类的路径
  • 回调(request, response) -> {}

首个应用

第一个应用返回一条简单消息。 Gradle 用于构建应用。

$ tree
.
├── build.gradle
└── src
    └── main
        └── java
            └── com
                └── zetcode
                    └── firstspark
                        └── FirstSpark.java

这是项目结构。 Gradle 的 Java 插件期望 Java 生产代码位于src/main/java目录中。

build.gradle

apply plugin: 'java'
apply plugin: 'application'

archivesBaseName = "first"
version = '1.0'
mainClassName = "com.zetcode.firstspark.FirstSpark"

repositories {
  mavenCentral()
}

dependencies {
  compile 'com.sparkjava:spark-core:2.5'
  compile 'org.slf4j:slf4j-simple:1.7.6'
}

这是 Gradle 构建文件。 它包括 Spark 核心组件和 slf4j 简单记录器的依赖项。

FirstSpark.java

package com.zetcode.firstspark;

import static spark.Spark.get;

public class FirstSpark {
    public static void main(String[] args) {
        get("/first", (req, res) -> "First Spark application");
    }
}

应用将"First Spark application"返回到 GET 请求。 当我们运行应用时,Spark 将启动嵌入式 Jetty Web 服务器。

get("/first", (req, res) -> "First Spark application");

get()方法映射 HTTP GET 请求的路由。 在 Spark 术语中,路由是处理器。路由是映射到处理器的 URL 模式。 处理器可以是物理文件,也可以是

$ gradle build

我们使用gradle build命令构建应用。

$ gradle run

我们使用gradle run命令运行该应用。 嵌入式 Jetty 服务器启动。

$ curl localhost:4567/first
First Spark application

我们使用curl工具将 GET 请求发送到服务器。 内置嵌入式 Jetty 服务器默认情况下监听端口 4567。

你好应用

第二个应用将向用户打招呼。 客户端发送带有 URL 的名称,应用向用户打招呼。

build.gradle

apply plugin: 'java'
apply plugin: 'application'

archivesBaseName = "hello"
version = '1.0'
mainClassName = "com.zetcode.hellospark.HelloSpark"

repositories {
  mavenCentral()
}

dependencies {
  compile 'com.sparkjava:spark-core:2.5'
  compile 'org.slf4j:slf4j-simple:1.7.6'
}

这是应用的 Gradle 构建文件。

$ tree
.
├── build.gradle
└── src
    └── main
        └── java
            └── com
                └── zetcode
                    └── hellospark
                        └── HelloSpark.java

6 directories, 2 files

这是项目结构。

HelloSpark.java

package com.zetcode.hellospark;

import static spark.Spark.get;

public class HelloSpark {
    public static void main(String[] args) {
        get("/hello/:name", (req, res) -> "Hello " + req.params(":name"));
    }
}

Spark 应用检索请求参数,生成一条消息,然后将其返回给调用方。

get("/hello/:name", (req, res) -> "Hello " + req.params(":name"));

params()方法返回提供的路由模式参数的值。

$ gradle build run

我们构建并运行该应用。

$ curl localhost:4567/hello/Peter
Hello Peter

我们向服务器发送请求; URL 包含一个名称。 该应用发回问候。

在 Tomcat 中运行 Spark 应用

默认情况下,Spark 应用在嵌入式 Jetty 服务器中运行。 在此示例中,我们显示了如何在 Tomcat 中运行 Spark Java 应用。 这次我们使用 Maven 构建工具并在 NetBeans 中创建一个项目。

NetBeans project structure

图:NetBeans 项目结构

该图显示了该项目在 NetBeans 中的外观。

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.zetcode</groupId>
    <artifactId>HelloSpark2</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>war</packaging>

    <name>HelloSpark2</name>

    <properties>
        <endorsed.dir>${project.build.directory}/endorsed</endorsed.dir>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>

    <dependencies>

        <dependency>
            <groupId>com.sparkjava</groupId>
            <artifactId>spark-core</artifactId>
            <version>2.5</version>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-simple</artifactId>
            <version>1.7.21</version>
        </dependency>

    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.1</version>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                    <compilerArguments>
                        <endorseddirs>${endorsed.dir}</endorseddirs>
                    </compilerArguments>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-war-plugin</artifactId>
                <version>2.3</version>
                <configuration>
                    <failOnMissingWebXml>false</failOnMissingWebXml>
                </configuration>
            </plugin>
        </plugins>
    </build>

</project>

这是 Maven 构建文件。

context.xml

<?xml version="1.0" encoding="UTF-8"?>
<Context path="/HelloSpark2"/>

这是context.xml文件。

web.xml

<?xml version="1.0" encoding="UTF-8"?>

<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
         version="3.1">

    <welcome-file-list>
        <welcome-file>index.html</welcome-file>
    </welcome-file-list>    

    <filter>
        <filter-name>SparkFilter</filter-name>
        <filter-class>spark.servlet.SparkFilter</filter-class>
        <init-param>
            <param-name>applicationClass</param-name>
            <param-value>com.zetcode.hellospark2.HelloSpark</param-value>
        </init-param>
    </filter>

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

</web-app>

web.xml部署描述符中,我们指定spark.servlet.SparkFilter

HelloSpark.java

package com.zetcode.hellospark2;

import static spark.Spark.get;
import spark.servlet.SparkApplication;

public class HelloSpark implements SparkApplication {

    @Override
    public void init() {

        get("/hello/:name", (request, response) -> "Hello " + request.params(":name"));
    }
}

我们实现SparkApplication接口,并在init()方法中指定路由。

最后,我们运行 Tomcat Web 服务器。

$ curl localhost:8084/HelloSpark2/hello/Peter
Hello Peter

NetBeans 的内置 Tomcat 监听端口 8084。

模板引擎

Spark 没有自己的模板系统。 它使用第三方引擎。 在以下两个示例中,我们使用 Thymeleaf 和 FreeMarker。

使用 Thymeleaf

在以下示例中,我们将把 Thymeleaf 模板引擎集成到我们的 Spark 应用中。 Thymeleaf 是适用于 Web 和独立环境的现代服务器端 Java 模板引擎。

$ tree
.
├── build.gradle
└── src
    └── main
        ├── java
        │   └── com
        │       └── zetcode
        │           └── thymeleaf
        │               └── SparkThymeleaf.java
        └── resources
            └── templates
                └── hello.html

这是项目的目录结构。 模板文件位于src/main/resources/templates目录中。

build.gradle

apply plugin: 'java'
apply plugin: 'application'

archivesBaseName = "sparkthymeleaf"
version = '1.0'
mainClassName = "com.zetcode.thymeleaf.SparkThymeleaf"

repositories {
  mavenCentral()
}

dependencies {
  compile 'com.sparkjava:spark-core:2.5'
  compile 'org.slf4j:slf4j-simple:1.7.6'
  compile 'com.sparkjava:spark-template-thymeleaf:2.3'
}

在这里,我们有 Gradle 构建文件,其中包含spark-template-thymeleaf依赖项。

SparkThymeleaf.java

package com.zetcode.thymeleaf;

import java.util.HashMap;
import java.util.Map;
import spark.ModelAndView;
import spark.Request;
import spark.Response;
import spark.template.thymeleaf.ThymeleafTemplateEngine;
import static spark.Spark.get;
import static spark.Spark.staticFileLocation;

public class SparkThymeleaf {

    public static void main(String[] args) {

        get("/hello/:name", SparkThymeleaf::message, new ThymeleafTemplateEngine());
    }

    public static ModelAndView message(Request req, Response res) {

        Map<String, Object> params = new HashMap<>();
        params.put("name", req.params(":name"));
        return new ModelAndView(params, "hello");
    }
}

应用读取请求参数并将其放入ModelAndView对象。

get("/hello/:name", SparkThymeleaf::message, new ThymeleafTemplateEngine());

ThymeleafTemplateEngine的实例传递给get()方法。

hello.html

<pre class="code">
<!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8"></meta>
    <title>Hello user</title>
</head>
<body>
<p th:inline="text">Hello, [[${name}]]!</p>
</body>
</html>

这是hello.html模板文件。 它引用随ModelAndView对象传递的名称变量。

$ curl localhost:4567/hello/Peter
<!DOCTYPE html>

<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>
    <meta charset="UTF-8" />
    <title>Hello user</title>
</head>
<body>
<p>Hello, Peter!</p>
</body>
</html>

我们得到这个输出。

FreeMarker

在以下示例中,我们将把 FreeMarker 模板引擎集成到我们的 Spark 应用中。 FreeMarker 是一个完善的 Java 模板引擎。

$ tree
.
├── build.gradle
└── src
    └── main
        ├── java
        │   └── com
        │       └── zetcode
        │           └── SparkFreeMarker.java
        └── resources
            └── views
                └── hello.ftl

这是项目的目录结构。 模板文件位于src/main/resources/views目录中。

build.gradle

apply plugin: 'application'

sourceCompatibility = '1.8'
version = '1.0'
mainClassName = "com.zetcode.SparkFreeMarker"

repositories {
    mavenCentral()

}

dependencies {
  compile 'com.sparkjava:spark-core:2.5.5'
  compile 'org.slf4j:slf4j-simple:1.7.24'
  compile 'com.sparkjava:spark-template-freemarker:2.5.5'
}

在这里,我们有 Gradle 构建文件,其中包含spark-template-freemarker依赖项。

SparkFreeMarker.java

package com.zetcode;

import freemarker.template.Configuration;
import freemarker.template.Version;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import spark.ModelAndView;
import spark.Request;
import spark.Response;
import static spark.Spark.get;
import spark.template.freemarker.FreeMarkerEngine;

public class SparkFreeMarker {

    public static void main(String[] args) throws IOException {

        Configuration conf = new Configuration(new Version(2, 3, 23));
        conf.setClassForTemplateLoading(SparkFreeMarker.class, "/views");

        get("/hello/:name", SparkFreeMarker::message, new FreeMarkerEngine(conf));
    }

    public static ModelAndView message(Request req, Response res) {

        Map<String, Object> params = new HashMap<>();
        params.put("name", req.params(":name"));
        return new ModelAndView(params, "hello.ftl");
    }
}

我们为 FreeMarker 设置了相同的应用。

Configuration conf = new Configuration(new Version(2, 3, 23));
conf.setClassForTemplateLoading(SparkFreeMarker.class, "/views");

我们用Configuration类配置 FreeMarker。 模板文件将放置在views目录中,该目录必须位于类路径上。

get("/hello/:name", SparkFreeMarker::message, new FreeMarkerEngine(conf));

FreeMarkerEngine传递给get()方法。

hello.ftl

<!DOCTYPE html>
<html>
    <head>
        <title>Home page</title>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
    </head>
    <body>
        <p>Hello ${name}</p>
    </body>
</html>

这是hello.ftl模板文件; 它引用随ModelAndView对象传递的名称变量。

$ curl localhost:4567/hello/Lucy
<!DOCTYPE html>
<html>
    <head>
        <title>Home page</title>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
    </head>
    <body>
        <p>Hello Lucy</p>
    </body>
</html>

这是输出。

在本教程中,我们介绍了 Spark Java 框架。 您可能也对相关教程感兴趣: Java 教程游戏介绍Stripes 介绍Jtwig 教程



回到顶部