Java >> Java Tutorial >  >> Tag >> Spring

Verwenden von Asciidoctor mit Spring:Rendern von Asciidoc-Dokumenten mit Spring MVC

Asciidoc ist ein textbasiertes Dokumentenformat, und deshalb ist es sehr nützlich, wenn wir unsere Dokumente in ein Versionskontrollsystem einbinden und die Änderungen zwischen verschiedenen Versionen verfolgen möchten. Dies macht Asciidoc zu einem perfekten Werkzeug zum Schreiben von Büchern, technischen Dokumenten, FAQs oder Benutzerhandbüchern.

Nachdem wir ein Asciidoc-Dokument erstellt haben, stehen die Chancen gut, dass wir es veröffentlichen möchten, und eine Möglichkeit, dies zu tun, besteht darin, dieses Dokument auf unserer Website zu veröffentlichen. Heute lernen wir, wie wir Asciidoc-Dokumente mit AsciidoctorJ in HTML umwandeln und das erstellte HTML mit Spring MVC rendern können.

Die Anforderungen unserer Bewerbung sind:

  • Es muss Asciidoc-Dokumente unterstützen, die im Klassenpfad gefunden werden.
  • Es muss Asciidoc-Markup unterstützen, das als String angegeben wird Objekt.
  • Es muss die Asciidoc-Dokumente in HTML umwandeln und das erstellte HTML rendern.
  • Es muss den erstellten HTML-Code in das Layout unserer Anwendung „einbetten“.

Beginnen wir damit, die erforderlichen Abhängigkeiten mit Maven abzurufen.

Erforderliche Abhängigkeiten mit Maven erhalten

Wir können die erforderlichen Abhängigkeiten mit Maven erhalten, indem wir diesen Schritten folgen:

  1. Aktivieren Sie die Spring IO-Plattform.
  2. Konfigurieren Sie die erforderlichen Abhängigkeiten.

Zuerst , können wir die Spring IO-Plattform aktivieren, indem wir das folgende Snippet zu unserer POM-Datei hinzufügen:

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>io.spring.platform</groupId>
            <artifactId>platform-bom</artifactId>
            <version>1.0.2.RELEASE</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

Zweiter , können wir die erforderlichen Abhängigkeiten konfigurieren, indem wir diesen Schritten folgen:

  1. Konfigurieren Sie die Logging-Abhängigkeiten in der pom.xml Datei.
  2. Fügen Sie die spring-webmvc-Abhängigkeit zur pom.xml hinzu Datei.
  3. Fügen Sie die Servlet-API-Abhängigkeit zur POM-Datei hinzu.
  4. Konfigurieren Sie die Abhängigkeit von Sitemesh (Version 3.0.0) in der POM-Datei. Sitemesh stellt sicher, dass jede Seite unserer Anwendung ein einheitliches Erscheinungsbild aufweist.
  5. Asciidoctorj-Abhängigkeit (Version 1.5.0) zur pom.xml hinzufügen Datei. AsciidoctorJ ist eine Java-API für Asciidoctor und wir verwenden sie, um Asciidoc-Dokumente in HTML umzuwandeln.

Der relevante Teil unserer pom.xml Datei sieht wie folgt aus:

<dependencies>
    <!-- Logging -->
    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-api</artifactId>
    </dependency>
    <dependency>
        <groupId>log4j</groupId>
        <artifactId>log4j</artifactId>
    </dependency>
    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-log4j12</artifactId>
    </dependency>
    <!-- Spring -->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-webmvc</artifactId>
    </dependency>
    <!-- Java EE -->
    <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>javax.servlet-api</artifactId>
        <scope>provided</scope>
    </dependency>
    <!-- Sitemesh -->
    <dependency>
        <groupId>org.sitemesh</groupId>
        <artifactId>sitemesh</artifactId>
        <version>3.0.0</version>
    </dependency>
    <!-- AsciidoctorJ -->
    <dependency>
        <groupId>org.asciidoctor</groupId>
        <artifactId>asciidoctorj</artifactId>
        <version>1.5.0</version>
    </dependency>
</dependencies>

Fahren wir fort und beginnen mit der Implementierung unserer Anwendung.

Rendern von Asciidoc-Dokumenten mit Spring MVC

Wir können die Anforderungen unserer Bewerbung erfüllen, indem wir diesen Schritten folgen:

  1. Konfigurieren Sie unsere Webanwendung und den Sitemesh-Filter.
  2. Implementieren Sie die Ansichtsklassen, die für die Umwandlung von Asciidoc-Dokumenten in HTML und die Wiedergabe des erstellten HTML verantwortlich sind.
  3. Implementieren Sie die Controller-Methoden, die die erstellten Ansichtsklassen verwenden.

Fangen wir an.

Sitemesh konfigurieren

Als erstes müssen wir Sitemesh konfigurieren. Wir können Sitemesh konfigurieren, indem wir diesen drei Schritten folgen:

  1. Konfigurieren Sie den Sitemesh-Filter in der Webanwendungskonfiguration.
  2. Erstellen Sie den Decorator, der verwendet wird, um ein konsistentes Erscheinungsbild für unsere Anwendung zu schaffen.
  3. Konfiguriere den Decorator, der vom Sitemesh-Filter verwendet wird.

Zuerst , müssen wir den Sitemesh-Filter in unserer Webanwendungskonfiguration konfigurieren. Wir können unsere Webanwendung konfigurieren, indem wir diesen Schritten folgen:

  1. Erstellen Sie eine WebAppConfig Klasse, die den WebApplicationInitializer implementiert Schnittstelle.
  2. Implementieren Sie onStartup() Methode des WebApplicationInitializer Schnittstelle, indem Sie diesen Schritten folgen:
    1. Erstellen Sie einen AnnotationConfigWebApplicationContext -Objekt und konfigurieren Sie es so, dass es unsere Anwendungskontext-Konfigurationsklasse verarbeitet.
    2. Konfigurieren Sie das Dispatcher-Servlet.
    3. Konfigurieren Sie den Sitemesh-Filter, um den HTML-Code zu verarbeiten, der von den JSP-Seiten unserer Anwendung und allen Controller-Methoden zurückgegeben wird, die das URL-Muster „/asciidoctor/*“ verwenden
    4. Fügen Sie einen neuen ContextLoaderListener hinzu Objekt zum ServletContext . Ein ContextLoaderListener ist für das Starten und Beenden des WebApplicationContext von Spring verantwortlich .

Der Quellcode der WebAppConfig Klasse sieht wie folgt aus (Sitemesh-Konfiguration ist hervorgehoben):

import org.sitemesh.config.ConfigurableSiteMeshFilter;
import org.springframework.web.WebApplicationInitializer;
import org.springframework.web.context.ContextLoaderListener;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
import org.springframework.web.servlet.DispatcherServlet;

import javax.servlet.DispatcherType;
import javax.servlet.FilterRegistration;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRegistration;
import java.util.EnumSet;

public class WebAppConfig implements WebApplicationInitializer {

    private static final String DISPATCHER_SERVLET_NAME = "dispatcher";

    private static final String SITEMESH3_FILTER_NAME = "sitemesh";
    private static final String[] SITEMESH3_FILTER_URL_PATTERNS = {"*.jsp", "/asciidoctor/*"};

    @Override
    public void onStartup(ServletContext servletContext) throws ServletException {
        AnnotationConfigWebApplicationContext rootContext = new AnnotationConfigWebApplicationContext();
        rootContext.register(WebAppContext.class);

        configureDispatcherServlet(servletContext, rootContext);
        configureSitemesh3Filter(servletContext);

        servletContext.addListener(new ContextLoaderListener(rootContext));
    }

    private void configureDispatcherServlet(ServletContext servletContext, WebApplicationContext rootContext) {
        ServletRegistration.Dynamic dispatcher = servletContext.addServlet(
                DISPATCHER_SERVLET_NAME,
                new DispatcherServlet(rootContext)
        );
        dispatcher.setLoadOnStartup(1);
        dispatcher.addMapping("/");
    }

    private void configureSitemesh3Filter(ServletContext servletContext) {
        FilterRegistration.Dynamic sitemesh = servletContext.addFilter(SITEMESH3_FILTER_NAME, 
                new ConfigurableSiteMeshFilter()
        );
        EnumSet<DispatcherType> dispatcherTypes = EnumSet.of(DispatcherType.REQUEST, 
                DispatcherType.FORWARD
        );
        sitemesh.addMappingForUrlPatterns(dispatcherTypes, true, SITEMESH3_FILTER_URL_PATTERNS);
    }
}

Zweiter , müssen wir den Decorator erstellen, der für unsere Anwendung ein einheitliches Erscheinungsbild bietet. Wir können dies tun, indem wir diesen Schritten folgen:

  1. Erstellen Sie die Decorator-Datei in src/main/webapp/WEB-INF Verzeichnis. Die Decorator-Datei unserer Beispielanwendung heißt layout.jsp .
  2. Fügen Sie den HTML-Code hinzu, der der erstellten Decorator-Datei das konsistente Erscheinungsbild verleiht.
  3. Stellen Sie sicher, dass Sitemesh den aus dem zurückgegebenen HTML-Code gefundenen Titel dem HTML-Code hinzufügt, der vom Webbrowser gerendert wird.
  4. Konfiguriere Sitemesh so, dass die HTML-Elemente, die aus dem Kopf des zurückgegebenen HTML gefunden wurden, dem Kopf des gerenderten HTML hinzugefügt werden.
  5. Stellen Sie sicher, dass Sitemesh den aus dem zurückgegebenen HTML gefundenen Text zu dem HTML hinzufügt, das dem Benutzer angezeigt wird.

Der Quellcode unserer Decorator-Datei (layout.jsp ) sieht wie folgt aus (die Teile, die sich auf Sitemesh beziehen, sind hervorgehoben):

<!doctype html>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title><sitemesh:write property="title"/></title>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <link rel="stylesheet" type="text/css" href="${contextPath}/static/css/bootstrap.css"/>
    <link rel="stylesheet" type="text/css" href="${contextPath}/static/css/bootstrap-theme.css"/>
    <script type="text/javascript" src="${contextPath}/static/js/jquery-2.1.1.js"></script>
    <script type="text/javascript" src="${contextPath}/static/js/bootstrap.js"></script>
    <sitemesh:write property="head"/>
</head>
<body>
<nav class="navbar navbar-inverse" role="navigation">
    <div class="container-fluid">
        <!-- Brand and toggle get grouped for better mobile display -->
        <div class="navbar-header">
            <button type="button" class="navbar-toggle" data-toggle="collapse"
                    data-target="#bs-example-navbar-collapse-1">
                <span class="sr-only">Toggle navigation</span>
                <span class="icon-bar"></span>
                <span class="icon-bar"></span>
                <span class="icon-bar"></span>
            </button>
        </div>
        <div class="collapse navbar-collapse">
            <ul class="nav navbar-nav">
                <li><a href="${contextPath}/">Document list</a></li>
            </ul>
        </div>
    </div>
</nav>
<div class="container-fluid">
    <sitemesh:write property="body"/>
</div>
</body>
</html>

Dritter , müssen wir Sitemesh konfigurieren, um die Decorator-Datei zu verwenden, die wir im zweiten Schritt erstellt haben. Wir können dies tun, indem wir diesen Schritten folgen:

  1. Erstellen Sie eine sitemesh3.xml Datei in die src/main/webapp/WEB-INF Verzeichnis.
  2. Konfiguriere Sitemesh so, dass unser Decorator für alle Anfragen verwendet wird, die vom Sitemesh-Filter verarbeitet werden.

Die sitemesh3.xml Datei sieht wie folgt aus:

<sitemesh>
    <mapping path="/*" decorator="/WEB-INF/layout/layout.jsp"/>
</sitemesh>

Das ist es. Wir haben jetzt Sitemesh konfiguriert, um ein einheitliches Erscheinungsbild für unsere Anwendung bereitzustellen. Lassen Sie uns weitermachen und herausfinden, wie wir die Ansichtsklassen implementieren können, die Asciidoc-Markup in HTML umwandeln und das erstellte HTML rendern.

Implementieren der View-Klassen

Bevor wir mit der Implementierung der Ansichtsklassen beginnen können, die Asciidoc-Markup in HTML umwandeln und das erstellte HTML rendern, müssen wir einen kurzen Blick auf unsere Anforderungen werfen. Die für diesen Schritt relevanten Anforderungen sind:

  • Unsere Lösung muss Asciidoc-Dokumente unterstützen, die im Klassenpfad gefunden werden.
  • Unsere Lösung muss Asciidoc-Markup unterstützen, das als String-Objekt angegeben wird.
  • Unsere Lösung muss die Asciidoc-Dokumente in HTML umwandeln und das erstellte HTML rendern.

Diese Anforderungen legen nahe, dass wir drei Ansichtsklassen erstellen sollten. Diese Ansichtsklassen werden im Folgenden beschrieben:

  • Wir sollten eine abstrakte Basisklasse erstellen, die die Logik enthält, die Asciidoc-Markup in HTML umwandelt und das erstellte HTML darstellt.
  • Wir sollten eine Ansichtsklasse erstellen, die das Asciidoc-Markup aus einer Datei lesen kann, die im Klassenpfad gefunden wird.
  • Wir sollten eine Ansichtsklasse erstellen, die das Asciidoc-Markup aus einem String lesen kann Objekt.

Mit anderen Worten, wir müssen die folgende Klassenstruktur erstellen:

Zuerst , müssen wir die AbstractAsciidoctorHtmlView implementieren Klasse. Diese Klasse ist eine abstrakte Basisklasse, die Asciidoc-Markup in HTML umwandelt und das erstellte HTML rendert. Wir können diese Klasse implementieren, indem wir diesen Schritten folgen:

  1. Erstellen Sie die AbstractAsciidoctorHtmlView Klasse und erweitern Sie die AbstractView Klasse.
  2. Fügen Sie der erstellten Klasse einen Konstruktor hinzu und setzen Sie den Inhaltstyp der Ansicht auf „text/html“.
  3. Fügen Sie eine geschützte abstrakte Methode getAsciidocMarkupReader() hinzu zur erstellten Klasse und setzen Sie ihren Rückgabetyp auf Reader . Die Unterklassen dieser abstrakten Klasse müssen diese Methode implementieren, und die Implementierung dieser Methode muss einen Reader zurückgeben Objekt, das verwendet werden kann, um das gerenderte Asciidoc-Markup zu lesen.
  4. Fügen Sie ein privates getAsciidoctorOptions() hinzu -Methode auf die erstellte Klasse und implementieren Sie sie, indem Sie die Konfigurationsoptionen von Asciidoctor zurückgeben.
  5. Überschreiben Sie das renderMergedOutputModel() Methode der AbstractView Klasse, und implementieren Sie sie, indem Sie das Asciidoc-Dokument in HTML umwandeln und das erstellte HTML rendern.

Der Quellcode der AbstractAsciidoctorHtmlView Klasse sieht wie folgt aus:

import org.asciidoctor.Asciidoctor;
import org.asciidoctor.Options;
import org.springframework.http.MediaType;
import org.springframework.web.servlet.view.AbstractView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.Reader;
import java.io.Writer;
import java.util.Map;

public abstract class AbstractAsciidoctorHtmlView extends AbstractView {

    public AbstractAsciidoctorHtmlView() {
        super.setContentType(MediaType.TEXT_HTML_VALUE);
    }

    protected abstract Reader getAsciidocMarkupReader();

    @Override
    protected void renderMergedOutputModel(Map<String, Object> model,
                                           HttpServletRequest request,
                                           HttpServletResponse response) throws Exception {
        //Set the content type of the response to 'text/html'
        response.setContentType(super.getContentType());

        Asciidoctor asciidoctor = Asciidoctor.Factory.create();
        Options asciidoctorOptions = getAsciidoctorOptions();

        try (
                //Get the reader that reads the rendered Asciidoc document
                //and the writer that writes the HTML markup to the request body
                Reader asciidoctorMarkupReader = getAsciidocMarkupReader();
                Writer responseWriter = response.getWriter();
        ) {
            //Transform Asciidoc markup into HTML and write the created HTML 
            //to the response body
            asciidoctor.render(asciidoctorMarkupReader, responseWriter, asciidoctorOptions);
        }
    }

    private Options getAsciidoctorOptions() {
        Options asciiDoctorOptions = new Options();
        //Ensure that Asciidoctor includes both the header and the footer of the Asciidoc 
        //document when it is transformed into HTML.
        asciiDoctorOptions.setHeaderFooter(true);
        return asciiDoctorOptions;
    }
}

Zweiter , müssen wir die ClasspathFileAsciidoctorHtmlView implementieren Klasse. Diese Klasse kann das Asciidoc-Markup aus einer Datei lesen, die im Klassenpfad gefunden wird. Wir können diese Klasse implementieren, indem wir diesen Schritten folgen:

  1. Erstellen Sie die ClasspathFileAsciidoctorHtmlView Klasse und erweitern Sie die AbstractAsciidoctorHtmlView Klasse.
  2. Fügen Sie einen privaten String hinzu Feld namens asciidocFileLocation zur erstellten Klasse. Dieses Feld enthält den Speicherort der Asciidoc-Datei, die in HTML umgewandelt wird. Dieser Speicherort muss in einem Format angegeben werden, das von getResourceAsStream() verstanden wird Methode der Klasse Klasse.
  3. Erstellen Sie einen Konstruktor, der als Konstruktorargument den Speicherort der gerenderten Asciidoc-Datei annimmt. Implementieren Sie den Konstruktor, indem Sie den Konstruktor der Oberklasse aufrufen und den Speicherort der gerenderten Asciidoc-Datei in asciidocFileLocation speichern Feld.
  4. Überschreiben Sie getAsciidocMarkupReader() -Methode und implementieren Sie sie, indem Sie einen neuen InputStreamReader zurückgeben Objekt, das verwendet wird, um die aus dem Klassenpfad gefundene Asciidoc-Datei zu lesen.

Der Quellcode der ClasspathFileAsciidoctorHtmlView Klasse sieht wie folgt aus:

import java.io.InputStreamReader;
import java.io.Reader;

public class ClasspathFileAsciidoctorHtmlView extends AbstractAsciidoctorHtmlView {

    private final String asciidocFileLocation;

    public ClasspathFileAsciidoctorHtmlView(String asciidocFileLocation) {
        super();
        this.asciidocFileLocation = asciidocFileLocation;
    }

    @Override
    protected Reader getAsciidocMarkupReader() {
        return new InputStreamReader(this.getClass().getResourceAsStream(asciidocFileLocation));
    }
}

Dritter , müssen wir den StringAsciidoctorHtmlView implementieren Klasse, die das Asciidoc-Markup aus einem String-Objekt lesen kann. Wir können diese Klasse implementieren, indem wir diesen Schritten folgen:

  1. Erstellen Sie die StringAsciidoctorHtmlView Klasse und erweitern Sie die AbstractAsciidoctorHtmlView Klasse.
  2. Fügen Sie einen privaten String hinzu Feld namens asciidocMarkup zur erstellten Klasse. Dieses Feld enthält das in HTML umgewandelte Asciidoc-Markup.
  3. Erstellen Sie einen Konstruktor, der das gerenderte Asciidoc-Markup als Konstruktorargument verwendet. Implementieren Sie diesen Konstruktor, indem Sie den Konstruktor der Oberklasse aufrufen und das gerenderte Asciidoc-Markup auf asciidocMarkup setzen Feld.
  4. Überschreiben Sie getAsciidocMarkupReader() -Methode und implementieren Sie sie, indem Sie einen neuen StringReader zurückgeben -Objekt, das verwendet wird, um das im asciidocMarkup gespeicherte Asciidoc-Markup zu lesen Feld.

Der Quellcode des StringAsciidoctorHtmlView sieht wie folgt aus:

import java.io.Reader;
import java.io.StringReader;

public class StringAsciidoctorHtmlView extends AbstractAsciidoctorHtmlView {

    private final String asciidocMarkup;

    public StringAsciidoctorHtmlView(String asciidocMarkup) {
        super();
        this.asciidocMarkup = asciidocMarkup;
    }

    @Override
    protected Reader getAsciidocMarkupReader() {
        return new StringReader(asciidocMarkup);
    }
}

Wir haben nun die erforderlichen Ansichtsklassen erstellt. Lassen Sie uns weitermachen und herausfinden, wie wir diese Klassen in einer Spring MVC-Webanwendung verwenden können.

Verwenden der erstellten Ansichtsklassen

Unser letzter Schritt besteht darin, die Controller-Methoden zu erstellen, die die erstellten Ansichtsklassen verwenden. Wir müssen zwei Controller-Methoden implementieren, die im Folgenden beschrieben werden:

  • Das renderAsciidocDocument() Methode verarbeitet GET Anfragen werden an die URL '/asciidoctor/document' gesendet, und es wandelt ein Asciidoc-Dokument in HTML um und rendert das erstellte HTML.
  • Der renderAsciidocString() Methode verarbeitet GET get-Anforderungen werden an die URL „/asciidoctor/string“ gesendet und transformieren einen Asciidoc String in HTML und rendert das erstellte HTML.

Der Quellcode unserer Controller-Klasse sieht wie folgt aus:

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.ModelAndView;

@Controller
public class AsciidoctorController {

    private static final String ASCIIDOC_FILE_LOCATION = "/asciidoctor/document.adoc";

    private static final String ASCIIDOC_STRING = "= Hello, AsciiDoc (String)!\n" +
            "Doc Writer <[email protected]>\n" +
            "\n" +
            "An introduction to http://asciidoc.org[AsciiDoc].\n" +
            "\n" +
            "== First Section\n" +
            "\n" +
            "* item 1\n" +
            "* item 2\n" +
            "\n" +
            "[source,ruby]\n" +
            "puts \"Hello, World!\"";

    @RequestMapping(value = "/asciidoctor/document", method = RequestMethod.GET)
    public ModelAndView renderAsciidocDocument() {
		//Create the view that transforms an Asciidoc document into HTML and
		//renders the created HTML.
		ClasspathFileAsciidoctorHtmlView docView = new ClasspathFileAsciidoctorHtmlView(ASCIIDOC_FILE_LOCATION);
        return new ModelAndView(docView);
    }

    @RequestMapping(value = "/asciidoctor/string", method = RequestMethod.GET)
    public ModelAndView renderAsciidocString() {
		//Create the view that transforms an Asciidoc String into HTML and
		//renders the created HTML.
		StringAsciidoctorHtmlView stringView = new StringAsciidoctorHtmlView(ASCIIDOC_STRING);
        return new ModelAndView(stringView);
    }
}

Wir haben jetzt die Controller-Methoden erstellt, die unsere Ansichtsklassen verwenden. Wenn der Benutzer unserer Anwendung eine GET-Anfrage an die URL „/asciidoctor/document“ aufruft, sieht der Quellcode der gerenderten HTML-Seite wie folgt aus (die von Asciidoctor erstellten Teile sind hervorgehoben):

<!doctype html>

<html>
<head>
    <title>Hello, AsciiDoc (File)!</title>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <link rel="stylesheet" type="text/css" href="/static/css/bootstrap.css"/>
    <link rel="stylesheet" type="text/css" href="/static/css/bootstrap-theme.css"/>
    <script type="text/javascript" src="/static/js/jquery-2.1.1.js"></script>
    <script type="text/javascript" src="/static/js/bootstrap.js"></script>
    
<meta charset="UTF-8">
<!--[if IE]><meta http-equiv="X-UA-Compatible" content="IE=edge"><![endif]-->
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="generator" content="Asciidoctor 1.5.0">
<meta name="author" content="Doc Writer">

<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Open+Sans:300,300italic,400,400italic,600,600italic|Noto+Serif:400,400italic,700,700italic|Droid+Sans+Mono:400">
<link rel="stylesheet" href="./asciidoctor.css">

</head>
<body>
<nav class="navbar navbar-inverse" role="navigation">
    <div class="container-fluid">
        <!-- Brand and toggle get grouped for better mobile display -->
        <div class="navbar-header">
            <button type="button" class="navbar-toggle" data-toggle="collapse"
                    data-target="#bs-example-navbar-collapse-1">
                <span class="sr-only">Toggle navigation</span>
                <span class="icon-bar"></span>
                <span class="icon-bar"></span>
                <span class="icon-bar"></span>
            </button>
        </div>
        <div class="collapse navbar-collapse">
            <ul class="nav navbar-nav">
                <li><a href="/">Document list</a></li>
            </ul>
        </div>
    </div>
</nav>
<div class="container-fluid">
    
<div id="header">
<h1>Hello, AsciiDoc (File)!</h1>
<div class="details">
<span id="author" class="author">Doc Writer</span><br>
<span id="email" class="email"><a href="mailto:[email protected]">[email protected]</a></span><br>
</div>
</div>
<div id="content">
<div id="preamble">
<div class="sectionbody">
<div class="paragraph">
<p>An introduction to <a href="http://asciidoc.org">AsciiDoc</a>.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_first_section">First Section</h2>
<div class="sectionbody">
<div class="ulist">
<ul>
<li>
<p>item 1</p>
</li>
<li>
<p>item 2</p>
</li>
</ul>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlight"><code class="language-ruby" data-lang="ruby">puts "Hello, World!"</code></pre>
</div>
</div>
</div>
</div>
</div>
<div id="footer">
<div id="footer-text">
Last updated 2014-09-21 14:21:59 EEST
</div>
</div>

</div>
</body>
</html>

Wie wir sehen können, ist der von Asciidoctor erstellte HTML-Code in unser Layout eingebettet, was den Benutzern unserer Anwendung eine konsistente Benutzererfahrung bietet.

Fahren wir fort und bewerten die Vor- und Nachteile dieser Lösung.

Vor- und Nachteile

Die Vorteile unserer Lösung sind:

  • Die gerenderten HTML-Dokumente haben dasselbe Erscheinungsbild wie die anderen Seiten unserer Anwendung. Dies bedeutet, dass wir den Benutzern unserer Anwendung eine konsistente Benutzererfahrung bieten können.
  • Wir können sowohl statische Dateien als auch Strings rendern, die aus einer Datenbank geladen werden können.

Die Nachteile unserer Lösung sind:

  • Die Kriegsdatei unserer einfachen Anwendung ist riesig (51,9 MB). Der Grund dafür ist, dass Asciidoctor zwar eine Java-API hat, aber in Ruby geschrieben ist. Daher benötigt unsere Anwendung zwei große JAR-Dateien:
    • Die Größe der asciidoctorj-1.5.0.jar-Datei beträgt 27,5 MB.
    • Die Größe der jruby-complete-1.7.9.jar-Datei beträgt 21,7 MB.
  • Unsere Anwendung wandelt Asciidoc-Dokumente in HTML um, wenn der Benutzer sie anfordert. Dies wirkt sich negativ auf die Antwortzeit unserer Controller-Methoden aus, denn je größer das Dokument, desto länger dauert die Verarbeitung.
  • Die erste Anfrage, die ein Asciidoc-Dokument als HTML darstellt, ist 4-5 Mal langsamer als die nächsten Anfragen. Ich habe die Anwendung nicht profiliert, aber ich gehe davon aus, dass JRuby etwas damit zu tun hat.
  • Im Moment ist es nicht möglich, diese Technik zu verwenden, wenn wir Asciidoc-Dokumente in PDF-Dokumente umwandeln wollen.

Fahren wir fort und fassen zusammen, was wir aus diesem Blogbeitrag gelernt haben.

Zusammenfassung

Dieser Blogpost hat uns drei Dinge gelehrt:

  • Wir haben gelernt, wie wir Sitemesh konfigurieren können, um ein konsistentes Erscheinungsbild für unsere Anwendung bereitzustellen.
  • Wir haben gelernt, wie wir die Ansichtsklassen erstellen können, die Asciidoc-Dokumente in HTML umwandeln und das erstellte HTML rendern.
  • Obwohl unsere Lösung funktioniert, hat sie viele Nachteile, die sie in realen Anwendungen unbrauchbar machen können.

Der nächste Teil dieses Tutorials beschreibt, wie wir die Leistungsprobleme dieser Lösung lösen können.

P.S. Wenn Sie mit der Beispielanwendung dieses Blogbeitrags herumspielen möchten, können Sie sie von Github herunterladen.


Java-Tag