C'est un framework d'application web très simple, décrit sur le site officiel (http://sparkjava.com/) comme suit:
Spark - A micro framework for creating web applications in Kotlin and Java 8 with minimal effort
Il a une note de: star: 7199 sur github (au 3/4/2018), il semble donc être un framework assez utilisé.
En tant que fonctionnalité, il est très facile d'implémenter une application Web à l'aide d'expressions lambda et de méthodes statiques. Vous trouverez ci-dessous un échantillon de la documentation officielle.
HelloWorld.java
import static spark.Spark.*;
public class HelloWorld {
public static void main(String[] args) {
get("/hello", (req, res) -> "Hello World");
}
}
Exécutez comme une application Java normale avec une méthode principale.
Une fois l'application lancée, accédez à http: // localhost: 4567 / hello avec un navigateur Web et vous verrez Hello World
. C'est très simple!
Cette fois, je voudrais créer une application Todo de service REST à l'aide de ce Spark Framework.
Todo.java
package com.example.spark.demo;
import java.io.Serializable;
import java.util.Date;
public class Todo implements Serializable {
private static final long serialVersionUID = 1L;
private String todoId;
private String todoTitle;
private Date createdAt;
private boolean finished;
// constructor, setter, getter omitted
}
Numéro d'article | chemin | Méthode HTTP | La description |
---|---|---|---|
1 | /api/todo | POST | Créer un TODO avec les données transmises |
2 | /api/todo/:todoId | GET | Obtient le TODO spécifié par todoId |
3 | /api/todo/:todoId | PUT | Mettre à jour le TODO spécifié par todoId |
4 | /api/todo/:todoId | DELETE | Supprimer le TODO spécifié par todoId |
Tout d'abord, créez un projet vierge avec mvn.
Exemple de commande dans Windows
mvn archetype:generate ^
-DinteractiveMode=false ^
-DarchetypeArtifactId=maven-archetype-quickstart ^
-DgroupId=com.example.spark.demo ^
-DartifactId=spark-demo
Après avoir créé un projet vierge, ajoutez la bibliothèque à utiliser cette fois dans pom.xml
.
Cette fois, nous utiliserons GSON pour convertir le format JSON. Les autres bibliothèques sont bien. Puisque le document officiel de Spark Framework utilisait GSON, j'ai décidé d'utiliser GSON cette fois.
pom.xml
<!-- add spark framework -->
<dependency>
<groupId>com.sparkjava</groupId>
<artifactId>spark-core</artifactId>
<version>2.7.1</version>
</dependency>
<!-- add gson -->
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.8.2</version>
</dependency>
Lorsque l'ajout de la bibliothèque à pom.xml
est terminé, la bibliothèque sera acquise, alors essayons de construire avec la commande suivante. C'est OK si «BUILD SUCCESS» s'affiche.
Commande de construction d'essai
mvn package -Dmaven.test.skip=true
App.java
package com.example.spark.demo;
import static spark.Spark.*;
/**
*★ Point 1
* spark demo app
*/
public class App {
//★ Point 1
public static void main(String[] args) {
//★ Point 2
// initialize
initialize();
//★ Point 3
// define api
TodoApi.api();
// omitted
}
//★ Point 2
private static void initialize() {
// server port
port(8090);
// static files
staticFiles.location("/public");
// connection pool
// maxThreads, minThreads, timeOutMillis
threadPool(8, 2, 30000);
}
}
** ★ Point 1 ** L'application Spark Framework est implémentée comme une application Java normale exécutée par la méthode Main.
** ★ Point 2 ** Le processus de paramétrage initial (configuration) de l'application a été découpé à la méthode ʻinitialize`. Cette fois, j'ai effectué les trois réglages initiaux suivants qui sont susceptibles d'être utilisés fréquemment.
Modification du port du serveur de la valeur par défaut «4567» à «8090» avec la méthode «port».
Ce n'est pas nécessaire pour un service REST normal, mais il peut être utilisé comme un simple serveur Web, je vais donc vous expliquer comment publier des fichiers statiques sous le chemin de classe vers le Web.
Spécifiez le répertoire à publier par la méthode staticFiles.location
.
Dans les exemples de paramètres, vous pouvez obtenir le fichier / spark-demo / src / main / resources / public / css / styles.css
en accédant à http: // localhost: 8090 / css / styles.css
avec un navigateur Web. ..
Définissez le pool de connexions avec la méthode threadPool
.
Les arguments sont le nombre maximum de threads, le nombre minimum de threads et le délai d'expiration (en millisecondes) dans l'ordre.
** ★ Point 3 ** Nous avons décidé de définir l'API Web comme une classe distincte en tenant compte de la maintenabilité lors d'ajouts ou de modifications.
TodoApi.java
package com.example.spark.demo;
import static spark.Spark.*;
import java.util.HashMap;
import java.util.Map;
/**
*★ Point 4
* Web API for TODO
*/
public class TodoApi {
//★ Point 4
public static void api() {
//★ Point 5
TodoService todoService = new TodoService();
JsonTransformer jsonTransformer = new JsonTransformer();
//★ Point 6
path("/api", () -> {
path("/todo", () -> {
post("", (request, response) -> {
String json = request.body();
Todo todo = jsonTransformer.fromJson(json, Todo.class);
return todoService.create(todo);
}, jsonTransformer);
get("/:todoId", (request, response) -> {
return todoService.find(request.params(":todoId"));
}, jsonTransformer);
put("/:todoId", (request, response) -> {
String json = request.body();
Todo todo = jsonTransformer.fromJson(json, Todo.class);
todo.setTodoId(request.params(":todoId"));
return todoService.update(todo);
}, jsonTransformer);
delete("/:todoId", (request, response) -> {
todoService.delete(request.params(":todoId"));
return success();
}, jsonTransformer);
});
//★ Point 7
// set response-type to all request of under '/api'
after("/*", (request, response) -> {
response.type("application/json;charset=UTF-8");
});
});
}
private static Map<String, String> success() {
Map<String, String> map = new HashMap<String, String>();
map.put("result", "success!");
return map;
}
}
** ★ Point 4 ** Définissez le traitement de l'API Web comme une classe régulière. Comme il existe de nombreuses méthodes statiques dans l'API Spark Framework, j'ai décidé de la définir comme une méthode statique ʻapi` cette fois.
** ★ Point 5 ** Créez une instance des classes de logique métier (TodoService) et de transformation de format (JsonTransformer). Nous parlerons des deux classes plus tard.
** ★ Point 6 ** Tel est le but de cet article.
path
./: todoId
et obtenez-le avec la méthode request.params
.request.body
.Voir Official Documentation Routes et Request pour plus d'informations.
** ★ Point 7 ** Vous pouvez ajouter un traitement avant et après l'API Web avec la fonction appelée filtre de Spark Framework. Dans l'exemple, nous avons défini un filtre «après» qui définit «application / json; charset = UTF-8» sur «content-type» dans l'en-tête de réponse pour toutes les requêtes dont le chemin est sous «/ api».
En plus du filtre «après», il existe également des filtres «avant» et «après». Pour plus d'informations sur les filtres, consultez la documentation officielle (http://sparkjava.com/documentation#filters).
JsonTransformer.java
package com.example.spark.demo;
import com.google.gson.Gson;
import spark.ResponseTransformer;
//★ Point 8
public class JsonTransformer implements ResponseTransformer {
private Gson gson = new Gson();
//★ Point 8
@Override
public String render(Object model) throws Exception {
return gson.toJson(model);
}
//★ Point 9
public <T> T fromJson(String json, Class<T> classOfT) {
return gson.fromJson(json, classOfT);
}
}
** ★ Point 8 **
Définit une classe qui implémente l'interface spark.ResponseTransformer
.
Le but de cette interface est de convertir le résultat du traitement de la méthode API (le résultat de l'expression lambda au point 6) en une chaîne à écrire dans la réponse HTTP.
Implémentez ce processus dans render
car @ Override
est donné.
Cette fois, le processus décrit dans le document officiel est utilisé tel quel, et il est converti au format JSON à l'aide de GSON.
** ★ Point 9 **
Comme le nom de ResponseTransformer
l'indique, il s'agit à l'origine d'une classe de conversion de données de réponse, mais j'ai décidé de convertir la conversion d'objet de JSON au moment de la demande ici. (Je voulais juste réutiliser les objets GSON)
À propos, il n'existe pas de RequestTransformer
qui transforme les données de demande dans Spark Framework.
TodoService.java
package com.example.spark.demo;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
//★ Point 10
public class TodoService {
private Map<String, Todo> store = new HashMap<String, Todo>();
public Todo find(String todoId) {
return store.get(todoId);
}
public void delete(String todoId) {
store.remove(todoId);
System.out.println("delete todoId : " + todoId);
}
public Todo update(Todo todo) {
Todo updatedTodo = store.get(todo.getTodoId());
if (updatedTodo != null) {
updatedTodo.setTodoTitle(todo.getTodoTitle());
updatedTodo.setFinished(todo.isFinished());
}
return updatedTodo;
}
public Todo create(Todo todo) {
String todoId = UUID.randomUUID().toString();
Todo registeredTodo = new Todo(todoId, todo.getTodoTitle(), new Date(),
false);
store.put(todoId, registeredTodo);
System.out.println("registeredTodo : " + registeredTodo);
return registeredTodo;
}
}
** ★ Point 10 ** Implémentez la logique métier de l'application TODO. Cependant, il s'agit d'un processus factice approprié car il n'utilise pas les fonctions de Spark Framework. Cette fois, nous n'avons pas accédé à la base de données et avons utilisé Map pour le traitement CRUD en mémoire.
Puisqu'il s'agit d'un micro service, j'aimerais simplifier l'exécution. Je veux le construire comme un fichier jar exécutable comme ʻuber.jar`.
pom.xml
<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/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example.spark.demo</groupId>
<artifactId>spark-demo</artifactId>
<packaging>jar</packaging>
<version>1.0-SNAPSHOT</version>
<name>spark-demo</name>
<url>http://maven.apache.org</url>
<dependencies>
<!-- add spark framework -->
<dependency>
<groupId>com.sparkjava</groupId>
<artifactId>spark-core</artifactId>
<version>2.7.1</version>
</dependency>
<!-- add gson -->
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.8.2</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
</dependencies>
<!-- java8 -->
<properties>
<java.version>1.8</java.version>
<maven.compiler.target>${java.version}</maven.compiler.target>
<maven.compiler.source>${java.version}</maven.compiler.source>
</properties>
<!-- add for executable jar -->
<build>
<plugins>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<mainClass>com.example.spark.demo.App</mainClass>
</manifest>
</archive>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
</plugin>
</plugins>
</build>
</project>
Une fois que vous avez un fichier jar exécutable, exécutez-le avec java -jar
.
C:\tmp\spark\spark-demo>java -jar target/spark-demo-1.0-SNAPSHOT-jar-with-dependencies.jar
SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.
Cette fois, j'ai expliqué la mise en œuvre de micro services à l'aide de Spark Framework. C'est très simple et facile à mettre en œuvre, et il peut être construit comme un fichier jar exécutable unique, donc je pense qu'il est facile à publier. Dans l'exemple, la vérification d'entrée est omise, mais il s'agit en fait d'un processus nécessaire. Java-json-tools / json-schema-validator lors de la vérification de l'entrée comme JSON, lors de la vérification de l'entrée comme Java Bean Validation est recommandé.
Recommended Posts