WebMvcConfig e pom.xml poco chiari

di il
6 risposte

WebMvcConfig e pom.xml poco chiari

Sto leggendo questa applicazione:
https://github.com/Apress/beg-spring-boot-2/tree/master/chapter-10/springboot-web-demo
e non ho capito i file WebMvcConfig.java e pom.xml.
WebMvcConfig.java
1) Non riesco a capire a che piffero serve questo metodo:

    @Override
    public Validator getValidator() {
        LocalValidatorFactoryBean factory = new LocalValidatorFactoryBean();
        factory.setValidationMessageSource(messageSource);
        return factory;
    }
Ho letto qui:
https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/validation/beanvalidation/LocalValidatorFactoryBean.html
ma proprio non riesco a capire un accidente!
2) L'autore scrive anche che WebMvcConfigurer è deprecato ma allora perché lo usa? Cosa dovrei usare al posto di WebMvcConfigurer con JDK 14?
pom.xml
3) Codice (le domande le ho messe sopra il codice poco chiaro):

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<!-- Scope prevede 3 opzioni: compile, provided e test. -->
			<!-- Di default, quando non c'è scritto niente si sottintende compile e la dipendenza viene messa nel file
			.war. Quando si usa provided la dipendenza non viene aggiunta al file .war ma viene sempre resa disponibile
			localmente all'avvio dell'applicazione sull'IDE di sviluppo. Quando si usa test la dipendenza non viene
			aggiunta al file .war e viene resa disponibile localmente solo quando si eseguono dei test sulla webapp
			ovvero si eseguono delle classi su cui sono presenti annotazioni del tipo @SpringBootTest o similari.
			E' corretto quello che scrivo????????????????????????????????????????????????????????????????????????????-->
			<scope>test</scope>
		</dependency>
4) Codice:

		<!-- 'spring-boot-devtools' è presente nel .war eventualmente prodotto oppure viene caricato solo quando premo
		run sul mio IntelliJ IDEA? Se si trattasse di un'applicazione reale dovrei rimuovere la dipendenza dal pom.xml
		prima di produrre il file .war? Disabilitare la cache anche sul server reale è una pratica da evitare?
		???????????????????????????????????????????????????????????????????????????????????????????????????????????? -->
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-devtools</artifactId>
			<optional>true</optional>
		</dependency>
5) Codice:

		<dependency>
			<groupId>org.webjars</groupId>
			<artifactId>bootstrap</artifactId>
			<!-- Si indica la versione nella dipendenza perché Spring Boot non prevedere il caricamento automatico di
			una versione di bootstrap? Come faccio a capire quando devo usare <version> e quando usare
			<bootstrap.version>?
			???????????????????????????????????????????????????????????????????????????????????????????????????????? -->
			<version>3.3.7</version>
		</dependency>
6) Codice:

	<profiles>
		<profile>
			<!-- Profilo creato per usare tomcat come server embedded. -->
			<id>tomcat</id>
			<activation>
				<!-- Dipendenza attiva di default. -->
				<activeByDefault>true</activeByDefault>
			</activation>
			<dependencies>
				<!-- Dipendenza per creare Web Application usando Spring MVC. -->
				<dependency>
					<groupId>org.springframework.boot</groupId>
					<artifactId>spring-boot-starter-web</artifactId>
				</dependency>
				<!-- Perché non si aggiunge la dipendenza tomcat con tag <scope>provided</scope>? Se sul server reale ci
				sarà tomcat perché caricarlo automaticamente insieme a spring-boot-starter-web?
				Perché in questa esercitazione c'è:
				https://github.com/Apress/beg-spring-boot-2/tree/master/chapter-10/springboot-war-demo
				e in questa esercitazione non c'è:
				https://github.com/Apress/beg-spring-boot-2/tree/master/chapter-10/springboot-web-demo
				?????????????????????????????????????????????????????????????????????????????????????????????????????-->
			</dependencies>
7) Codice:

				<dependency>
					<groupId>org.springframework.boot</groupId>
					<!-- Perché spring-boot-starter-jetty è segnato in rosso dall'IDEA? Come risolvo? Come attivo il 
					profilo jetty aggiungendo codice alla webapp? 
					?????????????????????????????????????????????????????????????????????????????????????????????????-->
					<artifactId>spring-boot-starter-jetty</artifactId>
				</dependency>
8) Codice:

				<dependency>
					<groupId>org.springframework.boot</groupId>
					<!-- Perché spring-boot-starter-undertow è segnato in rosso dall'IDEA? Come risolvo?
					?????????????????????????????????????????????????????????????????????????????????????????????????-->
					<artifactId>spring-boot-starter-undertow</artifactId>
				</dependency>

6 Risposte

  • Re: WebMvcConfig e pom.xml poco chiari

    giannino1995 ha scritto:


    Sto leggendo questa applicazione:
    https://github.com/Apress/beg-spring-boot-2/tree/master/chapter-10/springboot-web-demo
    Precisiamo innanzitutto che quel progetto è stato pensato per essere usato "standalone" (jar) ... NON war.

    giannino1995 ha scritto:


    WebMvcConfig.java
    1) Non riesco a capire a che piffero serve questo metodo:
    
        @Override
        public Validator getValidator() {
            LocalValidatorFactoryBean factory = new LocalValidatorFactoryBean();
            factory.setValidationMessageSource(messageSource);
            return factory;
        }
    
    Ho letto qui:
    https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/validation/beanvalidation/LocalValidatorFactoryBean.html
    ma proprio non riesco a capire un accidente!
    Mah .. comunque il quel springboot-web-demo non vedo alcun uso esplicito della "validazione". Nè l'uso dei messages_XXX.properties.
    Quindi o è un refuso dell'autore (es. copia-incolla da un altro progetto) o .... boh.

    La validazione si può usare a molti livelli, anche "programmaticamente". A livello di parametri nei controller, la validazione è già "di serie" (non devi implementare/overridare nulla!), basta avere il spring-boot-starter-validation

    giannino1995 ha scritto:


    2) L'autore scrive anche che WebMvcConfigurer è deprecato
    No, la classe di implementazione WebMvcConfigurerAdapter è deprecata. Ma la interfaccia WebMvcConfigurer è ancora perfettamente valida e non deprecata.

    giannino1995 ha scritto:


    le domande le ho messe sopra il codice poco chiaro
    Era meglio se le mettevi nel testo normale ... altrimenti diventa difficile "quotarle".

    giannino1995 ha scritto:


    Scope prevede 3 opzioni: compile, provided e test.
    Di default, quando non c'è scritto niente si sottintende compile e la dipendenza viene messa nel file .war. Quando si usa provided la dipendenza non viene aggiunta al file .war ma viene sempre resa disponibile localmente all'avvio dell'applicazione sull'IDE di sviluppo. Quando si usa test la dipendenza non viene aggiunta al file .war e viene resa disponibile localmente solo quando si eseguono dei test sulla webapp ovvero si eseguono delle classi su cui sono presenti annotazioni del tipo @SpringBootTest o similari.
    E' corretto quello che scrivo????????????????????????????????????????????????????????????????????????????
    Innanzitutto Maven prevede 6 (SEI) scope che sono documentati nella documentazione ufficiale: https://maven.apache.org/guides/introduction/introduction-to-dependency-mechanism.html#Dependency_Scope

    Quindi dopo che hai letto a quel link, quali possono essere gli ulteriori dubbi?

    giannino1995 ha scritto:


    'spring-boot-devtools' è presente nel .war eventualmente prodotto oppure viene caricato solo quando premo run sul mio IntelliJ IDEA? Se si trattasse di un'applicazione reale dovrei rimuovere la dipendenza dal pom.xml prima di produrre il file .war?
    No non va a finire in un war, se noti ha <optional>true</optional>

    Optional è documentato qui: https://maven.apache.org/guides/introduction/introduction-to-optional-and-excludes-dependencies.html
    Leggi il paragrafo a "Why use optional dependencies?"

    giannino1995 ha scritto:


    Disabilitare la cache anche sul server reale è una pratica da evitare?
    In ambiente "produzione", il caching non è da togliere ... altrimenti che senso avrebbe?
    Mentre è utile toglierlo in ambiente di "sviluppo".

    giannino1995 ha scritto:


    Si indica la versione nella dipendenza perché Spring Boot non prevedere il caricamento automatico di una versione di bootstrap? Come faccio a capire quando devo usare <version> e quando usare <bootstrap.version>?
    Te lo avevo già spiegato in parte. Il pom della applicazione ha come <parent> l'artifact spring-boot-starter-parent il quale ha a sua volta come <parent> l'artifact spring-boot-dependencies.
    Questo spring-boot-dependencies è quello che contiene un <properties> con TANTE versioni e poi contiene un <dependencyManagement> con <dependencies> e le dichiarazioni di TANTE dipendenze.
    Vedine uno, es. https://repo1.maven.org/maven2/org/springframework/boot/spring-boot-dependencies/2.3.3.RELEASE/spring-boot-dependencies-2.3.3.RELEASE.pom

    <dependencyManagement> è una cosa particolare, NON tira dentro quelle dipendenze! E' solo per così dire la dichiarazione "teorica" delle dipendenze. Un po' come se fossero dei "suggerimenti per la spesa". Ti dice es.: guarda che per Spring Boot 2.3.3 le versioni "consigliate" sono queste, 3.16.1 per AssertJ, 2.11.2 per Jackson, 1.7.30 per SLF4J, 8.0.21 per il MySQL Connector/J, ecc... ecc...

    Poi se nel TUO pom vuoi proprio mettere il Connector/J di MySQL, allora metti solo:
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
    </dependency>
    SENZA versione, perché viene EREDITATA da quel spring-boot-dependencies. Il <dependencyManagement> serve per "accentrare" in un unico punto (tipicamente in un pom "parente") le versioni in modo che più progetti possano "ereditare" facilmente quelle versioni.

    Ma è ovvio che in quel spring-boot-dependencies NON ci sono tutte le versioni/dipendenze di questo mondo!!! Ci sono solo quelle più legate a Spring Boot. E quindi è chiaro che se ne metti una "particolare" (es. quel javamelody-core), la versione la devi specificare tu!

    E quindi chiedevi "Come faccio a capire quando devo usare <version>". Lo scopri (anche) "studiando" un po' di più quel spring-boot-dependencies ....

    giannino1995 ha scritto:


    Perché non si aggiunge la dipendenza tomcat con tag <scope>provided</scope>? Se sul server reale ci sarà tomcat perché caricarlo automaticamente insieme a spring-boot-starter-web?
    Ripeto innanzitutto che questo springboot-web-demo NON è stato fatto per creare un war da deployare su un "altro" server.

    Ma comunque il spring-boot-starter-web ha GIA' come dipendenza il spring-boot-starter-tomcat.

    giannino1995 ha scritto:


    Perché spring-boot-starter-jetty è segnato in rosso dall'IDEA? Come risolvo?
    In che senso lo segna in rosso? Che vuol dire? E' un errore? O un warning? Cosa ti dice esattamente? Devi PRECISARE!!!

    E comunque NON è sbagliato. Dato che spring-boot-starter-tomcat è già incluso dal spring-boot-starter-web, se si vuole usare un altro server embedded allora va dichiarata innanzitutto la "esclusione" del spring-boot-starter-tomcat per mettere poi lo starter per un altro server (es. spring-boot-starter-jetty).

    giannino1995 ha scritto:


    Come attivo il profilo jetty aggiungendo codice alla webapp?
    Lo dice chiaramente il README.md:

    mvn spring-boot:run -P jetty

    giannino1995 ha scritto:


    Perché spring-boot-starter-undertow è segnato in rosso dall'IDEA? Come risolvo?
    Idem come sopra.



    Uhhh... fatica .......
  • Re: WebMvcConfig e pom.xml poco chiari

    1) Ok, grazie.


    2) Si vero ma c'è qualcosa di poco buono anche nell'interfaccia WebMvcConfigurer oppure non capisco il discorso fino in fondo. L'autore scrive qualcosa al riguardo ma non riesco a capire bene.
    SpringMVC provides WebMvcConfigurerAdapter, which is an implementation of the WebMvcConfigurer interface. But WebMvcConfigurerAdapter is deprecated as of Spring 5.0, because WebMvcConfigurer has default method implementations and uses Java 8 default method support.
    Il pezzo che non comprendo bene è questo:
    ... WebMvcConfigurer has default method implementations and uses Java 8 default method support.
    Sembra che l'interfaccia imponga l'uso di nomi che cozzino con alcuni metodi di defualt presenti in Java 8.
    E' corretto?


    3) Ho letto ma non sono sicuro di aver capito bene la differenza tra runtime e provided.
    Da quello che leggo sembra che entrambe le dipendenze con questo scope non vengano aggiunte al .war perché già presenti sul Server o perché non utili all'applicazione una volta che viene pubblicata ma tali dipendenze vengano scaricate localmente mentre si lavora sull'IDE e quindi vengono usate solo dal programmatore.
    La dipendenza provided è una dipendenza che è già inclusa in un'altra dipendenza con scope compile mentre una dipendenza runtime è una dipendenza indipendente ovvero non transitiva.
    In pratica se non si aggiunge una dipendenza con scope provided essa viene inclusa nel .war e localmente mentre si lavora sull'IDE mentre se non si aggiunge una dipendenza con scope runtime essa non viene aggiunta da nessuna parte, nè dentro il .war e nè localmente mentre si lavora sull'IDE semplicemente perché la stessa dipendenza non è inclusa in nessun'altra dipendenza del file pom.xml ovvero non è una dipendenza transitiva.
    E' così?
    Dal titolo "Dependency Management" in giù non ho letto perché al momento non mi interessa.
    Concordi con me che sarebbe stato meglio scrivere il codice seguente nel pom.xml nel caso la webapp fosse stata un'applicazione reale? (escludere tomcad da spring-boot-starter-web)
    
    		<dependency>
    			<groupId>org.springframework.boot</groupId>
    			<artifactId>spring-boot-starter-web</artifactId>
    		</dependency>
    		<dependency>
    			<groupId>org.springframework.boot</groupId>
    			<artifactId>spring-boot-starter-tomcat</artifactId>
    			<scope>provided</scope>
    		</dependency>
    

    4) Anche sul tag optional ho qualche dubbio. Da quello che leggo sembra che una dipendenza a cui si assegna un optional pari a true è una dipendenza che è stata definita opzionale dall'autore della dipendenza ed è una dipendenza che è presente solo localmente sul IDE e non presente nel file .war e quindi non presente sul Server. Se ad una dipendenza opzionale si assegna false invece che true tale dipendenza viene aggiunta oltre che localmente anche nel file .war e quindi anche sul Server.
    E' giusto?


    5) Ok, grazie.


    6) Ok, grazie, ho risolto.


    7) Ok, grazie, ho risolto.

  • Re: WebMvcConfig e pom.xml poco chiari

    giannino1995 ha scritto:


    Il pezzo che non comprendo bene è questo:
    ... WebMvcConfigurer has default method implementations and uses Java 8 default method support.
    Sembra che l'interfaccia imponga l'uso di nomi che cozzino con alcuni metodi di defualt presenti in Java 8.
    E' corretto?
    Quello che hai appena detto non ha alcun senso!!! Hai letto almeno il javadoc di questi due tipi (WebMvcConfigurer e WebMvcConfigurerAdapter)??

    I metodi di "default" nelle interfacce (cioè che hanno un "corpo" con del codice) sono possibili SOLO da Java 8 (nuova feature). Prima di Java 8 quindi WebMvcConfigurer (la interfaccia) era solo la astrazione "pura" e basta mentre WebMvcConfigurerAdapter era/è una classe di implementazione di WebMvcConfigurer.

    Il punto è che WebMvcConfigurerAdapter ha tutti quei metodi implementati .... vuoti!! Perché? Beh, hai mai visto i listener di AWT/Swing? C'è ad esempio KeyListener (interfaccia con 3 metodi astratti) e poi c'è la classe KeyAdapter che implementa KeyListener e hai quei 3 metodi implementati VUOTI. In sostanza: se implementi direttamente KeyListener devi implementare tu tutti quei metodi. Non vuoi romperti le scatole perché magari hai bisogno solo es. del keyPressed(KeyEvent)? Allora ESTENDI la KeyAdapter e ridefinisci solo quel metodo. Gli altri restano implementati vuoti (=nessun effetto).

    Con WebMvcConfigurer/WebMvcConfigurerAdapter è la stessa cosa!!!! La interfaccia WebMvcConfigurer dichiara ben 18 metodi! In passato, in Spring Boot 1.x (< Java 8 ), per non rompersi le scatole, la cosa tipicamente sensata era ESTENDERE WebMvcConfigurerAdapter e ridefinire magari solo quei 1/2/pochi metodi che servivano.

    Con Spring Boot 2.x (minimo richiesto Java 8 ), hanno potuto mettere le implementazioni "vuote" direttamente nella interfaccia WebMvcConfigurer (sono infatti diventati tutti metodi di "default"). Quindi la classe WebMvcConfigurerAdapter è diventata sostanzialmente abbastanza superflua/poco utile. Ecco perché l'hanno anche "deprecata" (sebbene materialmente ci sia ancora). Ora non ci sono più scuse o questioni particolari ... basta usare WebMvcConfigurer in ogni caso, sia che serva 1 metodo, sia che servano tutti.

    Scusa, ma è veramente così difficile da comprendere?? Si tratta di concetti super-basilari su classi/interfacce ....

    giannino1995 ha scritto:


    3) Ho letto ma non sono sicuro di aver capito bene la differenza tra runtime e provided.
    Da quello che leggo sembra che entrambe le dipendenze con questo scope non vengano aggiunte al .war perché già presenti sul Server o perché non utili all'applicazione una volta che viene pubblicata ma tali dipendenze vengano scaricate localmente mentre si lavora sull'IDE e quindi vengono usate solo dal programmatore.
    Nooo. Una dipendenza scope "runtime" VA a finire in un war finale (e comunque tra i jar in un bundle finale).
    Lo scenario tipico d'uso: il driver JDBC di un db. Il driver JDBC non serve in compilazione (il TUO codice non dovrebbe mai importare le classi specifiche del driver, c'è la API JDBC che fa da "ponte"). Serve però ovviamente a runtime. E quindi secondo te come potrebbe funzionare se il driver non andasse a finire in un war o comunque in generale nel bundle finale??

    giannino1995 ha scritto:


    La dipendenza provided è una dipendenza che è già inclusa in un'altra dipendenza
    Noooooo. Provided vuol solo dire che verrà usata in compilazione ma NON verrà messa in war/bundle finale. Perché ci si aspetta che si una server/container/ambiente a fornire quel jar.

    Lo scenario tipico d'uso: le API delle Servlet. Ti servono in compilazione (es. se sviluppi servlet, filter ecc...) ma poi NON servono nel war perché un Servlet Container le fornisce già. Se guardi nella installazione di Tomcat, nella cartella lib/ ci trovi un servlet-api.jar. Non serve che ne metti un altro tu nel war che fornisce quella stessa API !! Quel servlet-api.jar viene già messo in classpath da Tomcat e quindi reso disponibile alle webapp.

    giannino1995 ha scritto:


    
    		<dependency>
    			<groupId>org.springframework.boot</groupId>
    			<artifactId>spring-boot-starter-web</artifactId>
    		</dependency>
    		<dependency>
    			<groupId>org.springframework.boot</groupId>
    			<artifactId>spring-boot-starter-tomcat</artifactId>
    			<scope>provided</scope>
    		</dependency>
    
    Se è una applicazione standalone (jar), NON ha senso, parte COMUNQUE con il Tomcat. Non l'hai rimosso.

    Se invece si vuole ottenere un war, la documentazione indica le modifiche (varie) da fare:
    17.1. Create a Deployable War File

    E tra queste dice di mettere <scope>provided</scope>. Quindi in questo contesto, è ok.

    giannino1995 ha scritto:


    una dipendenza a cui si assegna un optional pari a true è una dipendenza che è stata definita opzionale dall'autore della dipendenza ed è una dipendenza che è presente solo localmente sul IDE e non presente nel file .war e quindi non presente sul Server.
    L'ho già detto prima: una dipendenza con optional true NON va a finire nel bundle finale.


    P.S. non guardare i capitoli sulla parte Reactive o su Groovy/Scala/Kotlin o JHipster .... sennò ti saltano fuori 145 domande ....
  • Re: WebMvcConfig e pom.xml poco chiari

    A) Non sapevo che le interfacce potessero contenere dei metodi. L'ultimo libro che ho letto riguardava Java 1.7. Ora comunque ho capito tutto, mille grazie. Sei stato chiarissimo.


    B)
    Nooo. Una dipendenza scope "runtime" VA a finire in un war finale (e comunque tra i jar in un bundle finale). Lo scenario tipico d'uso: il driver JDBC di un db. Il driver JDBC non serve in compilazione (il TUO codice non dovrebbe mai importare le classi specifiche del driver, c'è la API JDBC che fa da "ponte"). Serve però ovviamente a runtime. E quindi secondo te come potrebbe funzionare se il driver non andasse a finire in un war o comunque in generale nel bundle finale??
    Comincio a capire i pezzi che mi mancano. L'uso di Spring Boot prevede delle conoscenze di informatica di base che non ho. E' stata dura ma ora forse ho capito la domanda che devo farti per avere il quadro del discorso. In pratica quello che io non so è il significato di “compilazione”. Non riesco a capire la differenza tra una dipendenza compilata dentro il .war ed una dipendenza non compilata dentro il .war, per me è sempre un software, un modulo, uno strumento per fare qualche cosa e che sta dentro un archivio con estensione .war. Non riesco a capire perché il driver JDBC non possa essere compilato. Non capisco il discorso dell'API JDBC che fa da ponte e forse non ho neppure ben chiaro il concetto di API.


    C)
    Se è una applicazione standalone (jar), NON ha senso, parte COMUNQUE con il Tomcat. Non l'hai rimosso.
    Se invece si vuole ottenere un war, la documentazione indica le modifiche (varie) da fare:
    17.1. Create a Deployable War File
    E tra queste dice di mettere <scope>provided</scope>. Quindi in questo contesto, è ok.
    Non capisco questa parte. Stai dicendo che i progetti che forniscono un .jar devono avere Tomcat in archivio oppure che se lo scope è su provided e l'output e un file .jar il 'provided' funziona come <scope>compile</scope> (mi ritrovo la dipendenza nel .jar)?


    D)
    L'ho già detto prima: una dipendenza con optional true NON va a finire nel bundle finale.
    Su questo punto sono d'accordo. Se però scrivo <optional>false</optional> la dipendenza finisce sul .war e quindi sul server, giusto?


    E) Accipicchia Andbin, senza di te sarebbe stato impossibile muoversi in questa ragnatela. Ok, salto i capitoli 17 e 18 (mai sentito parlare di quella roba se non da te in questo forum). Il capitolo 12 però è ancora attuale oppure posso saltare anche quello? Mi sembra di ricordare, correggimi se sbaglio, che WebFlux sia stato sostituito da Reactor. Se non ricordo male Reactor usa gli eventi e permette di sfruttare meglio le CPU moderne con tanti core.
    Chapter 10: Web Applications with Spring Boot ............................................... 107
    Chapter 11: Building REST APIs Using Spring Boot ........................................... 133
    Chapter 12: Reactive Programming Using Spring WebFlux ............................... 157
    Chapter 13: Securing Web Applications ............................................................ 175
    Chapter 14: Spring Boot Actuator ..................................................................... 197
    Chapter 15: Testing Spring Boot Applications ................................................... 221
    Chapter 16: Creating a Custom Spring Boot Starter .......................................... 247
    Chapter 17: Spring Boot with Groovy, Scala, and Kotlin .................................... 259
    Chapter 18: Introducing JHipster ...................................................................... 279
    Chapter 19: Deploying Spring Boot Applications ............................................... 289
    Gli altri capitoli invece hanno nomi famigliari, penso sia indispensabile leggerli, prima di tutto REST. L'esercitazione che vorrei fare finito il libro è un'applicazione di tipo REST che dovrebbe anche essere una delle più usate in ambito web.
  • Re: WebMvcConfig e pom.xml poco chiari

    giannino1995 ha scritto:


    A) Non sapevo che le interfacce potessero contenere dei metodi. L'ultimo libro che ho letto riguardava Java 1.7.
    Spring 5/Spring Boot 2 richiedono come minimo Java 8. E quindi tutte le nuove feature di Java 8, quali functional interfaces, default methods nelle interfacce, lambda expressions, method references, Stream API, ecc... le "dovresti" studiare e sapere .... altrimenti (detto in generale) molto avanti non ci vai ...

    giannino1995 ha scritto:


    Comincio a capire i pezzi che mi mancano. L'uso di Spring Boot prevede delle conoscenze di informatica di base che non ho. E' stata dura ma ora forse ho capito la domanda che devo farti per avere il quadro del discorso. In pratica quello che io non so è il significato di “compilazione”. Non riesco a capire la differenza tra una dipendenza compilata dentro il .war ed una dipendenza non compilata dentro il .war, per me è sempre un software, un modulo, uno strumento per fare qualche cosa e che sta dentro un archivio con estensione .war. Non riesco a capire perché il driver JDBC non possa essere compilato. Non capisco il discorso dell'API JDBC che fa da ponte e forse non ho neppure ben chiaro il concetto di API.
    Detto MOLTO in generale, una API è una "interfaccia di programmazione", ovvero tutto quello che un "modulo" (qui in senso molto ampio) è in grado di esporre all'esterno verso altri moduli.
    Tutto quello che vedi ad esempio del framework standard qui: https://docs.oracle.com/en/java/javase/14/docs/api
    è la API (come si dice, "pubblica") del framework. Poi nel framework ci sono anche classi/metodi "nascosti". Ad esempio nel package java.lang c'è una classe AbstractStringBuilder, ha il livello default ("package" level), quindi non è visibile all'esterno, la può usare solo il framework. E infatti non è nemmeno documentata nel javadoc. Ecco, questa AbstractStringBuilder non fa parte della API "pubblica" del framework.

    Su JDBC, la questione è questa. La API di JDBC sta principalmente nel package java.sql (più poco altro meno noto/usato in javax.sql). JDBC è una API principalmente "interface based", è basata su interfacce. Tutti i tipi più comuni, Connection, Statement, PreparedStatement, ResultSet, ecc.. sono interfacce. Non le devi ovviamente implementare tu. Le implementa un driver JDBC specifico!

    Se usi il Connector/J di MySQL, quando chiedi una Connection, JDBC ti fornisce un oggetto di una classe SPECIFICA dentro il jar del Connector/J ma te lo fa "vedere" solo come java.sql.Connection. Il driver può mettere la classe col nome che vuole, nel package che vuole, scritta come vuole, purché implementi e rispetti la interfaccia.
    E tu a livello di applicazione usi solo la API di JDBC, non dovresti importare cose specifiche del driver, tipo:

    import com.mysql.cj.jdbc.Blob; // NO

    Questa è la classe del Connector/J che implementa java.sql.Blob. Non serve che usi direttamente quella del driver. E questo in sostanza è il motivo per cui è prassi comune mettere la dependency di un driver JDBC con <scope>runtime</scope> .
    Quando fai il build del tuo progetto, cioè compili le TUE classi, esse non hanno riferimenti verso quelle classi specifiche, quindi in compilazione il jar del driver NON servirebbe e non verrebbe messo in classpath. Ma ovviamente serve poi a runtime e deve andare a finire in un bundle finale (es. war).

    Sarebbe anche un buon campanello di allarme. Se hai importato/usato tipi specifici del driver, il build fallisce. E allora è facile indagare .... "oh .. qualcuno ha referenziato classi del driver(?)" ...

    giannino1995 ha scritto:


    Non capisco questa parte. Stai dicendo che i progetti che forniscono un .jar devono avere Tomcat in archivio oppure che se lo scope è su provided e l'output e un file .jar il 'provided' funziona come <scope>compile</scope> (mi ritrovo la dipendenza nel .jar)?
    Stavo dicendo che se il progetto Spring Boot ha packaging jar ovvero fa una applicazione "standalone", anche se metti "provided" allo starter-tomcat, il Tomcat embedded ce l'hai lo stesso (l'avevo provato).

    EDIT: credo di aver capito il perché, mi sono ricordato di una cosa che avevo letto/visto ma verifico appena posso.

    giannino1995 ha scritto:


    Se però scrivo <optional>false</optional> la dipendenza finisce sul .war e quindi sul server, giusto?
    Sì. Comunque false è il valore predefinito di <optional>, non servirebbe esplicitarlo.

    giannino1995 ha scritto:


    Gli altri capitoli invece hanno nomi famigliari, penso sia indispensabile leggerli, prima di tutto REST. L'esercitazione che vorrei fare finito il libro è un'applicazione di tipo REST che dovrebbe anche essere una delle più usate in ambito web.
    Secondo me puoi ancora leggere il capitolo su REST e quello sulla Security. La Security in generale è "complessa", ci sono molti concetti e approcci (non li conosco tutti nemmeno io ..), quel capitolo ora non ricordo cosa spiega (poi lo rileggo ..) ma sicuramente spiega giusto qualcosa o comunque il minimo indispensabile. Solo per la Security di Spring ci sono interi libri apposta ...


    EDIT: mi stavo dimenticando un punto ..
    WebFlux NON è stato sostituito da Reactor..... Spring WebFlux USA Reactor. Reactor è lo strato appena sotto.
  • Re: WebMvcConfig e pom.xml poco chiari

    Mille grazie, tutto chiaro, procedo con il capitolo 10
Devi accedere o registrarti per scrivere nel forum
6 risposte