Zum Ende der Metadaten springen
Zum Anfang der Metadaten

Sie zeigen eine alte Version dieser Seite an. Zeigen Sie die aktuelle Version an.

Unterschiede anzeigen Seitenhistorie anzeigen

« Vorherige Version anzeigen Version 3 Nächste Version anzeigen »

In 1 - Einbinden jadice web toolkit haben wir den jadice Viewer eingebunden, aber noch kein Dokument zur Anzeige gebracht. In diesem Tutorial legen wir die Basis zum Laden und zur Anzeige eines Dokuments von einer beliebigen HTTP-URL.

Um ein Dokument laden zu können, muss ein eigener DocumentDataProvider, eine passende Source und ein PageSegmentHandle implementiert werden. Damit JWT diese Implementierungen verwendet, müssen sie in der DocumentDataProviderRegistry registriert werden. Zur Anzeige eines Dokuments auf Client-Seite, muss dieser eine Source über einen Reader anfragen.

Das Ergebnis des Tutorials kann in https://github.com/levigo/jwt-getting-started/tree/master/jwt-tutorial-002 überprüft werden.

Projektstruktur

Folgende Klassen werden wir in diesem Tutorial ergänzen:

Verzeichnisstruktur
└── src/main/java/						
	└── org/jwt/
		├── shared/							- Hier legen wir Klassen ab, die sowohl auf Client, als auch auf Server-Seite benötigt werden.
		│	└── model/	 						
		│		├── UrlSource.java					- Unsere Source-Implementierung.	      
		│		└── UrlHandle.java					- Unsere PageSegmentHandle-Implementierung.	
		└── server/							- Hier legen wir Klassen ab, die nur auf Server-Seite benötigt werden.
			└── dataprovider/
			 	└── UrlDocumentDataProvider.java	- Unsere DocumentDataProvider-Implementierung

Source

Die Source enthält alle Informationen, die zum Auffinden des Dokument-Datenstroms benötigt werden. Das kann z.B. eine Dokument-Id innerhalb eines Archivs oder der Dokumenten-Pfad in einem Dateisystem sein. In unserem Beispiel ist das die HTTP-URL des Dokuments.

org.jwt.shared.model.UrlSource.java
package org.jwt.shared.model;

import org.jwt.server.dataprovider.UrlDocumentDataProvider;
import com.levigo.jadice.document.Document;
import com.levigo.jadice.web.shared.model.Source;

public class UrlSource extends Source {
    private static final long serialVersionUID = 1L;
    private String url;
    
	/** @deprecated NoArgsConstructor for Serialization. */
    public UrlSource() {    }

    public UrlSource(String url) {
        this.setUrl(url);
    }

    public String getUrl() {
        return url;
    }

    public void setUrl(String url) {
        this.url = url;
    }

    @Override
    public String toString() {
        return "UrlSource [url=" + url + "]";
    }
}

PageSegmentHandle

Wurde das Dokument vom DocumentDataProvider erfolgreich geladen, werden bereits geladene Seiten des Dokuments über ein PageSegmentHandle identifiziert. Alle weiteren Client-Anfragen zu einer Dokument-Seite werden automatisch über die PageSegmentHandles durchgeführt.

org.jwt.shared.model.UrlHandle.java
package org.jwt.shared.model;

import com.levigo.jadice.document.PageSegment;
import com.levigo.jadice.web.shared.model.PageSegmentHandle;

public class UrlHandle extends PageSegmentHandle {
    private static final long serialVersionUID = 1L;
    private String url;

    /** @deprecated NoArgsConstructor for Serialization. */
    public UrlHandle() {    }

    public UrlHandle(String url) {
        this.setUrl(url);
    }

    public String getUrl() {
        return url;
    }

    public void setUrl(String url) {
        this.url = url;
    }

    @Override
    public String getIdentifier() {
        return url;
    }

    @Override
    public PageSegmentHandle copy() {
        final UrlHandle h = new UrlHandle(url);
        copyTo(h);
        return h;
    }

    @Override
    public String toString() {
        return "UrlHandle [url=" + url + "]";
    }
}

DocumentDataProvider

Ein DocumentDataProvider ist auf Serverseite für das Laden von Dokumenten verantwortlich. Hier ist also der Einstiegspunkt zum Einbinden des eigenen Dokument-Archivs, Dokument-Dienstes oder einer beliebigen anderen Dokumenten-Ablage. In unserem Beispiel-Projekt laden wir die Resource, die über die von der Source übergebenen URL referenziert wird.

http://webtoolkit.jadice.com/doc/sect.chapter-reference.general.html#sect.reference.docdataprov

org.jwt.server.dataprovider.UrlDocumentDataProvider.java
package org.jwt.server.dataprovider;

import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.net.URLConnection;
import org.jwt.shared.model.UrlHandle;
import org.jwt.shared.model.UrlSource;
import com.levigo.jadice.document.JadiceException;
import com.levigo.jadice.document.read.Reader;
import com.levigo.jadice.web.server.DocumentDataProvider;
import com.levigo.jadice.web.shared.model.PageSegmentHandle;
import com.levigo.jadice.web.shared.model.Source;
import com.levigo.jadice.web.shared.service.exceptions.RecoverFailedException;

public class UrlDocumentDataProvider implements DocumentDataProvider<UrlSource, UrlHandle> {

 	public UrlDocumentDataProvider() {    }

    @Override
    public UrlHandle createSourceHandle(UrlSource source) {
        return new UrlHandle(source.getUrl());
    }

    @Override
    public void read(Reader reader, UrlSource source) throws JadiceException, IOException {
        InputStream documentStream = getResourceStream(source.getUrl());
        reader.read(documentStream);
    }

    @Override
    public void recover(Reader reader, UrlHandle handle) throws RecoverFailedException, JadiceException {
        try {
            InputStream documentStream = getResourceStream(handle.getUrl());
            reader.read(documentStream);
        } catch (IOException e) {
            throw new RecoverFailedException("Can't recover " + handle, e);
        }
    }

    private InputStream getResourceStream(String url) throws IOException {
        URLConnection connection = new URL(url).openConnection();
        return connection.getInputStream();
    }
}

Interessant sind vor allem folgende Methoden:

  • read()
    Dieser Aufruf wird beim initialen Laden des Dokuments durchgeführt. Der Client fordert über eine Source ein Dokument an, und die Implementierung versucht dieses anhand der enthaltenen Informationen zu laden.
  • recover()
    Falls ein bereits geladenes Dokument aufgrund technischer Probleme wiederhergestellt werden muss, passiert das über den revocer-Aufruf. Gut zu erkennen ist, dass hier die PageSegmentHandle als Referenz auf das entsprechende Dokument genutzt wird.

In beiden Fällen laden wir in getResourceStream() den Datenstrom anhand der übergebenen URL. Die Implementierung über URLConnection ist an dieser Stelle absichtlich so einfach gehalten. Eine produktive Implementierung sollte hier sicherlich mehr Wert auf Sicherheitsaspekte und Fehlerbehandlung legen.

DocumentDataProviderRegistry

Die implementierten Klassen müssen nun noch in der DocumentDataProviderRegistry registriert werden. Hierzu gibt es verschiedene Möglichkeiten:

  1. Manuelle Registrierung über DocumentDataProviderRegistry.registerProvider() (Handbuch - DocumentDataProviderRegistry)
  2. Automatische Registrierung:
    1. über den Java ServiceLoader (Handbuch - Automatische Registrierung von DocumentDataProvidern)
    2. über CDI, bei Verwendung des Java-EE-Integrationsmodul (Handbuch - Automatische Registrierung von DocumentDataProvidern per CDI )
    3. über Spring-DI, bei Verwendung von Spring Boot (Handbuch - Spring-Integrationsmodul)

In unserem Beispiel wollen wir den ServiceLoader-Ansatz nutzen, da dies vom integrierten Jetty aus dem Workspace problemlos unterstützt wird. Bei Verwendung anderer Applikationsserver haben die CDI-Varianten aber durchaus Vorteile. Zur Registrierung müssen wir den UrlDocumentDataProvider vollqualifiziert in der Datei src/main/resources/META-INF/services/com.levigo.jadice.web.server.DocumentDataProvider angeben:

resources/META-INF/services/com.levigo.jadice.web.server.DocumentDataProvider
org.jwt.server.dataprovider.UrlDocumentDataProvider


Sollte der Provider nicht aufgelöst werden können, erscheint eine Fehlermeldung in der Art:
java.util.ServiceConfigurationError: com.levigo.jadice.web.server.DocumentDataProvider: Provider org.jwt.server.dataprovider.UrlDocumentDataProvider not found

Sollte sich GWT über nicht gefunde Klassen beschweren, müssen wir sicherstellen, dass

  1. die Anwendung korrekt kompiliert wurde (z.B. Maven > Update Maven Project oder Maven compile).
  2. das Package dieser Klasse als source in der gwt.xml gelistet ist.

Reader

Um im Client tatsächlich ein Dokument zu laden, müssen wir die gewünschte Source an einen Reader übergeben. Über einen AsyncCallback können wir im Erfolgsfall das zurückgelieferte Document zur Anzeige bringen, indem wir es der PageView unseres zuvor erstellten JadiceWidgets übergeben. In unserem Beispiel erweitern wir dazu die Klasse ApplicationEntryPoint:

org.jwt.client.ApplicationEntryPoint.java
(...)

import org.jwt.shared.model.UrlSource;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.levigo.jadice.document.Document;
import com.levigo.jadice.web.client.reader.Reader;

(...)

public class ApplicationEntryPoint implements EntryPoint {

	(...)

	@Override
    public void onModuleLoad() {

		(...)

		// finally load a testdocument
        loadDocument("https://www.levigo.de/fileadmin/download/jadicewebtoolkit.pdf");
 	}

	private void loadDocument(final String url) {
        Reader r = new Reader();
        r.append(new UrlSource(url));
        r.complete(new AsyncCallback<Document>() {
            @Override
            public void onSuccess(Document doc) {
                jadiceWidget.getPageView().setDocument(doc);
            }
            @Override
            public void onFailure(Throwable caught) {
                caught.printStackTrace();
                Window.alert("Cant load document from \"" + url + "\".");
            }
        });
    }
}

Modulkonfiguration (gwt.xml)

Unser UrlSource und PageSegmentHandle haben wir unterhalb des neuen packages org.jwt.shared abgelegt, das der Modulkonfiguration bisher nicht bekannt ist. Damit wir die Klassen auch auf Clientseite nutzen können, müssen wir unsere Modulkonfiguration noch anpassen:

src/main/java/org/jwt/Application.gwt.xml
<source path="shared" />

Zusammenfassung

In diesem Tutorial haben wir erfolgreich ein Dokument über eine HTTP-URL geladen. Wir können innerhalb des Dokument scrollen, weitere Interaktionsmöglichkeiten sind bisher aber nicht möglich.

  • Keine Stichwörter