Konfiguracja deskryptora
W tej części stworzymy pierwszy kontroler, który zwróci prosty widok. Widok będziemy mogli wyświetlić klikając na odpowiedni link w menu systemowym (wtyczka doda odpowiedni link).
Wymagane moduły:
Deklaracja tych modułów odbywa się w deskryptorze wtyczki:
<?xml version="1.0" encoding="UTF-8"?> <plugin key="com.suncode.plugin-tutorial" name="Tutorial Plugin"> <plugin-details> <description> <localized language="en">Description</localized> <localized language="pl">Opis</localized> </description> <author>Suncode</author> </plugin-details> <!-- I18N --> <i18n key="i18n-bundle" location="locale/messages" /> <!-- Web MVC --> <web-mvc key="mvc" /> </plugin>
Stworzenie strony
Kontroler odpowiedzialny jest za przyjęcie żądania HTTP i zwrócenie widoku albo innej odpowiedzi (np. json).
Nasz kontroler będzie wyświetlał widok w odpowiedzi na żądanie /hello oraz odpowiadał obiektem json w odpowiedzi na /api/hello.
package com.suncode.plugin.tutorial; import java.util.Date; import java.util.HashMap; import java.util.Map; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.ResponseBody; @Controller public class HelloController { @RequestMapping( value = "/hello", method = RequestMethod.GET ) public String showHelloView( Model model ) { // dodajemy do modelu atrybut "date" model.addAttribute( "date", new Date() ); // wyświetlamy widok "/views/hello.ftl" return "hello"; } @RequestMapping( value = "/api/hello", method = RequestMethod.GET, produces = "application/json" ) @ResponseBody public Map<String, Object> sayHello() { Map<String, Object> result = new HashMap<String, Object>(); result.put( "say", "hello" ); result.put( "date", new Date() ); // zwracamy mapę, która zostanie przetworzona na obiekt json return result; } }
Widok wyświetli prosty tekst i przesłaną z kontrolera datę:
<p>Hello World</p> <p>Current date: ${date?datetime}</p>
Widoki muszą być wykonane w technologii Freemarker. Wszystkie widoki muszą znajdować się w katalogu /views i mieć rozszerzenie .ftl (katalog i rozszerzenie są automatycznie dodawane do nazwy zwróconego widoku).
Standardowo Eclipse nie posiada wbudowanego edytora szablonów Freemarker. Taki edytor wchodzi w skład jBoss Tools.
Struktura projektu jest następująca:
Po zainstalowaniu/aktualizacji wtyczki możemy wypróbować działanie naszego kontrolera. W tym celu należy wysłać żądanie na odpowiedni adres URL:
Wszystkie adresy URL wtyczki poprzedzone są prefixem składającym się z /plugin/{identyfikator wtyczki}/ (np. /plugin/com.suncode.plugin-tutorial/)
- /plugin/com.suncode.plugin-tutorial/hello
Wszystkie widoki zwracane przez wtyczkę są domyślnie dekorowane (za wyjątkiem żądań z nagłówkiem X-Requested-With: XMLHTTPREQUEST.
Jeżeli nie chcemy dekorować naszej strony, musimy dodać parametr: decorator=none (np: /plugin/com.suncode.plugin-tutorial/hello?decorator=none) dzięki czemu otrzymamy czystą stronę:
Wszystkie dostępne dekoratory opisane są Tworzenie widoków Freemarker - Dekoratory widoków
/plugin/com.suncode.plugin-tutorial/api/hello
json{"say":"hello","date":1399446110308}
Serwowanie statycznych zasobów
Wtyczki mogą serwować dowolne zasoby statyczne (skrypty, zdjęcia etc.). Zasoby takie muszą znajdować się w katalogu /resources:
Zasoby statyczne mogą być pobierane przy użyciu 2 adresów URL (różniących się polityką cache):
- /plugin/{id}/resources/{resource} - zasoby odczytane w ten sposób nie są cache'owane:
- (np. plugin/com.suncode.plugin-tutorial/resources/data.js)
- /plugin/{id}/resources/{lastUpdate}/{resource} - zasoby odczytane w ten sposób są cache'owane(do aktualizacji wtyczki, kiedy zmienia się również link do zasobu):
- (np. plugin/com.suncode.plugin-tutorial/resources/1399542968944/data.js)
gdzie:
- id - identyfikator wtyczki
- resource - adres zasobu wewnątrz wtyczki relatywny do /resources
- lastUpdate - data ostatniej aktualizacji wtyczki
Ze względów wydajnościowych, należy zawsze dążyć do wykorzystywania URL z datą ostatniej aktualizacji, ze względu na politykę cache'owania.
Dynamiczny link do zasobów w widokach Freemarker
Dynamiczny link do zasobów tworzony jest poprzez dodanie do adresu URL daty ostatniej aktualizacji wtyczki. W widokach Freemarker można ułatwić sobie pobieranie gotowego linku:
Wykorzystany niżej obiekt i makro są opisane w dokumentacji tworzenia widoków Freemarker.
<!-- Pomocnicze makro --> <#import "/plugin.ftl" as plugin/> <!-- Wykorzystując obiekt pluginContext --> <script src="${pluginContext.pluginResourcesPath}/data.js"></script> <!-- Wykorzystując pomocnicze makro --> <script src="<@plugin.resourceUrl 'data.js'/>"></script>