Professional Documents
Culture Documents
Il framework Spring
E' un framework molto articolato. www.spring.io.
- Spring boot: ci sono gi molte cose preconfigurate che permetto-
no di costruire applicazioni articolate senza nemmeno avere Tom-
cat (usa una versione embedded).
- SPRING FRAMEWORK: parte con due idee fondamentali. La pri-
Tutorial:
ma la dependency injection (= creo e configuro programmi in mo- www.duckranger.com/2011/07/spring-mvc-3-0-with-sts-tutorial-part-i/
do dichiarativo). La seconda la possibilit di aggiungere compor-
tamenti cross-cutting.
- Spring XD: supporto per le operazioni che richiedono la manipola-
C. Barberis, G. Malnati, 2011-14
Applicazioni Internet 3
propria elaborazione
Approccio contrario alla normale creazione di
applicazioni
Lapproccio tradizionale infatti prevede che il punto di
ingresso del programma crei tutte le dipendenze e
che successivamente avvenga lelaborazione
Applicazioni Internet 4
Perch l'accoppiamento delle classi sia "debole", una classe non
Dependency injection deve contenere dentro di s riferimenti ad altre classi applicative
(quelle che descrivono il dominio nel quale io lavoro). Se una clas-
se ha bisogno di usarne un'altra, lo fa in quanto implementazione di
Per garantire un accoppiamento debole, ciascun un'interfaccia.
oggetto dovrebbe conoscere le proprie dipendenze
soltanto in termini di interfaccia Qui ad esempio abbiamo un cavaliere coraggioso. Non sa di preci-
In modo da legare la classe allinterfaccia piuttosto che so quale impresa vuole compiere.
allimplementazione
C. Barberis, G. Malnati, 2011-14
In questo caso un bean una qualunque classe Java, con dei meto-
Spring permette di creare le associazioni fra i
di setter e getter. Ogni bean ha un nome e fa riferimento a una clas-
diversi oggetti dellapplicazione tramite un file se. All'interno del tag bean posso mettere delle informazioni: nell'
xml esempio quando qualcuno chiede knight, l'XML si accorge che ser-
<?xml version="1.0" encoding="UTF-8"?> ve anche un quest da passare al costruttore.
<beans
C. Barberis, G. Malnati, 2011-14
xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/
beans http://www.springframework.org/schema/beans/spring-
beans-3.0.xsd">
Applicazioni Internet 9
Applicazioni Internet 11
Ciclo di vita di un bean Una volta che l'oggetto creato, il contenitore si chiede: "Ma questo
oggetto implementa una delle interfacce che io conosco?". Se ad
esempio un oggetto implementa BeanNameAware gli dico che sar
Il contenitore carica le definizioni dei bean noto al codice applicativo con un nome ben specifico.
Quando gli viene chiesto un bean specifico lo istanzia
Il bean viene popolato con le propriet dichiarate nelle definizioni
Se una propriet ha un riferimento ad un altro bean, questo viene creato e
inizializzato prima di creare il bean che lo referenzia
Se il bean implementa determinate interfacce, vengono chiamati i
metodi appropriati
C. Barberis, G. Malnati, 2011-14
Applicazioni Internet 12
Ciclo di vita di un bean Questo tutto il giro completo.
1) Recupero dall'XML il nome della classe e creo un'istanza
2) Popolo le propriet (nell'esempio del cavaliere, quest)
3) "Caro oggetto, sappi che tu ti chiami..."
4) "Guarda che tu sei appena stato creato da me..."
5) "Chi l'ApplicationContext che l'ha fatto"
...
C. Barberis, G. Malnati, 2011-14
Applicazioni Internet 13
Configurazione di Spring Dovendo lavorare con Spring dobbiamo preparare un file XML in
cui indichiamo una serie di bean. Per ciascuno di essi abbiamo un
identificatore e la relativa classe. All'interno di un bean posso mette-
La configurazione di Spring viene inserita in uno re tutte le dipendenze.
o pi file XML
Contiene le dichiarazioni dei bean
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
C. Barberis, G. Malnati, 2011-14
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation=
"http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd"
>
<bean id="..." class="...">
<! qui si inseriscono i collaboratori
e la configurazione di questo bean -->
</bean>
<! altri bean -->
</beans>
Applicazioni Internet 14
Configurazione di Spring
Applicazioni Internet 15
Configurazione tramite XML Siccome brutto creare un file con 5000 righe, fai tanti XML separa-
ti, suddivisi in base alle funzionalit (es.: Business.xml, Login.xml,
ClasseDAO.xml).
possibile suddividere le definizioni dei bean
allinterno di pi file Si possono creare bean anonimi solo quando vogliamo che ci siano
Suddividendoli, ad esempio, per funzionalit (business propriet collegate 1:1 con qualcun altro. Non sono accessibili se
bean, dao, utility beans, ) non nel contesto in cui sono inseriti.
C. Barberis, G. Malnati, 2011-14
Applicazioni Internet 16
Le dipendenze sono specificate nel momento in cui il codice viene
Injection tramite costruttore costruito.
I pezzi che servono al costruttore sono dichiarati in ordine!
I parametri che devono essere passati al Il vantaggio che se il bean viene costruito allora ha tutte le parti di
costruttore vengono specificati nel file di cui ha bisogno. Altrimenti c' una qualche eccezione (perch maga-
configurazione ri Sonnet29 non un poem).
Tramite il tag <constructor-arg>
public class PoeticJuggler extends Juggler {
C. Barberis, G. Malnati, 2011-14
li.
<bean name="fileReader" class="FileReader"
init-method="init" destroy-method=cleanUp>
In alternativa, si possono implementare le Dopo che tutte le restanti dipendenze mi sono state iniettate, vai a
interfacce fornite da Spring registrarti con JMX. Quando sei stato distrutto, cancellati.
InitializingBean con il metodo afterPropertiesSet()
permette linizializzazione
DisposableBean con il metodo destroy() per il rilascio
C. Barberis, G. Malnati, 2011-14
di risorse
public class Connection implements InitializingBean, DisposableBean
{
private ObjectName objectName;
//InitializingBean's method implementation
public void afterPropertiesSet(){
connection.registerToJmx(objectName);
}
//DisposableBean's method implementation
public void destroy(){
connection.unregisterFromJmx(objectName);
}
} Appl
Applicazioni Internet 21
Questo si presta sia a iniettare oggetti con nome (fai riferimento all'
Iniettare inner bean unico sassofono del mio progetto) o posso far s che kenny suoni
il proprio sassofono, che non ha nulla a che fare con quello degli
altri. L'inner bean costruito quando costruisco kenny: quando
Gli inner bean sono bean definiti nello scope di qualcuno fa la get di un sassofono ottiene come istanza quella dell'
altri bean ultima riga, su kenny invece c' un'istanza differente
Non necessitano di un attributo id perch non verr Gli inner bean non hanno un campo ID perch altrimenti sarebbero
mai fatto riferimento ad essi tramite il loro accessibili per nome. Cos invece sono accessibili solo nel contesto
identificativo dell'enclosing bean.
C. Barberis, G. Malnati, 2011-14
}
}
Iniettare mappe
public
public
class
class
OneManBand
JMSSource{
implements Performer {
private
private
Map<String,
Map sourceProps
Instrument>
= null;
instruments;
public
public
OneManBand()
void setProperties(Map
{ } props){
public void
sourceProps
setInstruments(Map<String,
= props; Instrument> inst){
} this.instruments = inst;
C. Barberis, G. Malnati, 2011-14
}}
}
Iniettare propriet
private Properties instruments;
public void setInstruments(Properties instruments) {
this.instruments = instruments;
}
C. Barberis, G. Malnati, 2011-14
Applicazioni Internet 26
Per nome - autodetect (prima provo per costruttore, poi per tipo)
Per tipo
Per costruttore
Autodetect
Il framework tenta di utilizzare prima lautowire per costruttore,
poi quello per tipo
Applicazioni Internet 27
Il contenitore cerca, per ogni propriet, il bean il kenny ha bisogno di una canzone e di uno strumento. La canzone
cui nome nel file di configurazione coincide con data in modo esplicito, dello strumento non diciamo nulla sapendo
il nome della propriet che lui al suo interno ha una propriet instrument. Spring capisce
Se vengono trovate le corrispondenze, i bean relativi e dice: "ok, lo strumento l'unico che c' qui dentro".
vengono iniettati, altrimenti viene generata
C. Barberis, G. Malnati, 2011-14
uneccezione Se pi oggetti hanno una propriet con lo stesso nome tutti ricevono
Se pi bean hanno una propriet con lo stesso nome, lo stesso elemento
verr iniettato sempre lo stesso oggetto
<bean id="kenny"
class="Instrumentalist"
autowire="byName">
<property name="song" value="Jingle Bells" />
</bean>
<bean id="instrument" class="Saxophone" />
Applicazioni Internet 28
Ci che succede che io vado a cercare un bean il cui nome coinci-
Autowire per tipo de col nome del tipo della propriet. Eventualmente posso aggiun-
gere indicazioni.
Il contenitore cerca, per ogni propriet, un bean kenny sceglie l'autowire by type. Ho dichiarato tre strumenti: il sas-
il cui tipo coincide con il tipo della propriet sofono, il tamburo e un altro sassofono (con un nome diverso). Sic-
Se viene trovata una sola corrispondenza, i bean come Instrumentalist ha bisogno di uno strumento vedo chi imple-
relativi vengono iniettati menta l'interfaccia Instrument.
Altrimenti viene generata uneccezione
C. Barberis, G. Malnati, 2011-14
Per evitare le ambiguit, si pu segnalare che Il primo pu starci. Il secondo ha scritto primary=false. Se non ci fos-
Un dato bean non un candidato primario per se nessun altro prenderei lui. Il terzo ha scritto autowire-candidate=
liniezione, con il lattributo primary=false false e quindi non viene nemmeno considerato.
Un bean non pu essere utilizzato per lautowiring
<bean id="kenny" class="Instrumentalist" autowire="byType">
<property name="song" value="Jingle Bells" />
</bean>
<bean id="instrument" class="Saxophone" />
<bean id="drum" class="Drum" primary=false" />
<beanApplicazioni
id="saxophone"
Internet class="Saxophone" autowire-candidate="false" /> 29
Se pi bean soddisfano gli argomenti del costruttore, di tipo DataSource, che verr automaticamente selezionato e passa-
viene generata uneccezione to al costruttore.
public class TradePersistor {
public TradePersistor (DataSource datasource){ ..}
}
Applicazioni Internet 30
Applicazioni Internet 31
Lo strato CoreContainer
I moduli "core" e "bean" costituiscono
l'infrastruttura base del framework
Offrono i meccanismi di inserimento delle diepndenze e
dell'inversione del controllo e l'accesso ai bean tramite
BeanFactory
Il modulo "expression language" offre l'accesso ad
C. Barberis, G. Malnati, 2011-14
Applicazioni Internet 32
All'interno dello strato web ci sono alcune cose fondamentali:
Lo strato web - gestione di cose di uso frequente (ServletListener, upload multi-
part...)
- servlet (contiene l'implementazione del paradigma MVC)
Il modulo "web" offre funzionalit generali nel contesto
di applicazioni web
Supporta l'invio di file tramite il meccanismo "multipart file-
upload", l'inizializzazione di un un contesto web utilizzando un
servlet listener, il supporto alla remotizzazione di oggetti tramite
http
Il modulo "servlet" contiene l'implementazione di spring
C. Barberis, G. Malnati, 2011-14
Applicazioni Internet 33
La cosa base che occorre notare che per poter utilizzare spring
Configurazione di un progetto sufficiente includere le tre dipendenze qui riportate.
jstl
Applicazioni Internet 34
LURL di destinazione
Eventuali parametri aggiuntivi, come quelli inseriti in una form
oggetto di tipo ViewModel che contiene una stringa che ci dice
quale sar la view da far vedere, nonch un insieme di coppie chia-
vi, valori utilizzabili nella vista. Tornare solo la stringa d una sod-
Req
Request
1
Dispatcher disfazione limitata: per questo motivo i metodi dei controllori pos-
servlet
sono ad esempio avere come parametro un oggetto che implemen-
ta l'interfaccia Model (vedi al fondo) in modo da attingere a informa-
zioni precedenti o predisporre informazioni successive, utilizzate
Applicazioni Internet
pi avanti dalle viste.
35
La vista viene poi scelta dal ViewResolver, che nel modo pi sempli-
ce pu appendere .jsp e prependere WEB-INF.
Costruire applicazioni web con
Spring
2. Il DispatcherServlet deve consegnare la
richiesta ad un controllore
Vengono consultati uno o pi gestori dei mapping per
capire qual il controllore adeguato
C. Barberis, G. Malnati, 2011-14
Handler
2 mapping
Request
Req Dispatcher
1
servlet
Applicazioni Internet 36
Costruire applicazioni web con
Spring
3. Il DispatcherServlet consegna la richiesta al
controllore
Il controllore analizza, elabora e rimuove i parametri
della richiesta
C. Barberis, G. Malnati, 2011-14
Handler
2 mapping
3
Request
Req Dispatcher
1 Controller
servlet
Applicazioni Internet 37
Handler
2 mapping
3
Request
Req Dispatcher
1 Controller
servlet Model and logical
view name 4
Applicazioni Internet 38
Handler
2 mapping
3
Request
Req Dispatcher
1 Controller
servlet Model and logical
view name 4
ViewResolver
Applicazioni Internet 39
Handler
2 mapping
3
Request
Req Dispatcher
1 Controller
servlet Model and logical
view name 4
6 5
View ViewResolver
Applicazioni Internet
erne 40
Possono avvenire un mucchio di cose: la richiesta arriva in alto al
Il quadro complessivo container che stiamo usando (Tomcat) nel quale configurata una
web application con determinati filtri. Dopo aver attraversato i filtri
si arriva al DispatcherServlet utilizzato per intercettare le richieste.
Il DispatcherServlet:
- capisce se nella richiesta indicato un locale
- capisce stato configurato un tema per la nostra applicazione
- capisce se c' bisogno di salvare il contenuto di una POST
Fatte queste operazioni preliminari, si chiede a chi passare le cose:
C. Barberis, G. Malnati, 2011-14
web.xml
<servlet>
<servlet-name>shop</servlet-name>
<servlet-class>
org.springframework.web.servlet.DispatcherServlet
</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
Applicazioni Internet 42
DispatcherServlet
Il tag <url-pattern> indica quali URL sono gestite
dal DispatcherServlet
/ indica che la servlet gestisce tutte le richieste, comprese
quelle per i contenuti statici
<servlet-mapping>
C. Barberis, G. Malnati, 2011-14
<servlet-name>shop</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
Controllore
Applicazioni Internet 44
Handler Mapping
Spring fornisce diverse implementazione dellhandler
mapping
BeanNameUrlHandlerMapping
mappa le URL su bean il cui nome inizia con "/"
ControllerBeanNameHandlerMapping
Mappa controllori su URL basate sul nome del bean del controller
C. Barberis, G. Malnati, 2011-14
ControllerClassNameHandlerMapping
Mappa controllori su URL utilizzando i nomi delle classi del bean
DefaultAnnotationHandlerMapping
Mappa le richieste su controllori o metodi annotati con
@RequestMapping
SimpleUrlHandlerMapping
Mappa controllori a URL utilizzando una collezione di tipo property
definita nellapplication context
Applicazioni Internet 45
Vedi aggiunte.
Quando noi creiamo il controllore lo chiamiamo @Controller e
Controllore della home page davanti ai suoi metodi mettiamo @RequestMapping. Se il nostro
package example; controllore avesse bisogno di cose particolari possiamo mettere
@Controller @Inject se vogliamo che il costruttore abbia dei parametri particola-
public class HomeController { ri: "Quando dovrai fare un homeController, vai a cercare tra i tuoi
public static final int ANNOUNCEMENTS_PER_PAGE = 25;
private MyService myService;
bean se ce n' qualcuno la cui classe implementa MyService". E'
tipo l'autowired su un attributo privato.
@Inject
C. Barberis, G. Malnati, 2011-14
Applicazioni Internet 47
Il metodo showHomePage()
annotato con @RequestMapping
Marca il metodo come un gestore di richieste, indicando che
deve gestire le richieste il cui path o / o /home
Prende come parametro una Map<String, Object>
C. Barberis, G. Malnati, 2011-14
Applicazioni Internet 48
A seconda del ViewResolver che abbiamo configurato, le regole
Identificare le viste sono diverse. Il caso pi semplice usare l'InternalResourceView
Resolver.
Quando noi ritorniamo home, quell'home diventa
Spring fornisce diverse implementazioni di identificatori
delle viste, come /WEB-INF/views/home.jsp. Nelle pagine jsp posso specificare dei
BeanNameViewResolver tag e utilizzare attributi del modello
Cerca unimplementazione di View il cui identificativo sia il nome logico
della vista
ContentNegotiatingViewResolver
Delega uno o pi altri identificatori, in base al tipo di contenuto richiesto
C. Barberis, G. Malnati, 2011-14
FreeMarkerViewResolver
Cerca un template basato su FreeMarker, il cui path viene determinato
utilizzando un prefisso o postfisso al nome logico
InternalResourceViewResolver
>>> Cerca un template allinterno del file WAR dellapplicazione. Il path viene
derivato dal nome logico
JasperReportsViewResolver
Cerca una vista definita come un file Jasper Reports report file, il cui path
viene derivato dal nome logico
Applicazioni Internet 49
Identificare le viste
ResourceBundleViewResolver
Cerca la vista a partire da un file di propriet
TilesViewResolver
Cerca una vista definita come un template Tiles, il cui nome il nome logico
UrlBasedViewResolver
la classe da cui derivano altri resolver
VelocityLayoutViewResolver
C. Barberis, G. Malnati, 2011-14
Applicazioni Internet 50
InternalResolverViewResolver
<bean class=
"org.springframework.web.servlet.view.InternalResourceVie
wResolver">
<property name="prefix" value="/WEB-INF/views/"/>
<property name="suffix" value=".jsp"/>
</bean>
Applicazioni Internet 51
InternalResolverViewResolver
<bean class=
"org.springframework.web.servlet.view.InternalResou
rceViewResolver">
<property name="viewClass"
value="org.springframework.web.servlet.
view.JstlView" />
<property name="prefix" value="/WEB-INF/views/"/>
<property name="suffix" value=".jsp"/>
</bean>
Applicazioni Internet 52
Se vogliamo fare un sito, tipicamente abbiamo bisogno di interagire
Gestione dellinput con delle form. Ad esempio noi possiamo dare la possibilit all'uten-
te di aggiungere un Item: l'operazione base da gestire quella di
progettare le URL che l'utente utilizzer (www.boh.it/addItem: GET
Spesso il controllore deve eseguire delle specifico il prodotto, POST lo aggiungo).
operazioni a fronte di informazioni ricevute
Come parametri della URL o come dati di un form Se stiamo passando i parametri con URL, il controllore accede ai
parametri con la sintassi di annotazione qui indicata. Segue esem-
Questi possono essere iniettati nel metodo di
pio, dove username etichettato con @RequestParam("user").
C. Barberis, G. Malnati, 2011-14
Applicazioni Internet 53
UserController
@Controller
@RequestMapping("/user")
public class UserController {
private final MyService myService;
@Inject
public UserController(MyService myService) {
this.myService = myService;
C. Barberis, G. Malnati, 2011-14
}
@RequestMapping(value="/users", method=GET)
public String listUserDetails(
@RequestParam("user") String username, Model model) {
UserDetails details = myService.getDetails(username);
model.addAttribute(details);
return "user/details";
}
}
Applicazioni Internet 54
Con form non cambia molto, devo solo fare attenzione a gestire i
Gestire l'invio di dati tramite form metodi GET e POST.
Applicazioni Internet 55
Gestire la vista
Per facilitare l'integrazione con le viste, spring
mette a disposizione alcune librerie di tag
<%@ taglib prefix="s"
uri="http://www.springframework.org/tags"%>
<%@ taglib prefix="form"
uri="http://www.springframework.org/tags/form" %>
C. Barberis, G. Malnati, 2011-14
Applicazioni Internet 56
Interessante perch posso passare i @RequestParam uno a fianco
Gestire l'invio tramite form all'altro OPPURE possiamo fare una classe qualunque che dentro
di s ha i vari attributi. In questo secondo caso mettiamo
@ModelAttribute. Affinch la cosa funzioni, necessario che chi
@Controller
public class GreetingController { spedisce i dettagli inserisca i parametri nel "pezzo" giusto.
@RequestMapping(value="/greeting",
method=RequestMethod.GET)
public String greetingForm(Model model) {
model.addAttribute("greeting", new Greeting());
return "greeting";
C. Barberis, G. Malnati, 2011-14
@RequestMapping(value="/greeting",
method=RequestMethod.POST)
public String greetingSubmit(
@ModelAttribute Greeting greeting, Model model) {
model.addAttribute("greeting", greeting);
return "result";
}
}
Applicazioni Internet 57
<td>Name:</td>
<td><form:input path="name" /></td>
</tr><tr>
<td colspan="2">
<input type="submit" value="Set" />
</td>
</tr>
</form:form>
</body>
</html>
Applicazioni Internet 58
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>5.1.0.Final</version>
Si possono esprimere vincoli su valore minimo,
massimo, lunghezza di una stringa, espressioni
regolari, nullit e non nullit dei valori
Applicazioni Internet 59
Validare i parametri (1) Nome dev'essere minimo 2 caratteri e massimo 30, ad esempio.
Quando person verr riempito, l'intercettore che mi crea questo og-
getto verifica che questi vincoli siano buoni. Se non sono buoni vie-
import javax.validation.constraints.*; ne lanciata un'eccezione che mi pu rimandare a una qualche pagi-
public class Person { na.
@Size(min=2, max=30)
private String name;
@NotNull
C. Barberis, G. Malnati, 2011-14
@Min(18)
private Integer age;
Applicazioni Internet 60
@Valid permette di fare l'enforcement sulla validazione. L'eccezio-
Validare i parametri (2) ne non viene scatenata subito, ma viene scritto in bindingResult se
ci sono problemi o meno e analizzandola posso sapere dove man-
dare l'utente.
@Controller
public class WebController {
@RequestMapping(value="/", method=RequestMethod.GET)
public String showForm(Person person) {
return "form";
}
C. Barberis, G. Malnati, 2011-14
@RequestMapping(value="/", method=RequestMethod.POST)
public String checkPersonInfo(@Valid Person person,
BindingResult bindingResult) {
if (bindingResult.hasErrors()) {
return "form";
}
return "results";
}
}
Applicazioni Internet 61
HomeController.java Pagina:1/1
C:\Users\Riccardo\Desktop\ Ultima modifica: 21/06/2014 01.11.06
package com.duckranger.goodproject;
import java.text.DateFormat;
import java.util.Date;
import java.util.Locale;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
/**
* Handles requests for the application home page.
*/
@Controller
public class HomeController {
private static final Logger logger = LoggerFactory.getLogger(HomeController.class);
/**
* Simply selects the home view to render by returning its name.
*/
@RequestMapping(value = "/", method = RequestMethod.GET)
public String home(Locale locale, Model model) {
logger.info("Welcome home! the client locale is "+ locale.toString());
Date date = new Date();
DateFormat dateFormat = DateFormat.getDateTimeInstance(DateFormat.LONG,
DateFormat.LONG, locale);
String formattedDate = dateFormat.format(date);
model.addAttribute("serverTime", formattedDate );
return "home";
}
}
Un possibile modo di costruire un controllore. C' un'annotazione che consente a Spring di capire di cosa si sta parlando
e dentro al controllore c' un metodo home preceduto da un @RequestMapping (quando io faccio una domanda a questi
URL con un certo metodo...).
Il parametro riceve un model in cui posso leggere le cose che c'era-no gi nella richiesta e posso scrivere aggiungendo
un attributo.Dato che c' un locale viene aggiunto un header che mi dice ancheche lingua stata scelta dall'utente.
Volendo possiamo aggiungereun HttpServletRequest req in modo da passare al metodo la richiesta cos come stata
modellata dal servlet base, perch magari vogliamo vedere altri header della richiesta.Un po' meno arzigogolato
rispetto a struts in cui torno stringhe enumerative.
org.springframework.ui
Interface Model
All Known Implementing Classes:
BindingAwareModelMap, ExtendedModelMap
Java-5-specific interface that defines a holder for model attributes. Primarily designed for adding attributes to the model.
Allows for accessing the overall model as a java.util.Map.
Since:
2.5.1
Author:
Juergen Hoeller
addAttribute
Model addAttribute(String attributeName,
Object attributeValue)
Parameters:
attributeName - the name of the model attribute (never null)
attributeValue - the model attribute value (can be null)
addAttribute
Model addAttribute(Object attributeValue)
1 di 2 19/06/2014 23.47
Model (Spring Framework API 2.5) http://docs.spring.io/spring/docs/2.5.x/api/org/springframework/ui/Mod...
Add the supplied attribute to this Map using a generated name.
Note: Empty Collections are not added to the model when using this method because we cannot correctly
determine the true convention name. View code should check for null rather than for empty collections as is already
done by JSTL tags.
Parameters:
attributeValue - the model attribute value (never null)
addAllAttributes
Model addAllAttributes(Collection<?> attributeValues)
Copy all attributes in the supplied Collection into this Map, using attribute name generation for each element.
See Also:
addAttribute(Object)
addAllAttributes
Model addAllAttributes(Map<String,?> attributes)
See Also:
addAttribute(String, Object)
mergeAttributes
Model mergeAttributes(Map<String,?> attributes)
Copy all attributes in the supplied Map into this Map, with existing objects of the same name taking precedence (i.e. not
getting replaced).
containsAttribute
boolean containsAttribute(String attributeName)
Parameters:
attributeName - the name of the model attribute (never null)
Returns:
whether this model contains a corresponding attribute
asMap
Map<String,Object> asMap()
2 di 2 19/06/2014 23.47
web.xml Pagina:1/1
C:\Users\Riccardo\Desktop\ Ultima modifica: 20/06/2014 11.53.32
<!-- The definition of the Root Spring Container shared by all Servlets and
Filters -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring/root-context.xml</param-value>
</context-param>
<!-- Creates the Spring Container shared by all Servlets and Filters -->
<listener>
<listener-
class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<servlet-mapping>
<servlet-name>appServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
web.xml contiene la configurazione base della descrizione del nostro progetto. Notare che per funzionare bene fa
due operazioni:
- crea un ContextLoaderListener cos da sapere quando il progetto viene deployed e quando undeployed (cos se o
file XML cambiano ricarica le configurazioni)
- contiene un Servlet (il dispatcher) che intercetta tutte le richieste. appServlet mappato sulla cartella radice in modo
da intercettare tutte le richieste e ha un suo parametro di configurazione (contextConfigLocation) che gli dice: quando
parti, vai a cercare nella cartella il file servlet-context.xml. All'interno del file possibile specificare i mapping tra URL e
controllori che andranno costruiti.
L'organizzazione del progetto si basa sul fatto che questo esiste a livello web (= l'utente finale accede al sito mediante
URL). Dall'altro lato, il servizio basato su una certa logica: il dominio del sito ha a che fare con alcuni concetti fonda-
mentali (in un sito di shopping ad esempio ho degli oggetti, dei cataloghi, dei carrelli della spesa, eventuali ordini...). Il
dominio di funzionamento interno e il dominio del web hanno dei parallelismi: certo che la parte web mostrer il carrel-
lo della spesa e le funzionalit, ma queste due cose bene tenerle separate. Questo perch la struttura interna dei dati
risponde alle esigenze di chi gestisce il negozio, mentre la parte web risponde ai bisogni dell'utente. In questo modo
posso fare evolvere la parte web dalla parte interna.
E' dunque bene che nel mio insieme di classi io vada a creare due sottocartelle: uno il package web (tutto quello che
mi serve per farlo girare sul web, e dentro ci vanno a finire i controllers) e uno il package service (in cui mappo "i con-
cetti", ovvero le cose che mi interessano). Ad esempio nel package service posso avere una public interface Item:
questo mi d la possibilit di crearmi delle classi concrete che implementano Item, e sono libero di farle evolvere nel
tempo.
Questo un file beans (come tutti i container di Spring) che contiene al suo interno alcuni pezzi base:
- Il bean che implementa InternalViewResolver, che si aspetta roba in .jsp. Viene specificato il prefisso da mettere
alle stringhe ritornate dai controller e anche il suffisso.
- <annotation-driven>: se noi non lo indichiamo, lui si limita a cercare nei file .XML. Quindi le annotazioni presenti
nelle classe vengono ignorate (e non ci piace)
- <context:component-scan>: lui di default non pu andare a cercare annotazioni in tutto il classpath esistente.
Tocca a noi dire il nome dei package in cui mettiamo annotazioni utili per il mapping.
- <resources>: guarda che all'interno del mio progetto ci sono due tipi di URL. Ho le URL dinamiche, che verranno
processate da un controller, ma ogni tanto far riferimento a delle cose statiche: vero che potrei fare un controller,
ma uno spreco. Questa regola ci dice che ogni volta che riceviamo un qualcosa il cui URL resources/... vai nella
cartella e daglielo.
<!-- Root Context: defines shared resources visible to all other web components -->
</beans>
Qui possiamo definirci dei bean che vogliamo rendere accessibili a tutta la nostra struttura. In questo modo viene
creato a tutti un bean chiamato itemManager con questa classe. Pi avanti un esempio di HomeController modificato.
package it.polito.ai.service;
/* Descrive un Item */
public interface Item {
String getName();
double getPrice();
String getDescription();
}
/*****************************************************************************/
package it.polito.ai.service;
package it.polito.ai.service;
import java.util.List;
/******************************************************************************/
package it.polito.ai.service;
import java.util.List;
import java.util.ArrayList;
public SimpleItemManager() {
for (int i = 1; i < 5; i++) {
Item i = new SimpleItem("Item " + i, "Description " + i, i*10);
items.add(item);
}
}
/* Affinch tutto funzioni, Item deve avere equals() e lo posso generare in modo
automatico */
package it.polito.ai.web;
import it.polito.ai.service.ItemManager;
/* ... */
/**
* Handles requests for the application home page.
*/
@Controller
public class HomeController {
/* A questo punto nella vista home posso aggiungere una table che elenca gli item.
Gli item li peschiamo, ad esempio, con <c:forEach var="item"
items="${items}"></c:forEach>.
Questo vuol dire: prendi nel modello una variabile items che dev'essere iterable e
per ciascuno di questi elementi scorri l'iteratore assegnando l'elemento che hai
preso a una nuova variabile item. Il nome lo prendo con ${item.name}: si guarda
nell'oggetto item se c' un metodo getName e se s lo invoca. E cos via per gli
altri. */