REST-Services mit Spring und Maven (Teil 1)

Dieser Teil der Serie über Webprogrammierung mit dem Spring-Framework beschäftigt sich mit Representational State Transfer oder kurz REST. Bei REST handelt es sich um ein Programmierparadigma für Webanwendungen, welches von Roy Fielding in seiner Dissertation im Jahr 2000 geprägt wurde.

Design-Prinzipien bei REST

Wichtiges Element einer REST-Schnittstelle sind Ressourcen. Eine Ressource ist hierbei jedes Element der API, welches sinnvollerweise einzeln angesprochen werden kann.

  • Adressierbarkeit der einzelnen Ressourcen. Die Adressen bleiben idealerweise über Lebensspanne der Resource konstant.
  • Darstellung der abgefragten Ressourcen in verschiedenen Repräsentationen, beispielsweise JSON für Javascript, HTML oder als Grafikdatei zur Anzeige im Browser
  • REST ist Zustandslos.Die Zustandslosigkeit einer REST-Schnittstelle bedingt sich durch das verwendete HTTP(s)-Protokoll. Viele der Vorteile wie das Verwenden von Caches und die Skalierbarkeit ergeben sich aus diese Zustandslosigkeit.
  • REST verwendet die durch HTTP bekannten Operationen wie GET, POST, PUT und weiteren um Manipulationen an den Ressourcen vorzunehmen.

Basisoperationen zur Umsetzung von CRUD sind:

  • POST zum Anlegen (Create) neuer Ressourcen. Die Daten zum Anlegen der Ressource sind hierbei im Body des Requests enthalten, als Antwort erhält man die angelegte Ressource. Diese Funktion hat Seiteneffekte, wiederholtes Ausführen erzeugt neue Ressourcen mit gleichen Eigenschaften.
  • GET zum Abfragen (Read) von Ressourcen. Die Daten werden in der gewählten Repräsentation als Antwortet geliefert. Diese Funktion hat keine Seiteneffekte und kann beliebig wiederholt werden.
  • PUT zum Aktualisieren (Update) von Resourcen. Die aktualisierten Werte befinden sich im Body des Requests und die Antwort zeigt den neuen Zustand der Ressource. Diese Funktion hat Seiteneffekte, wiederholte Ausführung ist möglich.
  • DELETE zum Löschen einer Ressource. Diese Funktion hat Seiteneffekte, wiederholte Ausführung ist nicht möglich.

REST mit Spring

Ausgehend vom ersten Teil der Serie seien nun hier die Unterschiede erläutert.

1) An der Datei spring-servlet.xml ergeben sich folgende Änderungen:

  • InternalResourceViewResolver wird nicht mehr benötigt, da wir keine JSP-Dateien mehr als Views verwenden, sondern MessageConverter für XML und JSON
  • MappingJacksonHttpMessageConverter wird neu eingeführt, um Ergebnisse von Methoden in JSON zu konvertieren. Das benötigt die Abhängkeit  org.codehaus.jackson:jackson-mapper-asl (siehe pom.xml)
  • Jaxb2RootElementHttpMessageConverter ermöglicht die Wandlung von Ergebnistypen in XML. Eine Abhängigkeit wird hier nicht benötigt.
  • AnnotationMethodHandlerAdapter wird durch die Angabe einer Property messageConverters  ergänzt. Dadurch wird die automatische Wandlung in entsprechende Representationen ermöglicht.

Insgesamt ergibt sich folgender neuer Block:

<bean id="jacksonMessageConverter" 
    class="...MappingJacksonHttpMessageConverter" />
<bean id="jaxbMessageConverter" 
    class="...Jaxb2RootElementHttpMessageConverter" />
<bean class="...AnnotationMethodHandlerAdapter">
    <property name="messageConverters">
        <list>
            <ref bean="jacksonMessageConverter"/>
            <ref bean="jaxbMessageConverter"/>
        </list>
    </property>
</bean>

2) In der Datei web.xml wird das url-pattern von *.html auf /rest/* geändert. Dadurch ergeben sich URL der Form http://HOST:PORT/CONTEXT/rest/persons/1, d.h. es wird klar, das es sich um eine REST-API handelt und gleichzeitig entfällt das Postfix .html.

3) Die Klassen PersonCreateDto und PersonDto sind Klassen zum Datentransfer. Die Annotation @XmlRootElement dient dem Übersetzen der Instanzen der Klassen in XML und umgekehrt. Wird als Repräsentationen lediglich JSON benötigt,  so ist diese Annotation unnötig.

4) Die Klasse RestController exponiert die einzelnen Ressourcen und Methoden. Über Annotationen wird das Spring Framework genutzt um einzelne Anfragen auf Methoden der Klassen abzubilden.
Die Annotation @Controller markiert die Klasse als für das Spring Framework.
Die Annotation @RequestMapping legt dabei den letzten Teil der URL und HTTP Methode fest. Wird dabei eine Variable (“persons/{id}”) in die URL eingebaut, so kann diese als Parameter mit der Annotation @PathVariable verwendet werden.
Soll eine Methode im Erfolgsfall nicht den Statuscode 200 liefern, kann dies über die Annotation @ResponseStatus festgelegt werden.
Die Annotationen @RequestBody und @ResponseBody ermöglicht den Transfer von Daten über den jeweiligen Body von Anfrage und Antwort.

5) Die Exception ResourceNotFoundException wird geworfen, wenn eine angefragte Resource nicht existiert.

Beispiel:

@RequestMapping(value = "persons/{id}", method = RequestMethod.DELETE)
@ResponseBody
@ResponseStatus(HttpStatus.GONE)
public boolean deletePerson(@PathVariable(value = "id") int id) {
    PersonDto toDelete = null;
    for (PersonDto person : persons) {
        if (id == person.getId()) {
            toDelete = person;
        }
    }
    if (toDelete != null) {
        return persons.remove(toDelete);
    } else {
        throw new ResourceNotFoundException();
    }
}

Nachdem Start der Anwendung beispielsweise in Tomcat können die Ressourcen unter der Wurzel-URL http://localhost:8080/RestBasics1/rest/ abgerufen werden. Mögliche URLs sind:

  • http://localhost:8080/RestBasics1/rest/persons mit Methoden GET und POST
  • http://localhost:8080/RestBasics1/rest/persons/{id} mit Methoden GET, DELETE und PUT

Diese URLs und Methoden können mit REST Clients wie SoapUI oder RESTClient verwendet werden.

Résumé

In diesem Teil werden noch keine Verknüpfungen zwischen den einzelnen Resourcen in den unterschiedlichen Representationen vorgenommen. Beispielsweise enthält die Resource /persons keine direkten Links auf die einzelnen Personen. Der Nutzer der API muss also den Link zu Jack (/persons/1) anderweitig erfahren.

<Response>
   <e>
      <email>foo@bar.com</email>
      <id>1</id>
      <name>Jack</name>
   </e>
</Response>

Unter dem Stichwort Hypermedia as the Engine of Application State versteht man in diesem Fall die Einbettung von Links direkt in die Resource. Besser wäre für obiges Beispiel also

<Response>
   <e>
      <email>foo@bar.com</email>      
      <name>Jack</name>
      <link xlink:href="../persons/1" />
   </e>
</Response>

Es bleiben also noch einige Sachen zu tun, aber die Basisarbeiten sind getan.

RestBasics1/

OCR-Software gibt es auch per Browser und hilft dabei Texte schnell zu erfassen

Zu erst: OCR steht für Optical Character Recognition und steht für Texterkennung und dient zur Erfassung von Texten aus Bildern.

Sucht man im Netz nach “online ocr” erhält man doch einige Ergebnisse. Stellvertretend habe ich folgende Angebote herausgepickt und getestet:

Ich bevorzuge für meinen Test hier eindeutig Angebote ohne Zwang zur Registrierung, da dies dem schnellen Einsatz für wenig Seiten doch irgendwie entgegen steht. Getestet wurde ebenfalls nur die Ausgabe in reinen Text (ohne Formatierungen etc.).

free-online-ocr.com

free-online-ocr.com bietet ein einfache Webinterface zum Upload der Eingabedatei (entweder Bilder oder PDF). Weiterhin kann das Ausgabeformat gewählt werden (Word, RTF, PDF und reiner Text). Die Seite informiert den Nutzer über einen Fortschrittsbalken über den Verlauf des OCR-Prozesses. Nach Beendigung wird das Ergebnis dem Nutzer zum Download angeboten. Eine Möglichkeit zur Preview existiert nicht.

onlineocr.net

onlineocr.net ermöglicht den Upload der Eingabedatei ebenfalls über ein Webinterface, fragt dabei neben dem Zielformat aber auch die Sprache der Eingabe ab. onlineocr.net unterstützt 32 Sprachen, darunter Englisch, Deutsch und viele weitere europäische Sprachen. Zum Starten der Erkennung muss ein einfaches Zahlen-Captcha eingegeben werden. Nach dem OCR-Prozess wird das Ergebnis in einem Preview angezeigt und kann von dort per Copy&Paste weiter verwendet werden. Der Download ist ebenfalls möglich. Der Dienst ist im Gast-Modus auf 15 Seiten pro Stunde beschränkt.

free-ocr.com

free-ocr.com bietet auch eine Auswahl der Sprache im Dokument, unterstützt jedoch nur die Ausgabe in ein Textfeld auf der Webseite. Zur Absicherung gegen automatisierte Benutzung wird ein Captcha von Recaptcha verwendet, da der Dienst laut Aussage der Webseite zum Brechen von Captchas verwendet wurde.

newocr.com

newocr.com unterstützt 29 Sprachen und bietet als einziger Dienst an, die Eingabedatei im 90° Winkel zu drehen. Es gibt keine Absicherung gegen automatisierte Nutzung durch Captchas.

ocrterminal.com und ocronline.com

Beide Dienste erfordern zunächst eine kostenlose Registrierung. Aus diesem Grund habe ich die Angebote nicht weiter getestet.

Test

Eine objektive Bewertung der Erkennungsrate wollte ich nicht vornehmen, eine subjektive Bewertung soll hier genügen.

Die Testseite entstammt aus einer Dissertation und besteht aus einem Zitat von Victor Hugo (rechtsbündig, kleinerer Font), einer Überschrift (zentriert, Fettdruck, größerer Font), dem Text in Blocksatz und den Fußnoten.

free-online-ocr.com bietet eine gute Erkennungsrate, hat aber teilweise Probleme mit Umlauten. Die Erkennung erstreckt sich auch auf das Zitat und die Fußnoten, was nicht jeder getestete Dienst erreicht.

onlineocr.net bietet eine ordentliche Erkennungsrate, scheitert aber beim Zitat und den Fußnoten.

free-ocr.com scheitert ebenfalls am Zitat und den Fußnoten und hat deutliche Probleme mit Umlauten.

newocr.com erkennt hingegen sowohl Zitat als auch Fußnoten korrekt und bietet subjektiv gesehen die bester Erkennungsrate.

Fazit

Durch die hohe Erkennungsrate und den Erfolg bei Fußnoten und Zitat scheint mir newocr.com der beste kostenlose Anbieter in diesem kleinen Test zu sein.