Skip to content


E-Mail mit Wicket verschicken

Wäre es nicht praktisch, wenn man eine E-Mail verschicken könnte, in dem man die Komponenten, die man für die Darstellung auf der Webseite verwendet, auch für das Erstellen der E-Mail heranziehen könnte. Das Unterfangen ist leider nicht trivial, weil man nicht ohne Weiteres um die “Magie”, die Wicket an vielen Stellen benutzt, herum kommt. Nun bietet Wicket die Möglichkeit, Komponenten und Seiten, Formulare und vieles mehr in Unit-Test zu testen. Was liegt also näher, als diese Funktionalität für unsere Zwecke zu missbrauchen.

Die E-Mail

Als erstes erstellen wir eine Seite, die den Inhalt der E-Mail erzeugen soll:

 Java(TM) 2 Platform Standard Edition 5.0 |  copy code |? 
01
package de.wicketpraxis.web.blog.pages.questions.email;
02
 
03
import java.util.List;
04
 
05
import org.apache.wicket.markup.html.WebPage;
06
import org.apache.wicket.markup.html.basic.Label;
07
import org.apache.wicket.markup.html.list.ListItem;
08
import org.apache.wicket.markup.html.list.ListView;
09
import org.apache.wicket.model.IModel;
10
 
11
public class EmailContentPage extends WebPage
12
{
13
  public EmailContentPage(IModel<List<? extends String>> list)
14
  {
15
    add(new ListView<String>("list",list)
16
    {
17
      @Override
18
      protected void populateItem(ListItem<String> item)
19
      {
20
        item.add(new Label("name",item.getModel()));
21
      }
22
    });
23
  }
24
}
25

Der Code soll zeigen, dass Komponenten ganz normal Funktionieren. Deshalb bekommt die Seite von außen eine Liste mit Werten übergeben, die dann durch eine ListView dargestellt wird.

 HTML |  copy code |? 
1
<h1>TestEmail</h1>
2
<ul>
3
  <li wicket:id="list"><span wicket:id="name"></span></li>
4
</ul>
5

Im Markup habe ich absichtlich den “Rahmen” der Seite (html > body) weggelassen. Die Klasse und das Markup dienen in diesem Beispiel nur als Platzhalter.

Darstellen und Abschicken

In Wicket sind sehr viele Objekte an den aktuellen Thread gebunden. Das ist notwendig, damit man nicht eine ganze Liste von Objekten als Übergabeparameter durch Methodenaufrufe schleifen muss. Das ist allerdings genau dann ein Problem, wenn wir innerhalb einer Wicketanwendung eine andere Seite darstellen möchten. Außerdem ist es ein Problem, wenn es wie in einem im Hintergrund laufenden Prozess überhaupt keine WicketApplication gibt. Daher erstellen wir uns ein paar Hilfsklassen, die sich um dieses Problem kümmern.

 Java(TM) 2 Platform Standard Edition 5.0 |  copy code |? 
1
package de.wicketpraxis.web.blog.pages.questions.email;
2
 
3
public interface WicketCallback<I,O>
4
{
5
  public O getResult(I input);
6
}
7

 Java(TM) 2 Platform Standard Edition 5.0 |  copy code |? 
01
package de.wicketpraxis.web.blog.pages.questions.email;
02
 
03
import java.util.logging.Logger;
04
 
05
public class WicketThreadAdapter<I,O> extends Thread
06
{
07
  private static final Logger _logger = Logger.getLogger(WicketThreadAdapter.class.getName());
08
 
09
  Object _lock=new Object();
10
 
11
  WicketCallback<I, O> _callback;
12
  I _input;
13
  O _output;
14
  boolean _done=false;
15
 
16
  protected WicketThreadAdapter(WicketCallback<I, O> callback, I input)
17
  {
18
    _callback=callback;
19
    _input=input;
20
  }
21
 
22
  @Override
23
  public void run()
24
  {
25
    synchronized (_lock)
26
    {
27
      _output=_callback.getResult(_input);
28
      _done=true;
29
      _lock.notify();
30
    }
31
  }
32
 
33
  protected O getResult() throws InterruptedException
34
  {
35
    synchronized (_lock)
36
    {
37
      while (!_done)
38
      {
39
        _lock.wait();
40
      }
41
      return _output;
42
    }
43
  }
44
 
45
  public static <I,O> O getResult(WicketCallback<I, O> callback, I input) throws InterruptedException
46
  {
47
    WicketThreadAdapter<I,O> threadAdapter = new WicketThreadAdapter<I,O>(callback,input);
48
    threadAdapter.start();
49
    return threadAdapter.getResult();
50
  }
51
}
52

Die WicketThreadAdapter-Klasse wird über die statische Methode getResult(…) angesprochen und macht folgendes: Es wird ein neuer Thread erzeugt. Im laufenden Thread wird der Callback aufgerufen und der Thread beendet. Das Ergebnis, das im Thread ermittelt wurde, wird als Ergebnis herausgereicht. Kurz: Das Ergebnis wird in einem anderen Thread als dem aktuellen ermittelt und führt so nicht zu Kollisionen mit der laufenden Anwendung.

Der Trick

Das alles führt noch nicht zum Ziel. Wir müssen uns jetzt noch darum kümmern, dass wir die Seite dargestellt bekommen. Dazu benutzten wir die Klasse BaseWicketTester, die sich um alles weitere kümmert. Dort übergeben wir die Seite, die wir darstellen wollen. Dann können wir auf den Inhalt der Seite zugreifen und als Ergebnis zurück liefern.

 Java(TM) 2 Platform Standard Edition 5.0 |  copy code |? 
01
package de.wicketpraxis.web.blog.pages.questions.email;
02
 
03
import java.util.Arrays;
04
import java.util.List;
05
 
06
import org.apache.wicket.markup.html.WebPage;
07
import org.apache.wicket.markup.html.basic.Label;
08
import org.apache.wicket.model.IModel;
09
import org.apache.wicket.model.Model;
10
import org.apache.wicket.util.tester.BaseWicketTester;
11
 
12
public class EmailFromComponentPage extends WebPage
13
{
14
  public EmailFromComponentPage()
15
  {
16
    WicketCallback<List<String>, String> callback = new WicketCallback<List<String>, String>()
17
    {
18
      public String getResult(List<String> input)
19
      {
20
        final IModel<List<? extends String>> listModel = Model.ofList(input);
21
 
22
        BaseWicketTester tester=new BaseWicketTester();
23
        tester.startPage(new EmailContentPage(listModel));
24
        return tester.getServletResponse().getDocument();
25
      }
26
    };
27
 
28
    String result;
29
    try
30
    {
31
      result = WicketThreadAdapter.getResult(callback, Arrays.asList("Klaus","Susi","Bert"));
32
    }
33
    catch (InterruptedException e)
34
    {
35
      e.printStackTrace();
36
      result=e.getLocalizedMessage();
37
    }
38
 
39
    add(new Label("email",result).setEscapeModelStrings(false));
40
  }
41
}
42

Damit das Ergebnis richtig angezeigt wird, teilen wir dem Label “email” mit, dass es den Text nicht umschreiben soll.

 HTML |  copy code |? 
1
<html>
2
  <head>
3
    <title>Email Form Component</title>
4
  </head>
5
  <body>
6
    Email <span wicket:id="email"></span>
7
  </body>
8
</html>

Wenn man die Seite aufruft, erhält man dann folgende Darstellung:

Ergebnis: Html-E-Mail aus Wicket

Ergebnis: Html-E-Mail aus Wicket

Wenn man die E-Mail durch Hintergrundprozesse versenden möchte, ist ein eigener Thread unnötig, weil keine WicketApplication-Klasse an den Thread gebunden ist. Dann sollte der Einsatz der BaseWicketTester-Klasse reichen. Es ist allerdings darauf zu achten, dass alles, was in der eigenen Application-Klasse definiert wurde, an dieser Stelle nicht ohne weiteres zur Verfügung steht (z.B. wird der OpenSessionInViewFilter für Spring nicht aufgerufen, die SpringBean-Annotationen sind ebenfalls funktionslos).

Fazit

Auch wenn sicher noch die eine oder andere Anpassung notwendig ist, damit man Komponenten sowohl für die Anwendung als auch für den E-Mail-Versand benutzten kann, lohnt sich der Aufwand, weil man a) auf die vielfältigen Möglichkeiten, die Wicket als “Template-Engine” bietet, zurückgreifen kann, b) man sich im besten Fall doppelten Code ersparen kann und c) man keine zweite Lösung einbinden muss. Und wieder hat mich Wicket ein wenig überrascht. Weil es dann doch so einfach ging:)

Share and Enjoy:
  • Digg
  • Sphinn
  • del.icio.us
  • Facebook
  • Mixx
  • Google Bookmarks

Andere Beiträge

Posted in Technologie, Wicket.

Tagged with , , , , .


32 Responses

Stay in touch with the conversation, subscribe to the RSS feed for comments on this post.

  1. Tweetback! @elsholz says

    cool, wicket als emailgenerator. http://tinyurl.com/ye9u9uv

  2. Tweetback! @elsholz says

    cool, wicket als emailgenerator. http://tinyurl.com/ye9u9uv

  3. Tweetback! @elsholz says

    cool, wicket als emailgenerator. http://tinyurl.com/ye9u9uv

  4. Tweetback! @elsholz says

    cool, wicket als emailgenerator. http://tinyurl.com/ye9u9uv

  5. Tweetback! @elsholz says

    cool, wicket als emailgenerator. http://tinyurl.com/ye9u9uv

  6. Tweetback! @elsholz says

    cool, wicket als emailgenerator. http://tinyurl.com/ye9u9uv

  7. Tweetback! @elsholz says

    cool, wicket als emailgenerator. http://tinyurl.com/ye9u9uv

  8. Tweetback! @elsholz says

    cool, wicket als emailgenerator. http://tinyurl.com/ye9u9uv

  9. Tweetback! @elsholz says

    cool, wicket als emailgenerator. http://tinyurl.com/ye9u9uv

  10. Tweetback! @elsholz says

    cool, wicket als emailgenerator. http://tinyurl.com/ye9u9uv

  11. Tweetback! @elsholz says

    cool, wicket als emailgenerator. http://tinyurl.com/ye9u9uv

  12. Tweetback! @elsholz says

    cool, wicket als emailgenerator. http://tinyurl.com/ye9u9uv

  13. Tweetback! @elsholz says

    cool, wicket als emailgenerator. http://tinyurl.com/ye9u9uv

  14. Tweetback! @elsholz says

    cool, wicket als emailgenerator. http://tinyurl.com/ye9u9uv

  15. Tweetback! @elsholz says

    cool, wicket als emailgenerator. http://tinyurl.com/ye9u9uv

  16. Tweetback! @elsholz says

    cool, wicket als emailgenerator. http://tinyurl.com/ye9u9uv

  17. Tweetback! @elsholz says

    cool, wicket als emailgenerator. http://tinyurl.com/ye9u9uv

  18. Tweetback! @elsholz says

    cool, wicket als emailgenerator. http://tinyurl.com/ye9u9uv

  19. Tweetback! @elsholz says

    cool, wicket als emailgenerator. http://tinyurl.com/ye9u9uv

  20. Tweetback! @elsholz says

    cool, wicket als emailgenerator. http://tinyurl.com/ye9u9uv

  21. Tweetback! @elsholz says

    cool, wicket als emailgenerator. http://tinyurl.com/ye9u9uv

  22. Tweetback! @elsholz says

    cool, wicket als emailgenerator. http://tinyurl.com/ye9u9uv

  23. Tweetback! @elsholz says

    cool, wicket als emailgenerator. http://tinyurl.com/ye9u9uv

  24. Tweetback! @elsholz says

    cool, wicket als emailgenerator. http://tinyurl.com/ye9u9uv

  25. Tweetback! @elsholz says

    cool, wicket als emailgenerator. http://tinyurl.com/ye9u9uv

  26. Tweetback! @elsholz says

    cool, wicket als emailgenerator. http://tinyurl.com/ye9u9uv

  27. Tweetback! @elsholz says

    cool, wicket als emailgenerator. http://tinyurl.com/ye9u9uv

  28. Tweetback! @elsholz says

    cool, wicket als emailgenerator. http://tinyurl.com/ye9u9uv

  29. Tweetback! @elsholz says

    cool, wicket als emailgenerator. http://tinyurl.com/ye9u9uv

  30. Tweetback! @elsholz says

    cool, wicket als emailgenerator. http://tinyurl.com/ye9u9uv

  31. Tweetback! @elsholz says

    cool, wicket als emailgenerator. http://tinyurl.com/ye9u9uv

  32. Tweetback! @elsholz says

    cool, wicket als emailgenerator. http://tinyurl.com/ye9u9uv



Some HTML is OK

or, reply to this post via trackback.