2
votes

Comment pointer spring.freemarker.template-loader-path vers les modèles dans un fichier jar de dépendances?

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?


8 commentaires

Donc, vous utilisez spring.freemarker.template-loader-path = classpath: / templates / ‌, et dans le fichier de dépendance, les modèles sont également sous templates / , 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 et ressources .


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 dont ClassLoader 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 le ClassLoader (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 le spring.freemarker.template-loader-path provenant de application.properties , mais maintenant vous forcez à la valeur souhaitée? À propos, FreeMarker enregistre ce qu'était le TemplateLoader 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 concernant TemplateLoader donc malheureusement je n'ai aucun indice à partager pour le moment.


Vous devez certainement définir la catégorie de journal freemarker sur DEBUG dans votre configuration de journalisation pour cela.


4 Réponses :


4
votes

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.


0 commentaires

0
votes

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;
    }


0 commentaires

0
votes

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;
}


0 commentaires

0
votes

La mise en propriété:

spring.freemarker.cache=false
spring.freemarker.template-loader-path=file:src/main/resources/templates/

a fonctionné pour moi.


0 commentaires