Category Archives: Spring

Model variables for all views in Thymeleaf 2.1 with Spring MVC

Recently I’ve stumbled upon quite common problem – how to inject a few variables to every Thymeleaf view in application. Of course there is @ModelParam annotation, I could use interceptor or @ControllerAdvice. All solutions are described on StackOverFlow (it is about controllers).

The problem was that I wanted to put Maven build information in that model (to show version and build time in footer). Therefore I did not need application-scope wiring, as build informations are available during Spring’s container startup. So I’ve found another solution dealing with model itself on the lower level – pure XML configuration. There is a special property in ThymeleafViewResolver that can be used – static variables. So code sample can look like this:

<bean id="thymeleafViewResolver" class="org.thymeleaf.spring4.view.ThymeleafViewResolver">
    <property name="templateEngine" ref="templateEngine" />
    <property name="characterEncoding" value="UTF-8" />
    <property name="staticVariables">
            <map>
                <entry key="myModelVariableIWantToSet" value="My model variable value" />
                <!-- All placeholders taken from context:property-placeholder tag can be used as value-->
            </map>
    </property>
</bean>

All defined variables are put into all Model instances that are linked to Thymeleaf views. If You are just serving plain JSON it does not go there – that can be expected behaviour or not! Be aware of that fact.

Advertisements

Spring MVC Revisited

Recently I had an opportunity to play with architecture of a new internal app in my company. In order to properly do my job I’ve reread whole Spring MVC documentation. It was very refreshing ( after a while of using this framework ) to discover several new things. My goal is just to present short list of features with links to docs. There is no point in reinventing the wheel 馃槈

Matrix Params

Ever wanted to provide more data with just URI? Matrix variables are the best way to do this. Just look at the URI presented:

http://localhost:8080/spring_3_2/matrixvars/stocks;BT.A=276.70,,+3.91;AZN=236.00,+103.00;SBRY=375.50/account;name=roger;number=105;location=stoke-on-trent,uk

Yep, you can process it and extract data very easilly. Above URI and nice blog posts about them can be found on Captain’s Debug blog (second part with code snippets here).

ModelAttribute

I am used to using ModelAttribute annotation, mostly on update/save actions in my controllers. What I did not know is that this annotation can be also used with methods. Remember all the situations when You must fill several model variables with data just in order to render them as eg. SELECT-tag values? Now you create just one method in controller and annotate it with @ModelAttribute to put method return value in model. More information can be found in spring docs.

Flash attributes with redirects

I remember problems with simple flash redirects a few years back (circa early Spring’s version 3, flash attributes were introduced in 3.1). Today they are even better handled – You do not need to manually put them into FlashMap. There is a nice class RedirectAttributes which greatly improves coders’ quality of life. Just look at this code:

@RequestMapping(value = "/accounts", method = RequestMethod.POST)
 public String handle(Account account, BindingResult result, RedirectAttributes redirectAttrs) {
   if (result.hasErrors()) {
     return "accounts/new";
   }
   // Save account ...
   redirectAttrs.addAttribute("id", account.getId()).addFlashAttribute("message", "Account created!");
   return "redirect:/accounts/{id}";
 }

Above example comes from RedirectAttributes API, but there is also short Spring doc section and simple tutorial.

BindingResult order

There is nothing new in BindingResult interface. But what cought my attention is the need for this interface be declared as first parameter after @ModelAttribute in controller’s method to work!. I was not aware of that and I assume knowing that can be real time-saver. Short example:

public String addNewBlogger(@ModelAttribute("blogger") Blogger blogger,
            ModelMap map, BindingResult results) 

The above example will not work properly. You will get either exception or application’s logic will behave strangely (depends mostly on error handling and view layer/resolver). Proper solution look like this:

public String addNewBlogger(@ModelAttribute("blogger") Blogger blogger, BindingResult results, ModelMap map) 

Simple creation of URIs

Very often there is a need to create a new URI, eg. to perform redirect. Concatenating string values with parameters is not often clean and simple (not to mention it is very error prone). In order to ease developers’ life Spring provides very dsl-like solution with MvcUriComponentsBuilder class. More can be found in documentation.

Link

Z pewno艣ci膮 znacie ten b贸l, kiedy u偶ywa si臋 jednego z framework贸w czy j臋zyk贸w JVM, kt贸rych kolejne wersje wychodz膮 do艣膰 cz臋sto i dobrze by艂oby od czasu do czasu uaktualni膰 istniej膮ce instalacje. Zazwyczaj ko艅czymy z du偶膮 ilo艣ci膮 poinstalowanych wersji, w r贸偶nych miejscach i nie wiedz膮c do ko艅ca ile tego mamy i gdzie. Je偶eli nie jest to sytuacja Wam obca polecam zapoznanie si臋 z bardzo fajnym narz臋dziem o nazwie GVM, kt贸re jest napisane w czystym bash-u, a do sprawnego dzia艂ania potrzebuje tylko curl-a oraz unzip-a. Narz臋dzie to pozwala w bardzo wygodny spos贸b zarz膮dza膰 wszystkimi zainstalowanymi wersjami najr贸偶niejszych bibliotek – oto lista obecnie wspieranych:

  • Groovy
  • Grails
  • Griffon
  • Gradle
  • Groovyserv
  • Lazybones
  • vert.x
  • Crash
  • Glide
  • Gaiden
  • JBake
  • Springboot

Wi臋cej informacji oraz sposoby u偶ycia mo偶na znale藕膰 na oficjalnej stronie narz臋dzia.

Bo ja chcia艂bym poczyta膰 o Springu

spripr Spring to s艂owo-wytrych w 艣wiecie Javy. Pojawia si臋 w olbrzymiej ilo艣ci projekt贸w, w og艂oszeniach o prac臋, sporo technologii ocenia si臋 por贸wnuj膮c je w艂a艣nie do Springa. Powiedzia艂bym, 偶e czasem boj臋 si臋 otworzy膰 lod贸wk臋…

Z ksi膮偶kami po艣wi臋conymi Springowi w j臋zyku polskim zawsze by艂 problem. Jeden problem. Pojawia艂y si臋 kiedy opisywana przez nie wersja Springa by艂a ju偶 do艣膰 leciwa. Dlatego te偶 rzecz jasna pozostawa艂y materia艂y sieciowe albo wydania angielskoj臋zyczne. Zasadniczo nie bym mia艂 z tym problem, ale mi艂o jest czasem poczyta膰 co艣 w rodzimym j臋zyku. Jaki艣 czas temu trafi艂a w moje r臋ce ksi膮偶ka Spring w praktyce, kt贸ra moim zdaniem, jest bardzo ciekaw膮 pozycj膮.

Przede wszystkim pocz膮tkuj膮cy otrzymuj膮 kilka pierwszych rozdzia艂贸w, kt贸re wyra藕nie przedstawiaj膮 o co chodzi w tym ca艂ym frameworku, a tak偶e dostarczaj膮 gotowych przyk艂ad贸w w jaki spos贸b rozpocz膮膰 prac臋 ze Springiem. Bardziej obeznani z tematem programi艣ci dostaj膮 z kolei kilkana艣cie rozdzia艂贸w przedstawiaj膮cych interesuj膮ce mo偶liwo艣ci wykorzystania Springa – testy integracyjne, integracja za pomoc膮 Spring Data czy obs艂uga u偶ytkownik贸w z pomoc膮 Spring Security. Maj膮c do wyboru reference-docs w witrynie SpringSource, a t臋 zgrabn膮 ksi膮偶k臋, na pocz膮tek zdecydowanie wybra艂bym papier – to dobre miejsce by rozpocz膮膰 bardziej szczeg贸艂owe dociekania.

Link

Ostatnio przegl膮daj膮c zasoby online na stronach Springa natkn膮艂em si臋 na ca艂kiem fajne narz臋dzie. Je艣li potrzebujecie wyprodukowa膰 gotowy projekt to wypr贸bujcie ten generator projekt贸w online. Do wyboru Maven oraz Gradle, z j臋zyk贸w Java lub Groovy i oczywi艣cie ca艂a rodzina produkt贸w ze stajni Springa. Polecam.

Powiew ksi膮偶kowej 艣wie偶o艣ci

W ostatnim czasie po raz kolejny co艣 si臋 ruszy艂o w kwestii wydawniczej w Polsce. Rodzimy Helion w ko艅cu poszed艂 po rozum do g艂owy i zabrali si臋 za wydawanie troszeczk臋 bardziej sensownych pozycji dotycz膮cych interesuj膮cego nas poletka. Mieli ju偶 przeb艂yski wcze艣niej, ale tym razem wygl膮da to jak sta艂y trend. Obecnie wydali (b膮d藕 te偶 planuj膮 wyda膰) kilka ciekawych pozycji.

Mog膮 pojawi膰 si臋 g艂osy, 偶e przecie偶:

  • g艂upot膮 jest czyta膰 ksi膮偶ki papierowe – jak kto woli, ja jestem fetyszyst膮 ksi膮偶kowym i do przesiadki na ebooki jako艣 si臋 nie pal臋
  • czekanie na polskie wydania jest 艣mieszne, technologia staje si臋 stara zanim przet艂umacz膮 – mo偶e tak, mo偶e i nie. Zasadniczo oczywistym jest, 偶e kiedy potrzebujemy wyuczy膰 si臋 na szybko nowej technologii to si臋gamy po oficjaln膮 dokumentacj臋 na sieci. Jednak偶e stoj臋 na stanowisku, 偶e czym innym s膮 tutoriale i dokumentacja, a czym innym ksi膮偶ka. To moje zdanie i b臋d臋 si臋 go trzyma艂.
  • po polsku? Angielskiego nie znasz? – zasadniczo to znam, ca艂kiem nawet zno艣nie. Jednak偶e o ile na co dzie艅 sp臋dzam sporo czasu wertuj膮c 藕r贸d艂a angielskoj臋zyczne, chcia艂bym m贸c dla luzu (np. w poci膮gu) przeczyta膰 co艣 w rodzimym j臋zyku. Ot tak tylko dla odmiany i rozlu藕nienia.

Co tam zatem Helion nam gotuje?

  • Clojure – daleko mi wci膮偶 do programowania funkcyjnego, ale Jacek Laskowski jak zawsze robi ciekawy hype wok贸艂 zagadnienia zatem jest to rzecz warta uwagi. Dla tych, co nie chc膮 czeka膰 mam inn膮 pozycj臋 – J臋zyk programowania Scala
  • Spring in Action – moim zdaniem najfajniejsza ksi膮偶ka o Springu wreszcie doczeka艂a si臋 polskiego wydania. Prawd膮 jest, 偶e dotyczy wersji 3.0, ale wci膮偶 pozostaje 艣wietnym wprowadzeniem do Springa jako takiego. Dla pocz膮tkuj膮cych – bezcenna pozycja.
  • Wydajno艣膰 Javy – tej ksi膮偶ki nie mia艂em w r臋kach w wersji oryginalnej, zaskoczy艂a mnie za艣 poruszana tematyka. Bardzo (moim zdaniem) ciekawe aspekty programowania, na kt贸re my – programi艣ci – mo偶e nie do ko艅ca zwracamy uwag臋. Z ca艂膮 pewno艣ci膮 zapoznam si臋 z ni膮 bli偶ej za艣 wra偶eniami podziel臋 si臋 na blogu.

Kilka sztuczek w Struts 1

W nowej pracy mam okazj臋 na co dzie艅 pracowa膰 z frameworkiem Struts. W moich dotychczasowych projektach nie mia艂em do tej pory okazji zapozna膰 si臋 z tym frameworkiem, jednak偶e p0 kilku tygodniach pisania w nim kodu mam o nim jakie艣 tam poj臋cie. Napotka艂em po drodze kilka do艣膰 frustruj膮cych “wpadek” i dlatego postanowi艂em je opisa膰 na blogu.

1. Tagi z dynamicznymi warto艣ciami.

Podstaw膮 internetu jest magiczny znacznik HTMLa o nazwie FORM. Zasadniczo do艣膰 cz臋sto zdarza si臋, i偶 adres akcji, kt贸ra zostanie wywo艂ana jest zale偶ny od przekazanego parametru. W聽Strustach zaleca si臋 do takich operacji u偶ywanie tagu聽<bean:write> – w sumie mo偶na si臋 z tym nawet zgodzi膰, problemem jest to, i偶 nie da si臋 umie艣ci膰 tego tagu wewn膮trz tre艣ci innego tagu. Czyli takie co艣 nie przejdzie:

<html:form action="<bean:write [...] />"  ></html:form>

Wpisanie czego艣 takiego do tre艣ci strony JSP spowoduje wyrzucenie wyj膮tku. O dziwo u偶ycie sk艂adni skrypletowej ze znacznikami r贸wnie偶 nie zadzia艂a;

<html:form action="<%=(String)request.getAtrtribute("cost")%>"  ></html:form>

Problem ten mo偶na obej艣膰 sposobem “niejavowym”. A mianowicie tak:

<html:form action='<%=(String)request.getAtrtribute("cost")%>'  ></html:form>

Wida膰 r贸偶nic臋? Zamieniamy po prostu cudzys艂贸w na apostrof. I nagle dziwnym trafem wszystko dzia艂a.

2. Checkboxy w checkboxie czyli o tagu html:multibox

Za艂贸偶my tak膮 sytuacj臋. Piszemy aplikacj臋 do rezerwacji pokoi w hotelu. Jako u偶ytkownik wybieramy sobie kilka opcji spo艣r贸d dost臋pnych w hotelu ( np. sejf w pokoju, wypo偶yczenie auta). I te informacje przechowujemy dla ka偶dej rezerwacji. Z drugiej strony mamy rzecz jasna r贸wnie偶 wszystkie mo偶liwe opcje – ich lista mo偶e by膰 d艂uga. I teraz – jak przy edycji/podgl膮dzie formularza szybko i 艂atwo zaznaczy膰 na li艣cie te, kt贸re u偶ytkownik wybra艂 dla swojej rezerwacji?

Rzecz jasna mo偶emy przeiterowa膰 po ca艂ej kolekcji ze wszystkimi opcjami i nast臋pnie iteracyjnie przechodzi膰 po opcjach, kt贸re wybra艂 u偶ytkownik. Je艣li obecnie przetwarzana warto艣膰 znajduje si臋 po艣r贸d tych, kt贸re wybra艂 u偶ytkownik renderujemy atrybut checked. Jednak偶e jest to troszeczk臋 nieefektywne i dlatego te偶 tw贸rcy Strutsa wymy艣lili tag o nazwie html:multibox. W skr贸cie – iterujemy po li艣cie wszystkich mo偶liwych opcji, ale zamiast por贸wnywa膰 cokolwiek (skrypletami cho膰by) wstawiamy do tej p臋tli ww. znacznik i powinno by膰 dobrze. Dlaczego o tym pisz臋? Ano rzu膰my okiem na dokumentacj臋 tagu:

Renders an HTML <input> element of type checkbox, whose “checked” status is initialized based on whether the specified value matches one of the elements of the underlying property’s array of current values.

Co pomy艣li sobie programista? 艢wietnie – iterujemy po li艣cie obiekt贸w i potem do tagu wrzucamy drug膮 list臋 tego samego typu obiekt贸w i jest OK. Czyli wystarczy dokona膰 troch臋 magii z przes艂oni臋ciem metod equals oraz hashCode i jeste艣my w domu. No i nie do ko艅ca…

Okazuje si臋 (po 3h mojego rzucania mi臋sem przed komputerem), i偶 w tym przypadku jednym rozwi膮zaniem jest to, 偶e obydwie kolekcje b臋d膮 zawiera艂y obiekty typu String!. Zapomnijcie o dobrach tego taga w przypadku w艂asnych klas. Ostatecznie mo偶e wygl膮da膰 to tak:

<logic:iterate id="lancuch" name="BeanFormularza" property="listaLancuchow" >

         <html:multibox property="listaLancuchowDoZaznaczenia">
             <bean:write name="lancuch" />
        </html:multibox>

</logic:iterate>

3. Sprawdzanie parametr贸w 偶膮dania

Generalnie sprawa jest prosta. W akcji zapisujemy zmienn膮 w obiekcie 偶膮dania i chcemy dobra膰 si臋 do niej w widoku. Robimy tak:

request.setAttribute( "klucz", wartoscPodTymKluczem );

Wiadomo jednak偶e, i偶 czasami wartoscPodTymKluczem mo偶e przyj膮膰 warto艣膰 NULL, albo co gorsza w og贸le nie zosta膰 ustawiona (co mo偶e, cho膰 nie do ko艅ca, znaczy膰 to samo co NULL). Dobr膮 praktyk膮 by艂oby tym samym sprawdzenie w widoku, czy aby interesuj膮ca nas zmienna nie jest w艂a艣nie NULLem. I tutaj ma艂a niespodzianka w przypadku tagu logic:present. Tag ten sprawdza, czy podana zmienna istnieje. Jednak偶e nale偶y uwa偶a膰, gdy偶 dokumentacja mo偶e by膰 myl膮ca – przyzwyczajeni bowiem jeste艣my do tego, i偶 atrybuty name oraz property oznaczaj膮 to samo w ka偶dym tagu – name zawiera nazw臋 beana, za艣 property to konkretna w艂asno艣膰 obiektu (cho膰 nie do ko艅ca, tak naprawd臋 liczy si臋 istnienie metody dost臋powej). Natomiast w przypadku atrybut贸w 偶膮dania jest odwrotnie! By powy偶szy przyk艂ad zadzia艂a艂 z ww. tagiem musi to wygl膮da膰 nast臋puj膮co:

<logic:present name="klucz" >
  tutaj jest miejsce na nasz kod i wszystko inne je艣li warto艣膰 istnieje i nie jest pusta
</logic:present>

Zapominamy o property. Tak to ma wygl膮da膰.

4. Podsumowanie
Duperelki, ale ile偶 potrafi膮 napsu膰 zdrowia i dobrego samopoczucia. Rzecz jasna wszystko dotyczy frameworka Struts w wersji 1. Jak wygl膮da ten temat obecnie nie wiem i raczej niezbyt pr臋dko b臋d臋 mia艂 okazj臋 pozna膰 drug膮 ods艂on臋 tego frameworka. Jednak偶e komentarze na ten temat jak najmilej widziane.