J'ai 2 projets. Un projet (A) contient toutes mes fonctionnalités de base telles que mes entités / services / daos etc. Il contient également de nombreux modèles .ftl dont je souhaite profiter et réutiliser dans mon autre projet (B). J'ai réussi à (B) utiliser les classes de (A) mais je n'ai pas de chance de réutiliser les modèles de freemarker.
Project (B) est une application Spring Boot (v2.1.3) et je pense donc que je J'ai raison d'utiliser l'application.property: spring.freemarker.template-loader-path
au lieu de définir un nouveau @Bean
.
Échéance être une application à démarrage à ressort, par défaut et sans cette propriété, le projet cherchera dans le propre emplacement src / main / resources / templates
du projet, mais mon objectif est que Project (A) n'ait ses propres modèles et pour que mon contrôleur renvoie les modèles trouvés dans Project (B).
Dans mes dépendances Maven, la hiérarchie est la suivante:
projectA-0.0.1.jar templates folder1 exampleA.ftl folder2 exampleB.ftl
Actuellement, mes contrôleurs sont configurés pour renvoyer des éléments tels que return new ModelAndView ("folder1 / exampleA")
où le préfixe de contexte est src / main / resources / templates /
Quelqu'un connaît-il le format correct de la valeur que je dois donner au spring.freemarker.t la propriété emplate-loader-path
pour pointer vers les modèles dans mon fichier de dépendances au lieu du src / main / resources / templates local?
4 Réponses :
Donc spring.freemarker.template-loader-path=
classpath: / templates / était la réponse à ma question initiale, mais cela n'a pas résolu mon problème.
L'ajout du @Bean
suivant à ma classe de configuration a fait, crédit à @ddekany
@Bean
public FreeMarkerConfigurationFactoryBean getFreeMarkerConfiguration () {
FreeMarkerConfigurationFactoryBean bean = nouveau FreeMarkerConfigurationFactoryBean ();
bean.setTemplateLoaderPath ("classpath: / templates /");
retourner le haricot;
}
Il semblerait que même si je pourrais utiliser une propriété, en raison d'autres facteurs, un @Bean
était nécessaire dans mon scénario.
Cela n'a pas fonctionné pour moi. Mais cette approche fonctionne:
@Bean @Primary public FreeMarkerConfigurationFactoryBean getFreeMarkerConfiguration() throws IOException { FreeMarkerConfigurationFactoryBean bean = new FreeMarkerConfigurationFactoryBean(); ClassTemplateLoader ctl = new ClassTemplateLoader(getClass(), "/templates"); bean.setPostTemplateLoaders(ctl); return bean; }
J'ai fini avec le haricot suivant. Si vous n'utilisez pas la dépendance maven spring-freeemarker-starter. J'utilisais simpleJavamail donc je n'avais pas besoin de toutes les dépendances.
@Bean("freeMarkerConfiguration") public freemarker.template.Configuration freeMarkerConfigurationFactoryBean() throws IOException { freemarker.template.Configuration freeMarkerConfiguration = new freemarker.template.Configuration(freemarker.template.Configuration.DEFAULT_INCOMPATIBLE_IMPROVEMENTS); freeMarkerConfiguration.setTemplateLoader(new ClassTemplateLoader(getClass(), "/templates")); return freeMarkerConfiguration; }
La mise en propriété:
spring.freemarker.cache=false spring.freemarker.template-loader-path=file:src/main/resources/templates/
a fonctionné pour moi.
Donc, vous utilisez
spring.freemarker.template-loader-path = classpath: / templates /
, et dans le fichier de dépendance, les modèles sont également soustemplates /
, et pourtant il ne les trouve pas? Je ne sais pas quel problème technique se pose alors ... généralement, cela devrait fonctionner.Je ne sais pas si cela fait une différence ou non, mais les
templates /
dans mon fichier de dépendances apparaissent dans mon IDE comme un package plutôt que comme un dossier typique. Mais en regardant le nom qualifié, la valeur / l'emplacement est le même que ce à quoi je m'attendais, donc je suppose que non?C'est bien s'il le montre sous forme de package, car il n'y a qu'un seul arbre dans un fichier jar, contrairement au code source qui peut suivre les conventions Maven pour séparer les choses en
java
etressources code >.
Je ne suis pas familier avec l'intégration FreeMarker de Spring, mais une chose qui peut être un problème en général lors du chargement de ressources avec
ClassLoader
-s est le choix de la classe dontClassLoader code > sera utilisé pour cela. Si Spring MVC utilise sa propre classe comme base pour cela et que le jar Spring associé est chargé à partir d'un emplacement potentiellement partagé par plusieurs applications (pas impossible si vous déployez sur un serveur d'applications "d'entreprise" sophistiqué), alors son chargeur de classe a gagné 'ne vois pas les classes et les ressources d'application.
Merci @ddekany, c'est votre dernier commentaire qui m'a amené à ma conclusion. J'ai pensé que je pourrais prendre le raccourci et utiliser la propriété
spring.freemarker.template-loader-path
en raison de l'utilisation d'une version de Spring Boot qui le prend en charge. Mais votre point sur leClassLoader
(auquel je n'aurais jamais pensé) m'a conduit à ajouter le@Bean
que j'ai ajouté à la question (pour la visibilité et la mise en forme) à ma configuration classe et faites-le fonctionner parfaitement!Pourquoi cela fonctionne-t-il? Je ne vois rien qui puisse résoudre un problème lié à
ClassLoader
. Peut-être que quelque chose remplaçait lespring.freemarker.template-loader-path
provenant deapplication.properties
, mais maintenant vous forcez à la valeur souhaitée? À propos, FreeMarker enregistre ce qu'était leTemplateLoader
quand il ne trouve pas de modèle; peut-être que cela contient un indice.J'ai supposé qu'un
@Bean
aurait plus à dire en ce qui concerne la configuration que celui de la propriétéspring.freemarker.template-loader-path
donc j'ai pensé que cela valait le coup . Peut-être y avait-il quelque chose qui l'emportait, comme vous le pensez. Je n'ai rien vu dans aucun de mes journaux concernantTemplateLoader
donc malheureusement je n'ai aucun indice à partager pour le moment.Vous devez certainement définir la catégorie de journal
freemarker
surDEBUG
dans votre configuration de journalisation pour cela.