Komunikacja applet – kontroler Java Spring

Przeglądając sieć zauważyłem, że trochę osób ma problem z komunikacją applet – kontroler Java Spring (model MVC). Trudno znaleźć opis zagadnienia. Postanowiłem więc napisać kilka słów.

Założenie jest takie, aby kontroler odebrał dane, przetworzył i przekazał do widoku lub ewentualnie odpowiedział wysyłając komunikat do appletu. Oczywiście najlepiej byłoby przesyłać całe obiekty (serializacja), aby móc np. potem korzystając z JPA (mapowanie obiektowo-relacyjne) zapisać dane wygodnie do bazy. Dlatego też użyjemy strumieni obiektowych (ObjectOutputStream oraz ObjectInputStream).

Zanim jednak przejdę do rzeczy – kilka słów na temat sposobu osadzania appletu.
Po pierwsze – nabywamy ładnych nawyków, więc używamy znacznika object, nie applet.
Po drugie – jeżeli nasz applet był tworzony z wykorzystaniem dodatkowych bibliotek, np. AbsoluteLayout, należy też je dołączyć. Umieszczamy więc w pliku widoku kod:

<object type="application/x-java-applet" width="800" height="600">
     <param name="classid" value="java:pakiet.Klasa.class" />
     <param name="archive" value="naszApplet.jar, AbsoluteLayout.jar" />
</object>

W ten sposób nasz applet będzie wyświetlany na wybranej stronie. A co z komunikacją?

applet → kontroler

Aby wysyłać dane do kontrolera, w metodzie appletu, która ma to robić, umieszczamy kod:

URL url = new URL("http://adresSeriwsu/odebranieDanych.html");
URLConnection uc = url.openConnection();
uc.setDoInput(true);
uc.setDoOutput(true);
uc.setUseCaches(false);
uc.setDefaultUseCaches(false);
uc.setRequestProperty ("Content-Type", "application/octet-stream");
OutputStream out = uc.getOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(out);
oos.writeObject("chrząszcz brzmi w trzcinie");
oos.flush();
oos.close();

Kolejno – tworzymy połączenie z odpowiednim adresem, przygotowujemy wejście i wyjście oraz upewniamy się, że nie będzie użyta wersja połączenia z pamięci podręcznej. Następnie definiujemy typ zawartości i ustawiamy strumienie. Do celów przykładu przesyłany jest obiekt String czyli ciąg znaków. Metoda kontrolera odbierająca informacje może wyglądać następująco:

@RequestMapping(value = "/odbieranieDanych", method = RequestMethod.POST)
public void savindProcess(HttpServletRequest req, HttpServletResponse res) throws Exception {
     ServletInputStream in = req.getInputStream();
     ObjectInputStream ois = new ObjectInputStream(in);
     String data = (String) ois.readObject();
     System.out.println("oderano: "+data);
}

I w ten oto sposób “chrząszcz brzmi w trzcinie” będzie widoczny z poziomu kontrolera.

kontroler → applet

Załóżmy, że chcemy, aby powyższa metoda zwracała jakieś informacje do appletu. Uzupełniamy ją więc o poniższy kod.

ServletOutputStream out = res.getOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(out);
oos.writeObject("wysyłamy coś do appletu");
oos.flush();
oos.close();

Tu również przesłany jest ciąg znaków. Applet odbierze dane w następujący sposób:

InputStream in = uc.getInputStream();
ObjectInputStream ois = new ObjectInputStream(in);
String data;
try {
     data = (String) ois.readObject();
     System.out.println("applet dostał: "+data);
} catch (ClassNotFoundException ex) {
}

I tak mamy zapewnioną komunikację pomiędzy appletem, a kontrolerem Java Spring. Łatwo zauważyć, że jest ona dość podobna do komunikacji ze zwyczajnymi servletami. Po wykonaniu takiej operacji można spokojnie przetworzyć dane i przekazać do widoku lub zapisać do bazy.