Der Blog handelt ĂŒber ein kleines privates Projekt, passt aber hervorragend zum Firmen-Blog. Die Kernaussage des Blogs: Ich liebe Spring! đ
News lese ich am liebsten ĂŒber meinen Google Reader. Mein Ziel ist es, so viele Informationen wie möglich ĂŒber diesen Kanal zu beziehen. Ich mag diesen Kanal, weil er viele andere KanĂ€le bĂŒndelt und mir die Informationen asynchron anbietet. Das heiĂt, ich kann jederzeit, z.B. beim Warten auf den Bus auf die Informationen zugreifen (âpullâ) ohne jedoch stĂ€ndig von neuen Informationen gestört zu werden (âpushâ). Leider sind nicht alle Informationen ĂŒber RSS verfĂŒgbar. In der Vergangenheit habe ich mich daher des Ăfteren mit frei verfĂŒgbaren RSS-Convertern o.Ă. beschĂ€ftigt. Hier ein paar Beispiele: FreeMyFeed, mmmmail.com oder eine Lösung fĂŒr eine Twitter-zu-RSS-Konvertierung . Keine Lösung konnte mich so richtig ĂŒberzeugen und deckte alle Aspekte ab. Dann dachte ich: Ich bin Programmierer , warum mach ich es nicht einfach selbst?!
Ich hĂ€tte hunderte Ideen, welche Informationen ich gerne in meinem Reader lesen wĂŒrde. Hier zwei Beispiele, die ich zuerst umgesetzt habe:
- Ich bin ein Geocacher und wĂŒrde gerne ĂŒber neue Kletter-Geocaches in der Umgebung informiert werden. Geocaching.com bietet Benachrichtigungen fĂŒr neue Caches in Form von E-Mails an. In diesen E-Mails findet man dann einen Link zum Geocache und dort kann man herausfinden, ob es sich um einen Kletter-Geocache handelt. Diese manuelle Arbeit stört und ich will natĂŒrlich keine E-Mails, sondern EintrĂ€ge in meinem Google Reader.
- Ich wĂŒrde gerne neue Tweets in meinem Google Reader lesen. Twitter ermöglicht nur das abonieren der Tweets eines einzelnen Users per RSS. Dazu muss man sogar authentifiziert sein, da einige Benutzer ihre Tweets schĂŒtzen. Google Reader unterstĂŒtzt leider keine Authentifizierung fĂŒr RSS Feeds. ZusĂ€tzlich möchte ich gerne alle Tweets in einem Feed lesen und ich möchte nach ein paar eigenen Regeln bestimmte Tweets filtern (z.B. Re-Tweets oder âI just became the mayor ofâŠâ-Tweets đ ). Noch dazu wĂŒrde ich gerne verlinkte Bilder sofort im Google Reader sehen können. Ganz unterschiedliche AnforderungenâŠ
Also startete ich ein kleines Projekt. Hier ist das Protokoll einer Woche mit 7 schönen Spring-Abenden đ
- Abend 1 â Veröffentlichen von einigen Beispieldaten ĂŒber RSS
Projekt-Setup mit Maven, initiale Konfiguration von Spring MVC mit einem Controller und einer View basierend auf AbstractAtomFeedView â Ein kleines biĂchen Request-Mapping, das erzeugen von Beispieldaten im Controller und â JA! â nach dem Tomcat-Start und dem Aufruf der URL fragt mein Chrome mich, ob ich den neuen Feed mit dem Google Reader abonieren möchte. NatĂŒrlich â Ohne Sinn, noch handelt es sich ja schlieĂlich um localhost đ1@Override 2protected void buildFeedMetadata(Map<String, Object> model, Feed feed, HttpServletRequest request) { 3⊠4@Override 5protected List<Entry> buildFeedEntries(Map<String, Object> model, HttpServletRequest request, HttpServletResponse response) throws Exception {
- Abend 2 â Entfernen der Beispieldaten und Anzeige von Mails aus meinem Google-Mail Postfach
Der Zugriff auf mein Google-Mail Postfach funktioniert sehr einfach mit dem ImapMailReceiver von Spring Integration . Ich lese dabei nur Mails zu meinem âtoRSSâ-Label aus, welches ich in meinem Google Konto konfiguriert habe. Zusammen mit ein paar einfachen Filter-Regeln ist dies alles was ich benötige.1Message[] messages = mailReceiver.receive();
- Abend 3 â Erzeugen von lesbarem Text aus javax.mail.Message und Auswertung von Nachrichten
Lesbaren Text aus javax.mail.Message zu generieren war fĂŒr mich eher frustrierend (MultiPart, BodyPart, uswâŠ). Gibt es dazu ein gutes Tool oder ein Framework? Denoch konnte ich nach der Konvertierung an der eigentlichen Auswertung meiner Nachrichten ganz nach meinen eigenen Vorgaben arbeiten. Zum Beispiel muss ich jeden Link zu einem Geocache öffnen, um die HTML-Beschreibung zu erhalten und zu ermitteln, ob es sich um einen Kletter-Geocache handelt. Diese Regeln habe ich sehr oft geĂ€ndert. Es ist toll mal sein eigener Product-Owner zu sein! đ - Abend 4 â Persistenz!
Spring Integrationâs ImapMailReseiver liest jede Mail nur einmal aus dem Google-Postfach. Das macht natĂŒrlich Sinn. Ich möchte Daten aus vielen Quellen sammeln und diesen Aspekt von der Bereitstellung der Daten ĂŒber die View trennen. Also mĂŒssen die gesammelten Daten in der Zwischenzeit persistiert werden. Zeit fĂŒr Mongo DB und Spring Data. Super! Wieder eine sehr, sehr einfache Sache. Ich benutze ein einfaches CrudRepository von Spring Data fĂŒr Mongo DB . Setup und Speichern der ersten Werte war in 30 Minuten erledigt. Wieder ein biĂchen Refactoring, einige neue Interfaces, einige Modell-Klassen (RssContent, RssContentProvider) und meine Software konnte Mails lesen, den verarbeiteten Inhalt in einer MongoDB speichern und den Inhalt spĂ€ter ĂŒber einen RSS Feed ausliefern.1public interface RssContentRepository extends CrudRepository<RssContent, String> { 2 List<RssContent> findByUserAndFeed(String user, String feed);
- Abend 5 â Zeitgesteuerter Aufruf der Content-Provider, Twitter
Wie schon in Schritt 4 beschrieben soll das Sammeln der Daten getrennt von deren Anzeige passieren und nicht mit einem neu eintreffenden HTTP-Request ausgelöst werden. Also muss der Aufruf der Daten-Sammler zeitgesteuert erfolgen. Und â natĂŒrlich â auch dies ist mit Spring sehr einfach. Alle ContenProvider in einem neuen SchedulerService âautowirenâ, eine Methode deklarieren, dort alle ContentProvider aufrufen und diese Methode mit Springâs @Scheduled anotieren.1@Scheduled(fixedRate = 1000 * 60 * 60) 2public void executeAll() { 3 for (ContentProvider contentProvider : contentProviderList) { 4 List<RssContent> content = contentProvider.getContent(); 5 contentRepository.save(content); 6 ...
Danach war noch Zeit fĂŒr meinen Twitter-ContentProvider. Dazu benutze ich Spring Social âs Twitter -Api um alle Tweets meiner Timeline zu lesen. Auch hier war es wieder schön, mein eigener Product Owner zu sein und die Tweets beliebig zu filtern und zu bearbeiten.
1List<Tweet> timeline = twitter.timelineOperations().getHomeTimeline(1, 200, lastTweetId, 0);
- Abend 6 â Ersetzen von âlocalhostâ
Leider lĂ€uft der Google Reader nicht auf meinem localhost. Also muss meine Anwendung irgendwo in einen öffentlichen Bereich deployed werden. Na klar, Spring hilft â Cloud Foundry. Da ich von Anfang an die Springsource Toolsuite benutzte, war das Deplyoment in die Cloud genauso leicht, wie ein Deployment in meinen lokalen Tomcat. MongoDB wird als Service innerhalb von CloudFoundry bereitgestellt. Die einzige Ănderung war die Erstellung eines Spring-Profils, welches eine andere mongo-db-factory benutzt. AnschlieĂend habe ich dann noch meinen SchedulerService mit @Profile(âcloudâ) annotiert, damit in meiner lokalen Entwicklungsumgebung keine automatische Datenverarbeitung stattfindet. - Abend 7 â Refactoring
Zu diesem Zeitpunkt lieferte meine Anwendung nur einen einzelnen RSS-Feed. Der richtige Zeitpunkt um einen genaueren Blick auf das Spring MVC-path mapping zu werfen. Die folgenden drei Zeilen und einige zusÀtzliche Informationen aus der Mongo-DB ermöglichen mehrere User und mehrere Feeds. User und Feed werden dabei beim Ablegen in die Mongo-DB vom jeweiligem ContentProvider gesetzt.1@RequestMapping(value = "/user/{user}/feed/{feed}", method = RequestMethod.GET) 2public ModelAndView getFeedContent(@PathVariable String user, @PathVariable String feed) { 3 Iterable<RssContent> content = contentRepository.findByUserAndFeed(user, feed); 4 ...
Fazit: Spring ist genial! Spring hilft einem Entwickler in nahezu allen Bereichen. In meinem Beispiel habe ich Spring Core, Spring MVC, Spring Data, Spring Social, Spring Integration und natĂŒrlich CloudFoundry genutzt. Man findet zu allen Bereichen immer gute Dokumentationen und Beispiele oder man wendet sich an die riesige Community. Alle oben beschriebenen Schritte waren in wenigen Stunden umgesetzt. Man muss nicht jede Technologie bis in die Tiefe verstehen, um mit Spring schnell erste Ergebnisse erzielen zu können. Wenn es im Projekt dann aber zur Sache geht, sollte man als professioneller Entwickler auch die zugrunde liegenden Basistechnologien beherrschen. Das erspart böse Ăberraschungen im Projektverlauf.
Weitere BeitrÀge
von Daniel Reuter
Dein Job bei codecentric?
Jobs
Agile Developer und Consultant (w/d/m)
Alle Standorte
Weitere Artikel in diesem Themenbereich
Entdecke spannende weiterfĂŒhrende Themen und lass dich von der codecentric Welt inspirieren.
Gemeinsam bessere Projekte umsetzen.
Wir helfen deinem Unternehmen.
Du stehst vor einer groĂen IT-Herausforderung? Wir sorgen fĂŒr eine maĂgeschneiderte UnterstĂŒtzung. Informiere dich jetzt.
Hilf uns, noch besser zu werden.
Wir sind immer auf der Suche nach neuen Talenten. Auch fĂŒr dich ist die passende Stelle dabei.
Blog-Autor*in
Daniel Reuter
Du hast noch Fragen zu diesem Thema? Dann sprich mich einfach an.
Du hast noch Fragen zu diesem Thema? Dann sprich mich einfach an.