Archiwum

Archive for the ‘SiteMesh’ Category

Spring Framework 3 + SiteMesh 3 – pierwsze starcie

2 czerwca 2010 17 komentarzy

Po dłuższej przerwie czas wrócić do pisania 🙂 Wprawdzie praca magisterska jeszcze nie skończona ale jest trochę luźniej i czas na jakiś mądry 😉 wpis.

Ostatnio jeden blogerów Darek Zoń zaczął na swoim blogu pisać tutorial o tworzeniu aplikacji w Spring Framework z wykorzystaniem SiteMesh i Hibernate. Zainteresowałem się tematem i podzielę się się wrażeniami z pierwszego starcia z tymi narzędziami.

Swój projekt rozpocząłem w NetBeans 6.9 RC 2 (ma wsparcie dla Spring Framework 3, do projektu są automatycznie dodane biblioteki wersji 3.0.2). Do utworzenia aplikacji konieczne jest pobranie biblioteki SiteMesh (wersja alpha).

Standardowo tworzymy nowy projekt wykonując następujące kroki

  • New project
  • Java Web -> WebApplication
  • serwer może być domyślny (Apache)
  • zaznaczamy Spring Web MVC i w konfiguracji wybieramy wersję 3

W związku z tym że nowy Spring Framework pozwala na tworzenie kontrolerów poprzez adnotację @Controller w pliku konfiguracyjnym trzeba dodać odpowiednie opcje które na to pozwolą.

W pliku dispatcher-servlet.xml należy dodać poniższy kod:

</span></span>
<pre><pre><context:component-scan base-package="eu.ryznar.controller" />
<context:annotation-config />
<context:spring-configured />

Próba umieszczenia takiego projektu na serwerze zwróci wyjątek w postaci (fragment):

org.springframework.beans.factory.xml.XmlBeanDefinitionStoreException: Line 13 in XML document from ServletContext resource [/WEB-INF/dispatcher-servlet.xml] is invalid; nested exception is org.xml.sax.SAXParseException: The prefix "context" for element "context:component-scan" is not bound.
.
.
.
Caused by: org.xml.sax.SAXParseException: The prefix "context" for element "context:component-scan" is not bound.
.
.
.
2010-06-02 12:25:23 org.apache.catalina.core.StandardContext loadOnStartup
SEVERE: Servlet /WebApp1 threw load() exception
org.xml.sax.SAXParseException: The prefix "context" for element "context:component-scan" is not bound.

Aby się tego „pozbyć” w tym samym pliku w sekcji beans należy dodać:

xmlns:context="http://www.springframework.org/schema/context"

Oraz do xsi:schemaLocation dopisać:

http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd

Teraz można dodać kontroler we wskazanej wcześniej paczce:

package eu.ryznar.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;

@Controller
public class IndexController {

    @RequestMapping(value="/index")
    public ModelAndView index() {
        ModelAndView mv = new ModelAndView("hello");

        return mv;
    }
}

oraz utworzyć plik hello.jsp w katalogu /WEB-INF/jsp:

<html>
  <head>
    <title>Hello World</title>
    <meta name='description' content='A simple page'>
  </head>
  <body>
    <p>Hello <strong>world</strong>!</p>
  </body>
</html>

Próba uruchomienia takiej aplikacje rzuca kolejny wyjątek (fragment):

java.lang.NoClassDefFoundError: org/aspectj/lang/NoAspectBoundException
.
.
.
Caused by: java.lang.ClassNotFoundException: org.aspectj.lang.NoAspectBoundException
.
.
.
2010-06-01 22:43:05 org.apache.catalina.core.StandardContext loadOnStartup
SEVERE: Servlet /WebApp1 threw load() exception
java.lang.ClassNotFoundException: org.aspectj.lang.NoAspectBoundException

Brakuje nam biblioteki AspectJ. Należy ją pobrać ze strony http://eclipse.org/aspectj .
Pobrany plik należy wypakować, i do bibliotek tworzonego projektu dodać plik jar: aspectjrt.jar.

Teraz można uruchomić aplikację, i po wpisaniu adresu (port zależny od serwera) http://localhost:8084/WebApp1/index.html strona zostanie wyświetlona poprawnie.

Czas na SiteMesh. Do bibliotek projektu należy dodać pobrane archiwum jar.
Działania SiteMesh nie będę omawiał, pokażę tylko konfigurację. Autor wskazanego bloga użył konfiguracji opartej o klasę Java, mi jednak udało się z samą konfiguracją xml. Tzn. w pliku web.xml dodajemy odpowiednie filtry:

  <filter>
    <filter-name>sitemesh</filter-name>
    <filter-class>org.sitemesh.config.ConfigurableSiteMeshFilter</filter-class>
  </filter>
  <filter-mapping>
    <filter-name>sitemesh</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>

I dodatkowo tworzymy plik sitemesh3.xml (w tej samej ścieżce co web.xml) o następującej zawartości:

<?xml version="1.0" encoding="UTF-8"?>
<sitemesh>
  <mapping path="/*" decorator="/WEB-INF/jsp/decorator.jsp"/>
</sitemesh>

Plik który widnieje w konfiguracji decorator.jsp trzeba stworzyć we wskazanej ścieżce. Odgrywa on rolę szablonu, wg którego budowane są podstrony. Przykładowa zawartość pliku.

<html>
  <head>
    <title>SiteMesh example: <sitemesh:write property='title'/></title>
    <style type='text/css'>
      /* Some CSS */
      body { font-family: arial, sans-serif; background-color: #ffffcc; }
      h1, h2, h3, h4 { text-align: center; background-color: #ccffcc; border-top: 1px solid #66ff66; }
      .mainBody { padding: 10px; border: 1px solid #555555; }
      .disclaimer { text-align: center; border-top: 1px solid #cccccc; margin-top: 40px; color: #666666; font-size: smaller; }
    </style>
    <sitemesh:write property='head'/>
  </head>
  <body>

    <h1 class='title'>SiteMesh example site: <sitemesh:write property='title'/></h1>

    <div class='mainBody'>
      <sitemesh:write property='body'/>
    </div>

    <div class='disclaimer'>Site disclaimer. This is an example.</div>

  </body>
</html>

To wszytko. Można odświeżyć wcześniej uruchomioną stronę i zobaczymy ładnie sformatowaną stronę z „Hello World”.

Jeśli coś źle napisałem będę wdzięczny za uwagi.