commandButton / commandLink / ajax action / metodo listener non richiamato o valore di input non impostato / aggiornato


345

A volte, quando si utilizza <h:commandLink>, <h:commandButton>o <f:ajax>, il action, actionListenero listenermetodo associato con il tag sono semplicemente non viene richiamato. In alternativa, le proprietà del bean non vengono aggiornate con i UIInputvalori inviati .

Quali sono le possibili cause e soluzioni per questo?

Risposte:


687

introduzione

Ogni volta che un UICommandcomponente ( <h:commandXxx>, <p:commandXxx>ecc.) Non riesce a invocare il metodo di azione associato o un UIInputcomponente ( <h:inputXxx>, <p:inputXxxx>ecc.) Non riesce a elaborare i valori inviati e / o aggiornare i valori del modello e non vengono visualizzate eccezioni googlabili e / o avvisi nel registro del server, anche quando si configura un gestore eccezioni ajax come da Gestione eccezioni nelle richieste ajax JSF , né quando si imposta il parametro di contesto sotto in web.xml,

<context-param>
    <param-name>javax.faces.PROJECT_STAGE</param-name>
    <param-value>Development</param-value>
</context-param>

e inoltre non visualizzi errori e / o avvisi googlable nella console JavaScript del browser (premi F12 in Chrome / Firefox23 + / IE9 + per aprire il set di strumenti per sviluppatori web e quindi apri la scheda Console ), quindi procedi attraverso l'elenco delle possibili cause.

Cause possibili

  1. UICommande i UIInputcomponenti devono essere collocati all'interno di un UIFormcomponente, ad es. <h:form>(e quindi non semplice HTML <form>), altrimenti non è possibile inviare nulla al server. UICommandanche i componenti non devono avere type="button"attributi, altrimenti sarà un pulsante morto che è utile solo per JavaScript onclick. Vedere anche Come inviare i valori di input del modulo e invocare un metodo nel bean JSF e <h: commandButton> non avvia un postback .

  2. Non è possibile nidificare più UIFormcomponenti l'uno nell'altro. Questo è illegale in HTML. Il comportamento del browser non è specificato. Fai attenzione con i file include! È possibile utilizzare i UIFormcomponenti in parallelo, ma non si elaboreranno a vicenda durante l'invio. Dovresti anche stare attento con l'antipasto "God Form"; assicurati di non elaborare / convalidare involontariamente tutti gli altri input (invisibili) nella stessa forma (ad es. avere una finestra di dialogo nascosta con input richiesti nella stessa forma). Vedi anche Come usare <h: form> nella pagina JSF? Forma singola? Forme multiple? Forme nidificate? .

  3. Non UIInputsi sarebbe verificato alcun errore di convalida / conversione del valore. È possibile utilizzare <h:messages>per mostrare tutti i messaggi che non sono mostrati da alcun <h:message>componente specifico di input . Non dimenticare di includere il iddi <h:messages>in <f:ajax render>, se presente, in modo che venga aggiornato anche nelle richieste Ajax. Vedi anche h: i messaggi non visualizzano i messaggi quando si preme p: commandButton .

  4. Se UICommando UIInputcomponenti vengono inseriti all'interno di un componente iterante come <h:dataTable>, <ui:repeat>ecc., È necessario assicurarsi che lo stesso valuecomponente iterante sia stato conservato durante la fase di richiesta dei valori della richiesta di invio del modulo. JSF lo ripeterà per trovare il link / pulsante cliccato e i valori di input inviati. Mettere il bean nell'ambito della vista e / o assicurarsi di caricare il modello di dati nel @PostConstructbean (e quindi non in un metodo getter!) Dovrebbe risolverlo. Vedi anche Come e quando devo caricare il modello dal database per h: dataTable .

  5. Se UICommando UIInputcomponenti sono inclusi da un'origine dinamica come <ui:include src="#{bean.include}">, allora è necessario assicurarsi che lo stesso #{bean.include}valore sia preservato durante il tempo di costruzione della vista della richiesta di invio del modulo. JSF lo eseguirà nuovamente durante la creazione dell'albero dei componenti. Mettere il bean nell'ambito della vista e / o assicurarsi di caricare il modello di dati nel @PostConstructbean (e quindi non in un metodo getter!) Dovrebbe risolverlo. Vedi anche Come aggiornare ajax in modo dinamico includere i contenuti tramite il menu di navigazione? (JSF SPA) .

  6. L' renderedattributo del componente e di tutti i suoi genitori e l' testattributo di qualsiasi genitore <c:if>/ <c:when>non devono essere valutati falsedurante la fase di richiesta dei valori della richiesta di invio del modulo. JSF lo ricontrollerà come parte della protezione contro richieste manomesse / compromesse. Memorizzare le variabili responsabili della condizione in un @ViewScopedbean o accertarsi di preinizializzare correttamente la condizione in @PostConstructun @RequestScopedbean dovrebbe risolverlo. Lo stesso vale per l' disabledattributo del componente, che non deve essere valutato truedurante la fase di applicazione dei valori di richiesta. Vedi anche l' azione CommandButton JSF non invocata , invio del modulo nel componente sottoposto a rendering condizionale non viene elaborato eh: commandButton non funziona una volta che lo avvolgo in un <h: panelGroup reso> .

  7. L' onclickattributo del UICommandcomponente e l' onsubmitattributo del UIFormcomponente non devono restituire falseo causare un errore JavaScript. In caso di errori JS <h:commandLink>o <f:ajax>anche non essere visibili nella console JS del browser, dovrebbero essere presenti. Di solito google il messaggio di errore esatto ti darà già la risposta. Vedi anche Aggiunta / caricamento manuale di jQuery con risultati PrimeFaces in Uncaught TypeErrors .

  8. Se si utilizza Ajax tramite JSF 2.xo <f:ajax>ad esempio PrimeFaces <p:commandXxx>, assicurarsi di avere un <h:head>modello principale anziché <head>. Altrimenti JSF non sarà in grado di includere automaticamente i file JavaScript necessari che contengono le funzioni Ajax. Ciò comporterebbe un errore JavaScript come "mojarra non definito" o "PrimeFaces non definito" nella console JS del browser. Vedi anche h: commandLink actionlistener non viene richiamato se usato con f: ajax e ui: repeat .

  9. Se si utilizza Ajax e i valori inviati finiscono per essere null, assicurarsi che i componenti UIInpute UICommanddi interesse siano coperti da <f:ajax execute>o ad es. <p:commandXxx process>, Altrimenti non verranno eseguiti / elaborati. Vedere anche Valori modulo inviati non aggiornati nel modello quando si aggiungono <f: ajax> in <h: commandButton> e Comprensione processo / aggiornamento PrimeFaces e JSF f: ajax eseguono / rendono gli attributi .

  10. Se i valori inviati continuano a essere null, e stai usando CDI per gestire i bean, assicurati di importare l'annotazione dell'ambito dal pacchetto corretto, altrimenti CDI verrà automaticamente impostato su predefinito per @Dependentricreare il bean su ogni singola valutazione dell'EL espressione. Vedi anche il bean @SessionScoped perde ambito e viene ricreato continuamente, i campi diventano nulli e Qual è l'ambito di bean gestito predefinito in un'applicazione JSF 2?

  11. Se un genitore del <h:form>con il UICommandpulsante è stato precedentemente reso / aggiornato da una richiesta Ajax proveniente da un altro modulo nella stessa pagina, la prima azione fallirà sempre in JSF 2.2 o precedente. La seconda e le successive azioni funzioneranno. Ciò è causato da un bug nella gestione dello stato di visualizzazione che viene segnalato come problema con le specifiche JSF 790 e attualmente risolto in JSF 2.3. Per le versioni più vecchie JSF, è necessario specificare in modo esplicito l'ID del <h:form>nel renderdel <f:ajax>. Vedi anche h: commandButton / h: commandLink non funziona al primo clic, funziona solo al secondo clic .

  12. Se <h:form>è stato enctype="multipart/form-data"impostato per supportare il caricamento di file, è necessario assicurarsi di utilizzare almeno JSF 2.2 o che il filtro servlet responsabile dell'analisi delle richieste multipart / form-data sia configurato correttamente, altrimenti la FacesServletvolontà finiscono per non ottenere alcun parametro di richiesta e quindi non possono applicare i valori di richiesta. La modalità di configurazione di tale filtro dipende dal componente di caricamento file utilizzato. Per Tomahawk <t:inputFileUpload>, controlla questa risposta e per PrimeFaces <p:fileUpload>, controlla questa risposta . Oppure, se in realtà non stai caricando affatto un file, rimuovi del tutto l'attributo.

  13. Assicurati che l' ActionEventargomento di actionListenersia un javax.faces.event.ActionEvente quindi no java.awt.event.ActionEvent, che è ciò che la maggior parte degli IDE suggerisce come prima opzione di completamento automatico. Non avere argomenti è sbagliato anche se si utilizza actionListener="#{bean.method}". Se non vuoi un argomento nel tuo metodo, usa actionListener="#{bean.method()}". O forse vuoi effettivamente usare actioninvece di actionListener. Vedi anche Differenze tra action e actionListener .

  14. Assicurarsi che nessuno PhaseListenero nessuno EventListenernella catena richiesta-risposta abbia modificato il ciclo di vita di JSF per saltare la fase di azione di richiamo, ad esempio chiamando FacesContext#renderResponse()o FacesContext#responseComplete().

  15. Assicurarsi che nessuna Filtero Servletnella stessa catena richiesta-risposta abbia bloccato la richiesta in FacesServletqualche modo. Ad esempio, i filtri di accesso / sicurezza come Spring Security. Soprattutto nelle richieste Ajax che per impostazione predefinita finirebbero senza alcun feedback dell'interfaccia utente. Vedi anche Gestione delle richieste AJAX di Spring Security 4 e PrimeFaces 5 .

  16. Se si utilizza un PrimeFaces <p:dialog>o un <p:overlayPanel>, quindi assicurarsi che abbiano i propri <h:form>. Perché, questi componenti sono per impostazione predefinita da JavaScript trasferiti alla fine di HTML <body>. Quindi, se fossero stati originariamente seduti all'interno di un <form>, allora non si sarebbero più seduti in un <form>. Vedi anche l' azione p: commandbutton non funziona all'interno di p: dialog

  17. Bug nel framework. Ad esempio, RichFaces presenta un " errore di conversione " quando si utilizza un rich:calendarelemento dell'interfaccia utente con un defaultLabelattributo (o, in alcuni casi, un rich:placeholderelemento secondario). Questo errore impedisce di invocare il metodo bean quando non è impostato alcun valore per la data del calendario. La traccia dei bug del framework può essere realizzata iniziando con un semplice esempio funzionante e costruendo il backup della pagina fino a quando il bug non viene scoperto.

Suggerimenti per il debug

Nel caso in cui rimanga bloccato, è il momento di eseguire il debug. Nel lato client, premi F12 nel browser web per aprire il set di strumenti per sviluppatori web. Fai clic sulla scheda Console, quindi vedi il cono JavaScript. Dovrebbe essere privo di errori JavaScript. Lo screenshot seguente mostra un esempio di Chrome che mostra il caso di invio di un <f:ajax>pulsante abilitato senza averlo <h:head>dichiarato (come descritto al punto 7 sopra).

console js

Fare clic sulla scheda Rete per vedere il monitoraggio del traffico HTTP. Invia il modulo e verifica se le intestazioni della richiesta, i dati del modulo e l'organismo di risposta sono conformi alle aspettative. Lo screenshot seguente mostra un esempio di Chrome che mostra un invio ajax di successo di un semplice modulo con un singolo <h:inputText>e un singolo <h:commandButton>con <f:ajax execute="@form" render="@form">.

monitor di rete

(avviso: quando pubblichi screenshot dalle intestazioni delle richieste HTTP come sopra da un ambiente di produzione, assicurati di mescolare / offuscare qualsiasi cookie di sessione nello screenshot per evitare attacchi di dirottamento della sessione!)

Sul lato server, assicurarsi che il server sia avviato in modalità debug. Inserisci un breakpoint di debug in un metodo del componente JSF di interesse che prevedi di essere chiamato durante l'elaborazione del modulo di invio. Ad esempio in caso di UICommandcomponente, sarebbe UICommand#queueEvent()e in caso di UIInputcomponente, sarebbe UIInput#validate(). Basta passare attraverso l'esecuzione del codice e ispezionare se il flusso e le variabili sono come da aspettative. Lo screenshot seguente è un esempio del debugger di Eclipse.

server di debug


1
il tuo secondo punto mi ha fatto pensare - per molto tempo. Ho appena scoperto che un tag f: view nel mio file principale era la causa della maggior parte dei miei problemi. E probabilmente perché rende una forma, giusto?
Paulo Guedes,

2
@pauloguedes Non riesco a trovare nulla che indichi che f: view rende un modulo. La mia comprensione è che è solo un contenitore. Nella mia esperienza, f: view non rende alcun elemento.
Lucas,

@balusc Un piccolo chiarimento sul punto 4, se il comandoLink non è nella stessa tabella dei dati, è ancora importante?
Lucas,

grazie, il punto è il punto: mettere il bean nell'ambito della vista e / o assicurarsi di caricare il modello di dati nel (post) costruttore del bean (e quindi non nel metodo getter!) dovrebbe risolverlo.
Merveotesi,

2
@Kukeltje: che avrebbe generato un'eccezione EL (già coperta dal primo paragrafo nella risposta)
BalusC

54

Se il tuo h:commandLinkè dentro a h:dataTablec'è un altro motivo per cui h:commandLinkpotrebbe non funzionare:

L'origine dati sottostante cui è associato h:dataTabledeve essere disponibile anche nel secondo ciclo di vita JSF che viene attivato quando si fa clic sul collegamento.

Quindi, se l'origine dati sottostante è nell'ambito della richiesta, h:commandLinknon funziona!


2
Ok, non era del tutto chiaro per me. Spero comunque che la mia risposta sia utile, poiché nel mio caso almeno non avevo a che fare esplicitamente con UICommand / UIData. La "soluzione" stava promuovendo un bean di supporto dall'ambito della richiesta all'ambito della sessione ...
jbandi

1
Secondo commento di Jens ... l'impostazione del bean RequestScoped su SessionScoped ha fatto la differenza sui miei dati Tabella - grazie
Zack Macomber,

28

Sebbene la mia risposta non sia applicabile al 100%, ma la maggior parte dei motori di ricerca trova questo come primo successo, ho deciso di pubblicarlo comunque:

Se stai usando PrimeFaces (o qualche API simile) p:commandButtono p:commandLink, è probabile che ti sei dimenticato di aggiungere esplicitamente process="@this"ai tuoi componenti di comando.

Come afferma la Guida dell'utente di PrimeFaces nella sezione 3.18, i valori predefiniti per processe updatesono entrambi @form, che si oppongono praticamente ai valori predefiniti che ci si potrebbe aspettare da JSF f:ajaxo RichFaces semplici, che sono execute="@this"e render="@none"rispettivamente.

Mi ci è voluto un po 'di tempo per scoprirlo. (... e penso che sia piuttosto unclever usare valori predefiniti diversi da JSF!)


6
L'impostazione predefinita per PrimeFaces processè @form. Quindi se l'azione non viene invocata in questo modo, ma lo fa durante l'utilizzo @this, molto probabilmente si applica il punto 3 della mia risposta.
BalusC

3
Questo non può essere. Ho avuto un p:commandButtonche non ha invocato il metodo actionListener fino a quando non l'ho aggiunto process="@this". Inoltre, la Guida per l'utente di PrimeFaces elenca esplicitamente le impostazioni predefinite menzionate nelle sezioni 3.18 e 3.19. È qui: primefaces.googlecode.com/files/primefaces_users_guide_3_4.pdf ... forse le impostazioni predefinite sono state modificate?
Kawu,

8
È probabile che si sia verificato un errore nella documentazione. Rimuovi process="@this"e aggiungi <p:messages autoUpdate="true">(o leggi il registro del server per i messaggi in coda ma non visualizzati) e vedrai che in realtà si è verificato un errore di conversione / convalida.
BalusC

Perché si rimuove questa domanda stackoverflow.com/questions/60673695/...
Kukeltje

Ho pensato che potrebbe non fornire molto valore ora ... L'ho eliminato.
Kawu,

9

Vorrei menzionare un'altra cosa che riguarda Primefaces p:commandButton!

Quando si utilizza a p:commandButtonper l'azione che deve essere eseguita sul server, non è possibile utilizzare type="button"perché è per i pulsanti che vengono utilizzati per eseguire javascript personalizzato senza causare una richiesta ajax / non-ajax al server.

A tale scopo, è possibile dispensare l' typeattributo (il valore predefinito è "submit") oppure è possibile utilizzare esplicitamente type="submit".

Spero che questo possa aiutare qualcuno!


questo è stato il mio problema principale in una delle nostre pagine, nessuno dei punti della risposta accettata ci ha avvicinato, dove hai trovato queste informazioni?
Uriel Arvizu,

Bene, ho avuto questo problema molte volte, e ho fatto ricerche e ho scoperto che p:commandButtonha diversi valori di typeattributo ed buttonè uno che riguarda tutto ciò che riguarda il lato client. È un po 'difficile trovarlo in Primefacesdoc, ma ecco un link: developer.am/primefaces/…
akelec

Il tuo suggerimento di inoltro ha risolto il mio problema che ho dovuto affrontare da giorni. Grazie mille per il tuo post!
gpuk360,

Grazie, è un piacere. Ho deliberatamente posto questa risposta perché molti di noi hanno avuto un tale problema. Avevo perso anche qualche giorno fino a quando non ho capito di cosa si tratta.
akelec,

3

Mi sono bloccato con questo problema e ho trovato un'altra causa per questo problema. Se non hai metodi setter nel tuo backing bean per le proprietà usate nel tuo * .xhtml, semplicemente l'azione non viene invocata.


5
Avrebbe dovuto tradursi in una spiegazione piuttosto chiara PropertyNotWritableException. Se non l'hai visto, forse hai lanciato una richiesta Ajax senza un appropriato gestore delle eccezioni Ajax, ma dovresti vederlo nei registri del server.
BalusC,

3
Non ha mostrato quell'eccezione fino a quando non ho creato p: commandButton's ajax = "false".
Dnavir,

GRAZIE DIO mi hai salvato la vita
exrezzo il

3

Di recente ho riscontrato un problema con un UICommand non richiamato in un'applicazione JSF 1.2 utilizzando IBM Extended Faces Components.

Avevo un pulsante di comando su una riga di un datatable (la versione estesa, quindi <hx:datatable>) e l'UICommand non si attiva da determinate righe della tabella (le righe che non si attivano sarebbero le righe maggiori della dimensione di visualizzazione della riga predefinita).

Avevo un componente a discesa per selezionare il numero di righe da visualizzare. Il valore a sostegno di questo campo era RequestScope. I dati a supporto della tabella stessa erano in una sorta di ViewScope(in realtà, temporaneamente in SessionScope).

Se la visualizzazione della riga è stata aumentata tramite il controllo, quale valore è stato anche associato ai datatable rows all'attributo , nessuna delle righe visualizzate a seguito di questa modifica potrebbe generare il comando UIC quando si fa clic.

Posizionare questo attributo nello stesso ambito dei dati della tabella stessa ha risolto il problema.

Penso che questo sia accennato in BalusC # 4 sopra, ma non solo il valore della tabella deve essere con ambito View o Session, ma anche l'attributo che controlla il numero di righe da visualizzare su quella tabella.


2

Ho avuto anche questo problema e ho iniziato a perfezionarmi sulla causa principale solo dopo aver aperto la console Web del browser. Fino a quel momento, non sono stato in grado di ricevere messaggi di errore (anche con <p:messages>). La console Web ha mostrato un codice di stato HTTP 405 che ritorna da<h:commandButton type="submit" action="#{myBean.submit}"> .

Nel mio caso, ho un mix di HttpServlet vanilla che fornisce l'autenticazione OAuth tramite facelet e bean Auth0 e JSF che eseguono le mie visualizzazioni dell'applicazione e la logica aziendale.

Una volta refactored il mio web.xml e rimosso un servlet man-middle, allora "magicamente" ha funzionato.

In conclusione, il problema era che il servlet middle-man stava usando RequestDispatcher.forward (...) per reindirizzare dall'ambiente HttpServlet all'ambiente JSF mentre il servlet chiamato prima di esso stava reindirizzando con HttpServletResponse.sendRedirect (.. .).

Fondamentalmente, l'utilizzo di sendRedirect () ha consentito al "contenitore" JSF di assumere il controllo, mentre RequestDispatcher.forward () ovviamente non lo era.

Quello che non so è il motivo per cui il facelet è stato in grado di accedere alle proprietà del bean ma non è riuscito a impostarle, e questo chiaramente grida per aver eliminato il mix di servlet e JSF, ma spero che questo aiuti qualcuno a evitare molte ore di testa- to-table-banging.


1

Mi sono divertito molto a eseguire il debug di un problema a causa del quale <h:commandLink>un'azione di un richfaces datatablegiocatore si rifiutava di sparare. La tabella funzionava ad un certo punto ma si fermava senza una ragione apparente. Non ho lasciato nulla di intentato, solo per scoprire che il mio rich:datatablestava usando il torto rowKeyConverterche restituiva valori nulli che richfaces usavano felicemente come chiavi di riga. Ciò ha impedito che la mia <h:commandLink>azione venisse chiamata.


0

Un'altra possibilità: se il sintomo è che la prima chiamata funziona, ma le successive non funzionano, è possibile che si stia utilizzando PrimeFaces 3.x con JSF 2.2, come dettagliato qui: Nessun ViewState viene inviato .


-1

Ho risolto il mio problema inserendo:

<h:commandButton class="btn btn-danger" value = "Remove" action="#{deleteEmployeeBean.delete}"></h:commandButton>

Nel:

<h:form>
     <h:commandButton class="btn btn-danger" value = "Remove" action="#{deleteEmployeeBean.delete}"></h:commandButton>
</h:form>

Questo è il numero 1 nella risposta> 600 votata. Non è necessario scriverlo come risposta separata.
Kukeltje,

-1

Questa è la soluzione, che ha funzionato per me.

<p:commandButton id="b1" value="Save" process="userGroupSetupForm"
                    actionListener="#{userGroupSetupController.saveData()}" 
                    update="growl userGroupList userGroupSetupForm" />

Qui, l'attributo process = "userGroupSetupForm" è obbligatorio per la chiamata Ajax. actionListener sta chiamando un metodo da @ViewScope Bean. Aggiornamento anche del messaggio di ringhio, Datatable: userGroupList e Modulo: userGroupSetupForm.


-2
<ui:composition>  
  <h:form id="form1">
    <p:dialog id="dialog1">
      <p:commandButton value="Save" action="#{bean.method1}" /> <!--Working-->
    </p:dialog>
  </h:form>

  <h:form id="form2">
    <p:dialog id="dialog2">
      <p:commandButton value="Save" action="#{bean.method2}" /> <!--Not Working-->
    </p:dialog>
  </h:form>
</ui:composition>

Risolvere;

<ui:composition>  
  <h:form id="form1">
    <p:dialog id="dialog1">
      <p:commandButton value="Save" action="#{bean.method1}" />   <!-- Working  -->
    </p:dialog>

    <p:dialog id="dialog2">
      <p:commandButton value="Save" action="#{bean.method2}" />   <!--Working  -->
    </p:dialog>
  </h:form>
  <h:form id="form2">
    <!-- ..........  -->
  </h:form>
</ui:composition>

Mi dispiace, ma questo è a mio modesto parere totalmente non vero. Affermate in modo efficace che 2 dialoghi devono essere nella loro forma per funzionare. Con la certezza del 99% hai avuto un problema diverso che hai risolto e per il quale ora pensi che questa sia la soluzione ...
Kukeltje,

Questa è una pagina inclusa. Forse questo può causare problemi. Dovresti testarlo prima del voto.
Kenan Gökbak,

No, avresti dovuto creare un esempio riproducibile minimo prima di pubblicare (e solo allora posso testarlo) ... E sì, le inclusioni possono causare problemi con finestre di dialogo e moduli, ma il problema non è ancora quello che sembra voler risolvere qui . Il tuo primo esempio va benissimo e il secondo è con certezza al 100% non una soluzione di un problema inesistente
Kukeltje,

Comunque. La mia applicazione funziona bene. Penso che non sia importante la finestra di dialogo nel modulo. Devo creare un secondo modulo per risolvere un altro problema.
Kenan Gökbak,

La tua applicazione potrebbe funzionare, ma ciò non è chiaro / visibile da un problema originale e dalla tua 'soluzione. Inoltre, dici _ "Penso che non sia importante dove finestre di dialogo nel modulo." _Ma nella tua risposta sembra essere importante dove sono. Una contraddizione che supporta la mia affermazione. Ci dispiace, ma la tua risposta è chiaramente sbagliata ... (c'è già un altro downvote)
Kukeltje,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.