Einführung in ActiveWeb

Einführung in ActiveWeb

1. Überblick

In diesem Artikel werden wir dieActiveweb veranschaulichen - ein Full-Stack-Webframework von JavaLite - das alles bietet, was für die Entwicklung dynamischer Webanwendungen oder REST-vollständiger Webdienste erforderlich ist.

2. Grundlegende Konzepte und Prinzipien

Activeweb nutzt "Konvention über Konfiguration" - was bedeutet, dass es konfigurierbar ist, aber sinnvolle Standardeinstellungen hat und keine zusätzliche Konfiguration erfordert. Wir müssen nur einige vordefinierte Konventionen befolgen, wie z. B. die Benennung von Klassen, Methoden und Feldern in einem bestimmten vordefinierten Format.

Es vereinfacht auch die Entwicklung, indem die Quelle neu kompiliert und in den laufenden Container geladen wird (standardmäßig Jetty).

Für das Abhängigkeitsmanagement wird Google Guice als DI-Framework verwendet. Um mehr über Guice zu erfahren, werfen Sie einen Blick auf unsereguide here.

3. Maven Setup

Fügen Sie zunächst die erforderlichen Abhängigkeiten hinzu:


    org.javalite
    activeweb
    1.15

Die neueste Version finden Sie unterhere.

Zum Testen der Anwendung benötigen wir außerdem die Abhängigkeit vonactiveweb-testing:


    org.javalite
    activeweb-testing
    1.15
    test

Schauen Sie sich die neueste Versionhere an.

4. Anwendungsstruktur

Wie bereits erwähnt, muss die Anwendungsstruktur einer bestimmten Konvention entsprechen. So sieht das für eine typische MVC-Anwendung aus:

image

Wie wir sehen können, sollten sichcontrollers,service,config undmodels in ihrem eigenen Unterpaket im Paketapp befinden.

Die Ansichten sollten sich im VerzeichnisWEB-INF/viewsbefinden und jeweils ein eigenes Unterverzeichnis haben, das auf dem Controller-Namen basiert. Zum Beispiel sollteapp.controllers.ArticleController einarticle/-Unterverzeichnis haben, das alle Ansichtsdateien für diesen Controller enthält.

Der Bereitstellungsdeskriptor oder dieweb.xml sollten normalerweise<filter> und die entsprechenden<filter-mapping>. enthalten. Da das Framework ein Servlet-Filter ist, gibt es anstelle einer<servlet>-Konfiguration eine Filterkonfiguration:

...

    dispatcher
    org.javalite.activeweb.RequestDispatcher
...

...

Wir benötigen auch<init-param>root_controller, um den Standard-Controller für die Anwendung zu definieren - ähnlich einemhome-Controller:

...

    root_controller
    home

...

5. Controller

Controller sind die Hauptkomponenten einer ActiveWeb-Anwendung. Wie bereits erwähnt, sollten sich alle Controller im Paketapp.controllersbefinden:

public class ArticleController extends AppController {
    // ...
}

Beachten Sie, dass der Controllerorg.javalite.activeweb.AppController. erweitert

5.1. Controller-URL-Zuordnung

Die Controller werden gemäß der Konvention automatisch einer URL zugeordnet. Zum Beispiel werdenArticleController zugeordnet:

http://host:port/contextroot/article

Damit würde ihnen nun standardmäßig eine Standardaktion in der Steuerung zugeordnet. Aktionen sind nichts anderes als Methoden innerhalb des Controllers. Nennen Sie die Standardmethodeindex():

public class ArticleController extends AppController {
    // ...
    public void index() {
        render("articles");
    }
    // ...
}

Bei anderen Methoden oder Aktionen hängen Sie den Methodennamen an die URL an:

public class ArticleController extends AppController {
    // ...

    public void search() {
        render("search");
    }
}

Die URL:

http://host:port/contextroot/article/search

Wir können sogar Controller-Aktionen basierend auf HTTP-Methoden durchführen. Kommentieren Sie die Methode einfach mit einem der@POST, @PUT, @DELETE, @GET, @HEAD.. Wenn wir eine Aktion nicht mit Anmerkungen versehen, wird sie standardmäßig als GET betrachtet.

5.2. Controller-URL-Auflösung

Das Framework generiert die Controller-URL anhand des Controllernamens und des Unterpaketnamens. Zum Beispielapp.controllers.ArticleController.java die URL:

http://host:port/contextroot/article

Befindet sich der Controller in einem Unterpaket, lautet die URL einfach:

http://host:port/contextroot/example/article

Bei einem Controllernamen mit mehr als einem Wort (z. B.app.controllers.PublishedArticleController.java) wird die URL durch einen Unterstrich getrennt:

http://host:port/contextroot/published_article

5.3. Anforderungsparameter abrufen

Innerhalb eines Controllers erhalten wir Zugriff auf die Anforderungsparameter mit den Methodenparam() oderparams() aus den MethodenAppController class.. Die erste Methode verwendet ein String-Argument - den Namen des abzurufenden Parameters:

public void search() {

    String keyword = param("key");
    view("search",articleService.search(keyword));

}

Und wir können die später verwenden, um alle Parameter zu erhalten, wenn wir müssen:

public void search() {

    Map criterion = params();
    // ...
}

6. Ansichten

In der ActiveWeb-Terminologie werden Ansichten häufig als Vorlagen bezeichnet. Dies liegt hauptsächlich daran, dass anstelle von JSPs die Template-Engine von ApacheFreeMarkerverwendet wird. Sie können mehr über FreeMarkerin our guide, here lesen.

Platzieren Sie die Vorlagen im Verzeichnis vonWEB-INF/views. Jeder Controller sollte ein Unterverzeichnis mit allen von ihm benötigten Vorlagen haben.

6.1. Controller View Mapping

Wenn ein Controller getroffen wird, wird die Standardaktionindex() ausgeführt und das Framework wählt die VorlageWEB-INF/views/article/index.ftl aus dem Verzeichnis "Ansichten" für diesen Controller aus. In ähnlicher Weise würde für jede andere Aktion die Ansicht basierend auf dem Aktionsnamen ausgewählt.

Dies ist nicht immer das, was wir möchten. Manchmal möchten wir möglicherweise einige Ansichten zurückgeben, die auf der internen Geschäftslogik basieren. In diesem Szenario stammenwe can control the process with the render() method aus der übergeordneten Klasseorg.javalite.activeweb.AppController:

public void index() {
    render("articles");
}

Beachten Sie, dass sich der Speicherort der benutzerdefinierten Ansichten auch im selben Ansichtsverzeichnis für diesen Controller befinden sollte. Ist dies nicht der Fall, stellen Sie dem Vorlagennamen den Verzeichnisnamen voran, in dem sich die Vorlage befindet, und übergeben Sie ihn an die Methoderender():

render("/common/error");

6.3. Ansichten mit Daten

Um Daten an die Ansichten zu senden, bietetorg.javalite.activeweb.AppController die Methodeview():

view("articles", articleService.getArticles());

Dies erfordert zwei Parameter. Erstens der Objektname, mit dem auf das Objekt in der Vorlage zugegriffen wird, und zweitens ein Objekt, das die Daten enthält.

Wir können auch die Methodeassign()verwenden, um Daten an die Ansichten zu übergeben. Es gibt absolut keinen Unterschied zwischen den Methoden von view () undassign()- wir können eine davon auswählen:

assign("article", articleService.search(keyword));

Ordnen wir die Daten in der Vorlage zu:

<@content for="title">Articles
...
<#list articles as article>
    
        ${article.title}
        ${article.author}
        ${article.words}
        ${article.date}
    

7. Abhängigkeiten verwalten

Um Objekte und Instanzen zu verwalten, verwendet ActiveWeb Google Guice als Framework für die Abhängigkeitsverwaltung.

Nehmen wir an, wir benötigen eine Serviceklasse in unserer Anwendung. Dies würde die Geschäftslogik von den Controllern trennen.

Erstellen wir zunächst eine Serviceschnittstelle:

public interface ArticleService {

    List
getArticles(); Article search(String keyword); }

Und die Umsetzung:

public class ArticleServiceImpl implements ArticleService {

    public List
getArticles() { return fetchArticles(); } public Article search(String keyword) { Article ar = new Article(); ar.set("title", "Article with "+keyword); ar.set("author", "example"); ar.set("words", "1250"); ar.setDate("date", Instant.now()); return ar; } }

Binden wir diesen Dienst nun als Guice-Modul:

public class ArticleServiceModule extends AbstractModule {

    @Override
    protected void configure() {
        bind(ArticleService.class).to(ArticleServiceImpl.class)
          .asEagerSingleton();
    }
}

Registrieren Sie dies schließlich im Anwendungskontext und fügen Sie es nach Bedarf in die Steuerung ein:

public class AppBootstrap extends Bootstrap {

    public void init(AppContext context) {
    }

    public Injector getInjector() {
        return Guice.createInjector(new ArticleServiceModule());
    }
}

Beachten Sie, dass dieser KonfigurationsklassennameAppBootstrap sein muss und sich im Paketapp.config befinden sollte.

Zum Schluss injizieren wir es wie folgt in den Controller:

@Inject
private ArticleService articleService;

8. Testen

Unit-Tests für eine ActiveWeb-Anwendung werden mit der BibliothekJSpecvon JavaLite geschrieben.

Wir verwenden die Klasseorg.javalite.activeweb.ControllerSpecvon JSpec, um unseren Controller zu testen, und benennen die Testklassen nach einer ähnlichen Konvention:

public class ArticleControllerSpec extends ControllerSpec {
    // ...
}

Beachten Sie, dass der Name dem Controller ähnelt, den es testet, und dass am Ende eine „Spezifikation“ steht.

Hier ist der Testfall:

@Test
public void whenReturnedArticlesThenCorrect() {
    request().get("index");
    a(responseContent())
      .shouldContain("Introduction to Mule");
}

Beachten Sie, dass die Methoderequest() den Aufruf des Controllers simuliert und die entsprechende HTTP-Methodeget(), den Aktionsnamen als Argument verwendet.

Wir können Parameter auch mit der Methodeparams() an die Steuerung übergeben:

@Test
public void givenKeywordWhenFoundArticleThenCorrect() {
    request().param("key", "Java").get("search");
    a(responseContent())
      .shouldContain("Article with Java");
}

Mit dieser fließenden API können wir auch Methoden verketten, um mehrere Parameter zu übergeben.

9. Anwendung bereitstellen

Es ist möglich, die Anwendung in einem beliebigen Servlet-Container wie Tomcat, WildFly oder Jetty bereitzustellen. Die einfachste Möglichkeit zum Bereitstellen und Testen ist natürlich die Verwendung des Maven Jetty-Plugins:

...

    org.eclipse.jetty
    jetty-maven-plugin
    9.4.8.v20171121
    
        manual
        10000
    

...

Die neueste Version des Plugins isthere.

Jetzt können wir endlich loslegen:

mvn jetty:run

10. Fazit

In diesem Artikel haben wir die grundlegenden Konzepte und Konventionen des ActiveWeb-Frameworks kennengelernt. Darüber hinaus verfügt das Framework über mehr Funktionen und Fähigkeiten als hier beschrieben.

Bitte beziehen Sie sich auf die offiziellendocumentation für weitere Details.

Und wie immer ist der im Artikel verwendete Beispielcodeover on GitHub verfügbar.