原文: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 用于构建应用。

  1. $ tree
  2. .
  3. ├── build.gradle
  4. └── src
  5. └── main
  6. └── java
  7. └── com
  8. └── zetcode
  9. └── firstspark
  10. └── FirstSpark.java

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

build.gradle

  1. apply plugin: 'java'
  2. apply plugin: 'application'
  3. archivesBaseName = "first"
  4. version = '1.0'
  5. mainClassName = "com.zetcode.firstspark.FirstSpark"
  6. repositories {
  7. mavenCentral()
  8. }
  9. dependencies {
  10. compile 'com.sparkjava:spark-core:2.5'
  11. compile 'org.slf4j:slf4j-simple:1.7.6'
  12. }

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

FirstSpark.java

  1. package com.zetcode.firstspark;
  2. import static spark.Spark.get;
  3. public class FirstSpark {
  4. public static void main(String[] args) {
  5. get("/first", (req, res) -> "First Spark application");
  6. }
  7. }

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

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

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

  1. $ gradle build

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

  1. $ gradle run

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

  1. $ curl localhost:4567/first
  2. First Spark application

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

你好应用

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

build.gradle

  1. apply plugin: 'java'
  2. apply plugin: 'application'
  3. archivesBaseName = "hello"
  4. version = '1.0'
  5. mainClassName = "com.zetcode.hellospark.HelloSpark"
  6. repositories {
  7. mavenCentral()
  8. }
  9. dependencies {
  10. compile 'com.sparkjava:spark-core:2.5'
  11. compile 'org.slf4j:slf4j-simple:1.7.6'
  12. }

这是应用的 Gradle 构建文件。

  1. $ tree
  2. .
  3. ├── build.gradle
  4. └── src
  5. └── main
  6. └── java
  7. └── com
  8. └── zetcode
  9. └── hellospark
  10. └── HelloSpark.java
  11. 6 directories, 2 files

这是项目结构。

HelloSpark.java

  1. package com.zetcode.hellospark;
  2. import static spark.Spark.get;
  3. public class HelloSpark {
  4. public static void main(String[] args) {
  5. get("/hello/:name", (req, res) -> "Hello " + req.params(":name"));
  6. }
  7. }

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

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

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

  1. $ gradle build run

我们构建并运行该应用。

  1. $ curl localhost:4567/hello/Peter
  2. Hello Peter

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

在 Tomcat 中运行 Spark 应用

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

Spark Java 简介 - 图1

图:NetBeans 项目结构

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

pom.xml

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  3. xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  4. <modelVersion>4.0.0</modelVersion>
  5. <groupId>com.zetcode</groupId>
  6. <artifactId>HelloSpark2</artifactId>
  7. <version>1.0-SNAPSHOT</version>
  8. <packaging>war</packaging>
  9. <name>HelloSpark2</name>
  10. <properties>
  11. <endorsed.dir>${project.build.directory}/endorsed</endorsed.dir>
  12. <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  13. </properties>
  14. <dependencies>
  15. <dependency>
  16. <groupId>com.sparkjava</groupId>
  17. <artifactId>spark-core</artifactId>
  18. <version>2.5</version>
  19. </dependency>
  20. <dependency>
  21. <groupId>org.slf4j</groupId>
  22. <artifactId>slf4j-simple</artifactId>
  23. <version>1.7.21</version>
  24. </dependency>
  25. </dependencies>
  26. <build>
  27. <plugins>
  28. <plugin>
  29. <groupId>org.apache.maven.plugins</groupId>
  30. <artifactId>maven-compiler-plugin</artifactId>
  31. <version>3.1</version>
  32. <configuration>
  33. <source>1.8</source>
  34. <target>1.8</target>
  35. <compilerArguments>
  36. <endorseddirs>${endorsed.dir}</endorseddirs>
  37. </compilerArguments>
  38. </configuration>
  39. </plugin>
  40. <plugin>
  41. <groupId>org.apache.maven.plugins</groupId>
  42. <artifactId>maven-war-plugin</artifactId>
  43. <version>2.3</version>
  44. <configuration>
  45. <failOnMissingWebXml>false</failOnMissingWebXml>
  46. </configuration>
  47. </plugin>
  48. </plugins>
  49. </build>
  50. </project>

这是 Maven 构建文件。

context.xml

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

这是context.xml文件。

web.xml

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
  5. version="3.1">
  6. <welcome-file-list>
  7. <welcome-file>index.html</welcome-file>
  8. </welcome-file-list>
  9. <filter>
  10. <filter-name>SparkFilter</filter-name>
  11. <filter-class>spark.servlet.SparkFilter</filter-class>
  12. <init-param>
  13. <param-name>applicationClass</param-name>
  14. <param-value>com.zetcode.hellospark2.HelloSpark</param-value>
  15. </init-param>
  16. </filter>
  17. <filter-mapping>
  18. <filter-name>SparkFilter</filter-name>
  19. <url-pattern>/*</url-pattern>
  20. </filter-mapping>
  21. </web-app>

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

HelloSpark.java

  1. package com.zetcode.hellospark2;
  2. import static spark.Spark.get;
  3. import spark.servlet.SparkApplication;
  4. public class HelloSpark implements SparkApplication {
  5. @Override
  6. public void init() {
  7. get("/hello/:name", (request, response) -> "Hello " + request.params(":name"));
  8. }
  9. }

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

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

  1. $ curl localhost:8084/HelloSpark2/hello/Peter
  2. Hello Peter

NetBeans 的内置 Tomcat 监听端口 8084。

模板引擎

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

使用 Thymeleaf

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

  1. $ tree
  2. .
  3. ├── build.gradle
  4. └── src
  5. └── main
  6. ├── java
  7. └── com
  8. └── zetcode
  9. └── thymeleaf
  10. └── SparkThymeleaf.java
  11. └── resources
  12. └── templates
  13. └── hello.html

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

build.gradle

  1. apply plugin: 'java'
  2. apply plugin: 'application'
  3. archivesBaseName = "sparkthymeleaf"
  4. version = '1.0'
  5. mainClassName = "com.zetcode.thymeleaf.SparkThymeleaf"
  6. repositories {
  7. mavenCentral()
  8. }
  9. dependencies {
  10. compile 'com.sparkjava:spark-core:2.5'
  11. compile 'org.slf4j:slf4j-simple:1.7.6'
  12. compile 'com.sparkjava:spark-template-thymeleaf:2.3'
  13. }

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

SparkThymeleaf.java

  1. package com.zetcode.thymeleaf;
  2. import java.util.HashMap;
  3. import java.util.Map;
  4. import spark.ModelAndView;
  5. import spark.Request;
  6. import spark.Response;
  7. import spark.template.thymeleaf.ThymeleafTemplateEngine;
  8. import static spark.Spark.get;
  9. import static spark.Spark.staticFileLocation;
  10. public class SparkThymeleaf {
  11. public static void main(String[] args) {
  12. get("/hello/:name", SparkThymeleaf::message, new ThymeleafTemplateEngine());
  13. }
  14. public static ModelAndView message(Request req, Response res) {
  15. Map<String, Object> params = new HashMap<>();
  16. params.put("name", req.params(":name"));
  17. return new ModelAndView(params, "hello");
  18. }
  19. }

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

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

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

hello.html

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

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

  1. $ curl localhost:4567/hello/Peter
  2. <!DOCTYPE html>
  3. <html lang="en" xmlns="http://www.w3.org/1999/xhtml">
  4. <head>
  5. <meta charset="UTF-8" />
  6. <title>Hello user</title>
  7. </head>
  8. <body>
  9. <p>Hello, Peter!</p>
  10. </body>
  11. </html>

我们得到这个输出。

FreeMarker

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

  1. $ tree
  2. .
  3. ├── build.gradle
  4. └── src
  5. └── main
  6. ├── java
  7. └── com
  8. └── zetcode
  9. └── SparkFreeMarker.java
  10. └── resources
  11. └── views
  12. └── hello.ftl

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

build.gradle

  1. apply plugin: 'application'
  2. sourceCompatibility = '1.8'
  3. version = '1.0'
  4. mainClassName = "com.zetcode.SparkFreeMarker"
  5. repositories {
  6. mavenCentral()
  7. }
  8. dependencies {
  9. compile 'com.sparkjava:spark-core:2.5.5'
  10. compile 'org.slf4j:slf4j-simple:1.7.24'
  11. compile 'com.sparkjava:spark-template-freemarker:2.5.5'
  12. }

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

SparkFreeMarker.java

  1. package com.zetcode;
  2. import freemarker.template.Configuration;
  3. import freemarker.template.Version;
  4. import java.io.IOException;
  5. import java.util.HashMap;
  6. import java.util.Map;
  7. import spark.ModelAndView;
  8. import spark.Request;
  9. import spark.Response;
  10. import static spark.Spark.get;
  11. import spark.template.freemarker.FreeMarkerEngine;
  12. public class SparkFreeMarker {
  13. public static void main(String[] args) throws IOException {
  14. Configuration conf = new Configuration(new Version(2, 3, 23));
  15. conf.setClassForTemplateLoading(SparkFreeMarker.class, "/views");
  16. get("/hello/:name", SparkFreeMarker::message, new FreeMarkerEngine(conf));
  17. }
  18. public static ModelAndView message(Request req, Response res) {
  19. Map<String, Object> params = new HashMap<>();
  20. params.put("name", req.params(":name"));
  21. return new ModelAndView(params, "hello.ftl");
  22. }
  23. }

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

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

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

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

FreeMarkerEngine传递给get()方法。

hello.ftl

  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <title>Home page</title>
  5. <meta charset="UTF-8">
  6. <meta name="viewport" content="width=device-width, initial-scale=1.0">
  7. </head>
  8. <body>
  9. <p>Hello ${name}</p>
  10. </body>
  11. </html>

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

  1. $ curl localhost:4567/hello/Lucy
  2. <!DOCTYPE html>
  3. <html>
  4. <head>
  5. <title>Home page</title>
  6. <meta charset="UTF-8">
  7. <meta name="viewport" content="width=device-width, initial-scale=1.0">
  8. </head>
  9. <body>
  10. <p>Hello Lucy</p>
  11. </body>
  12. </html>

这是输出。

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