Thymeleaf ohne Servlet in Standalone-Anwendungen nutzen

Thymeleaf ist eine Template Engine, welche für die Nutzung mittels Java (oder anderer JVM-Sprachen) gedacht ist. Über diese können entsprechende Templates geschrieben werden, anschließend gefüllt und genutzt werden. Thymeleaf verfügt über eine Dokumentation, allerdings fehlt mir dort ein minimales Beispiel für Anwendungen, welche sich nicht im Web (sogenannte non-web environments) abspielen.

thymeleaf.org

Für ein minimales Beispiel wird natürlich ein Template benötigt. Dieses wird hier als HTML definiert:

<!DOCTYPE html>
<html>
<head>
    <title th:text="${title}"></title>
</head>
<body>
</body>
</html>

Interessant ist hierbei das Feld title, welches wir mit einem Titel füllen wollen. Im Java-Quellcode sieht die Implementation wie folgt aus:

ClassLoaderTemplateResolver resolver = new ClassLoaderTemplateResolver();
resolver.setPrefix("templates/");
resolver.setTemplateMode("HTML5");
resolver.setSuffix(".html");

TemplateEngine templateEngine = new TemplateEngine();
templateEngine.setTemplateResolver(resolver);

Context context = new Context(Locale.GERMAN);
context.setVariable("title", "Ein minimales Beispiel");

final String content = templateEngine.process("header.html", context);

Im ersten Schritt wird mit dem ClassLoaderTemplateResolver ein Resolver definiert, welcher schlussendlich dafür sorgt die Templates aus den Ressourcen (im resources-Ordner) bezogen werden. Daneben wird der Template-Modus eingestellt. Neben dem Modus HTML5 unterstützt Thymeleaf wie z.B. TEXT oder JAVASCRIPT. Danach wird die Template Engine erstellt und ihr der Resolver zugewiesen. Die Variablen, welche in diesem Fall im Template genutzt werden, werden über den Context definiert und gesetzt. Anschließend wird das Ganze an die process-Methode der Template Engine übergeben. Als Ergebnis erhalten wir im String content folgenden Inhalt:

<!DOCTYPE html>
<html>
<head>
    <title">Ein minimales Beispiel</title>
</head>
<body>
</body>
</html>

Damit wurde Thymeleaf in einer minimalen Variante angewendet. Die offizielle Seite der Template Engine ist unter thymeleaf.org zu finden. Lizenziert ist Thymeleaf unter der Apache License in der Version 2.0 und damit freie Software.

libGDX; Multiplattform-Game-Engine für Java

Für ein kleineres Projekt war ich auf der Suche nach einer Game-Engine für Java. Empfohlen wurde mir schlussendlich libGDX. Dabei handelt es sich um eine Game-Engine welche ursprünglich für Android entwickelt wurde. Mario Zechner, der ursprüngliche Entwickler der Engine, baute allerdings nach relativ kurzer Zeit eine Unterstützung für Desktopsysteme ein. Mittlerweile werden als Zielsysteme Linux, macOS, Windows, Android, iOS und der Webbrowser unterstützt.

Ein kleines Projekt in libGDX, nach ein paar Stunden Entwicklungszeit

libGDX eignet sich für 2D- als auch 3D-Spiele und ist relativ einfach strukturiert, so dass man in wenigen Stunden von einer Idee zu einem Ergebnis kommen kann. Die seit mittlerweile 2009 in der Entwicklung befindliche Engine wurde 2010 erstmalig veröffentlicht und hat sich seitdem stetig weiterentwickelt. Technisch basiert die Engine neben Java auf OpenGL, welches zum Rendering der Spieleszenen genutzt wird.

Die Liste der implementierten Features von libGDX ist lang. So wird Audio ebenso unterstützt wie die abstrakte Behandlung von Eingabegeräten, so das ein Spiel auf Touchscreen ebenso läuft wie auf gewöhnlichen Rechnern. Im Bereich der Grafik werden Partikelsyssteme, die Nutzung von Tile-Maps (mit einer nativen Unterstützung des TMX-Dateiformates) und vieles mehr unterstützt. Der Entwickler nutzt dazu die entsprechenden High-Level-APIs und muss sich nicht mit der konkreten Implementierung herumschlagen. Daneben existieren entsprechende Hilfs- bzw. Datenklassen, welche die verwendete Mathematik wie Matrizen, Vektoren und ähnliches abdeckt.

Aktivieren Sie JavaScript um das Video zu sehen.
Video-Link: https://www.youtube.com/watch?v=hA2e3xIuNlk

Neben den im Kern vorhandenen Features, existiert ebenfalls eine Unterstützung für zusätzliche Module, so können unter anderem Box2D und das Entity-System Ashley als zusätzliche Module eingebunden werden.

Die offizielle Seite des Projektes ist unter libgdx.badlogicgames.com zu finden. Neben der spartanischen Dokumentation auf der offiziellen Webseite, ist die Wiki des GitHub-Projektes ein guter Einstiegspunkt für den Start mit libGDX. Der Quelltext der Engine ist ebenfalls auf GitHub zu finden. Die Engine ist unter der Apache License in Version 2 lizenziert und somit freie Software.

Bibliothek zur Nutzung der MediaWiki-API unter .NET

Für ein kleines Projekt war ich auf der Suche nach einer halbwegs aktuellen Bibliothek zur Nutzung der MediaWiki-API. Wenn man sich auf der entsprechenden Seite in der MediaWiki-Dokumentation umschaut, wird man feststellen das einem nicht all zu viele Bibliotheken zur Verfügung stehen.

Die Auswahl an .NET Bibliotheken fällt eher mager aus

Genutzt habe ich letztendlich die Bibliothek Wiki Client Library, da diese halbwegs aktuell ist und mit meinen MediaWiki-Installationen problemlos zusammenarbeitet. Ein minimales Beispiel zur Bearbeitung einer Wiki-Seite sieht mit der Bibliothek wie folgt aus:

// Init
var client = new WikiClient
{
    ClientUserAgent = "WikiBot"
};

var site = new WikiSite(client, https://wiki.example.com/api.php);

// Login
await site.Initialization;
try
{
    await site.LoginAsync("username", "password");
}
catch (WikiClientException ex)
{
    Console.WriteLine(ex.Message);
}

// Edit site
var page = new WikiPage(site, buildingName);

// Load page
await page.RefreshAsync(PageQueryOptions.FetchContent);

// Update page
page.Content = "new content";
await page.UpdateContentAsync("New page created.", minor: false, bot: true);

// Logout
await site.LogoutAsync();

Über die Nutzung von Generatoren ist es möglich größere Bereiche wie z.B. Kategorien oder Suchergebnisse zu iterieren:

// Iterate all pages
var generator = new AllPagesGenerator(site)
{
    StartTitle = "A",
    NamespaceId = BuiltInNamespaces.Main,
    PaginationSize = 50
};

using (var enumerator = generator.EnumPagesAsync().GetEnumerator())
{
    int index = 0;

    while (await enumerator.MoveNext(CancellationToken.None))
    {
        // Debug output
        var page = enumerator.Current;
        Console.WriteLine("{0}: {1}", index, page);
        index++;

        // Load page
        await page.RefreshAsync(PageQueryOptions.FetchContent);

        // Update page
        page.Content = "new content";
        await page.UpdateContentAsync("Update page.", minor: true, bot: true);
    }
}

Der Quelltext der Wiki Client Library ist auf GitHub zu finden. Lizenziert ist er unter der Apache Licence 2 und damit freie Software.

Clients und Server-Stubs mittels Swagger Codegen erzeugen

Mit Swagger gibt es seit einigen Jahren eine Möglichkeit REST-API sinnvoll zu dokumentieren und zu generieren. Aus einer YAML-Datei, welche die Beschreibung der API enthält kann mit dem Swagger Code Generator (kurz Swagger Codegen) eine entsprechende Client-Bibliothek oder ein Server-Stub erzeugt werden. Eine solche minimale YAML-Datei könnte wie folgt aussehen:

swagger: '2.0'
info:
  description: "API"
  version: "2018.04"
  title: "API"
host: "api.example.com"
basePath: "/v1"
schemes: 
- "https"
paths:
  /tree:
    get:
      produces: 
      - "application/json"
      summary: Returns the document tree
      tags:
      - "Document tree"
      description: Lorem Ipsum dolor sit amet
      responses:
        200:
          description: OK

In dieser Datei wird eine Ressource mit dem Namen tree und für diese eine Get-Methode definiert. Um daraus nun die Client-Bibliotheken bzw. Server-Stubs zu generieren muss der Swagger Codegen über Git bezogen, anschließend kompiliert und paketiert werden:

https://github.com/swagger-api/swagger-codegen.git
cd swagger-codegen
mvn clean package

Zur Erzeugung eines PHP-Server-Stubs mit dem Slim-Framework kann der Swagger Codegen anschließend wie folgt genutzt werden:

java -jar modules/swagger-codegen-cli/target/swagger-codegen-cli.jar generate -i api.yaml   -l slim -o folder/slim

Eine Client-Bibliothek wird auf dem gleichen Weg erzeugt:

java -jar modules/swagger-codegen-cli/target/swagger-codegen-cli.jar generate -i api.yaml   -l javascript -o folder/javascript

In diesem Fall wird eine JavaScript-Client-Bibliothek erzeugt. Die verfügbaren Sprachen bzw. Frameworks für die Clients und Server-Stubs erzeugt werden können, können mit dem Befehl:

java -jar modules/swagger-codegen-cli/target/swagger-codegen-cli.jar langs

angezeigt werden. Die Ausgabe spezifiziert alle vorhandenen Generatoren:

Available languages: [ada, ada-server, akka-scala, android, apache2, apex, aspnetcore, bash, csharp, clojure, cwiki, cpprest, csharp-dotnet2, dart, elixir, elm, eiffel, erlang-client, erlang-server, finch, flash, python-flask, go, go-server, groovy, haskell-http-client, haskell, jmeter, jaxrs-cxf-client, jaxrs-cxf, java, inflector, jaxrs-cxf-cdi, jaxrs-spec, jaxrs, msf4j, java-pkmst, java-play-framework, jaxrs-resteasy-eap, jaxrs-resteasy, javascript, javascript-closure-angular, java-vertx, kotlin, lua, lumen, nancyfx, nodejs-server, objc, perl, php, powershell, pistache-server, python, qt5cpp, r, rails5, restbed, ruby, rust, rust-server, scala, scala-gatling, scala-lagom-server, scalatra, scalaz, php-silex, sinatra, slim, spring, dynamic-html, html2, html, swagger, swagger-yaml, swift4, swift3, swift, php-symfony, tizen, typescript-aurelia, typescript-angular, typescript-inversify, typescript-angularjs, typescript-fetch, typescript-jquery, typescript-node, undertow, ze-ph, kotlin-server]

Lizenziert ist der Swagger Codegen unter der Apache Licence in der Version 2 und somit freie Software.

Domänenspezifische Sprache für Tests von REST-Schnittstellen

Eine domänenspezifische Sprache, kurz DSL, ist eine auf ein bestimmtes Problemfeld abgestimmte Sprache. Mit dem freien REST Assured existiert eine solche Sprache für den effektiven Test von REST-Schnittstellen. Genutzt wird REST Assured hauptsächlich unter Java und Groovy. Eine einfache Überprüfung des Statuscodes einer API-Anfrage würde in REST Assured wie folgt aussehen:

given().get("api.example.com").then().assertThat().statusCode(200);

Daneben sind auch komplexe Tests wie die Auswertung von zurückgegebenen JSON-Strukturen und Daten, sowie die Verknüpfung unterschiedlicher Bedingungen ohne Probleme zu implementieren. Eine große Übersicht über die Möglichkeiten von REST Assured bietet der Usage-Guide des Projektes.

rest-assured.io

Die Projektseite von REST Assured ist unter rest-assured.io zu finden. Der unter der Apache Lizenz (Version 2.0) lizenzierte Quellcode kann auf GitHub gefunden werden.