web-dev-qa-db-fra.com

Utilisation de Thymeleaf et de JSP

J'utilisais JSP + JSTL mais je m'ennuie de c: si, c: choisissez, ...

Donc, je veux que mes pages JSP soient rendues à la fois avec JSP et Thymeleaf (je prévois de supprimer tout JSTL dès que possible). J'utilise le Spring MVC framework:

<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
    <property name="prefix" value="/WEB-INF/pages/" />
    <property name="suffix" value=".jsp" />
    <property name="order" value="1" />
</bean>
<!-- Thymeleaf -->
<bean id="templateResolver" class="org.thymeleaf.templateresolver.ServletContextTemplateResolver">
    <property name="prefix" value="/WEB-INF/pages/" />
    <property name="suffix" value=".html" />
    <property name="templateMode" value="HTML5" />
</bean>
<bean id="templateEngine" class="org.thymeleaf.spring4.SpringTemplateEngine">
    <property name="templateResolver" ref="templateResolver" />
</bean>
<bean class="org.thymeleaf.spring4.view.ThymeleafViewResolver">
    <property name="templateEngine" ref="templateEngine" />
    <property name="order" value="2" />
</bean> 

Dans mon contrôleur, je retourne juste le jsp sans extension.

return "folder/page";

Mes pages JSP peuvent-elles être rendues d'abord avec le résolveur JSP, puis avec le résolveur Thymeleaf? Si oui comment?

Il semble que c’est très compliqué d’enchaîner JSP et Thymeleaf. Je souhaite donc utiliser le résolveur interne pour les fichiers JSP et le résolveur de modèles Thymeleaf pour les fichiers HTML. Comment puis-je le faire?

13
Athanor

Voici la réponse basée sur la réponse @Igd

<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
    <property name="prefix" value="/WEB-INF/pages/" />
    <property name="viewNames" value="*.jsp" />
</bean>
<!-- Thymeleaf -->
<bean id="templateResolver" class="org.thymeleaf.templateresolver.ServletContextTemplateResolver">
    <property name="prefix" value="/WEB-INF/pages/" />
    <property name="templateMode" value="HTML5" />
</bean>
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
    <property name="viewNames" value="redirect*" />
</bean>
<bean id="templateEngine" class="org.thymeleaf.spring4.SpringTemplateEngine">
    <property name="templateResolver" ref="templateResolver" />
</bean>
<bean class="org.thymeleaf.spring4.view.ThymeleafViewResolver">
    <property name="templateEngine" ref="templateEngine" />
    <property name="viewNames" value="*.html" />
</bean> 

Et j'utilise ceci pour la cartographie:

@RequestMapping("/view1")
public String thymeleafView(){
    return "mythymeleafview.html";
}

@RequestMapping("/view2")
public String jspView(){
    return "myjspview.jsp";
}
3
Athanor

Selon cet article sur le forum Thymeleaf, vous avez deux solutions.

Première solution :

Supprimez la propriété suffixe} dans votre déclaration de bean (<property name="suffix" value=".html" /> et <property name="suffix" value=".jsp" />) et transmettez le suffixe dans la valeur de retour de vos contrôleurs, par exemple. :

@RequestMapping("/view1")
public String thymeleafView(){
    return "mythymeleafview.html";
}

@RequestMapping("/view2")
public String jspView(){
    return "myjspview.html";
}

Deuxième solution :

Ajoutez la propriété viewNames aux résolveurs. La valeur est le nom d'un dossier contenant des vues dépendant de leur extension. Ainsi, vous aurez un dossier pour les fichiers JSP et un autre pour les fichiers HTML (thymeleaf), par exemple. :

Configuration

<bean id="templateResolver" class="org.thymeleaf.templateresolver.ServletContextTemplateResolver">
     <property name="prefix" value="/WEB-INF/views/" />
     <property name="suffix" value=".html" />
     <property name="viewNames" value="thymeleaf/*" />
     <property name="templateMode" value="HTML5" />
</bean>

<bean id="jspViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
     <property name="viewClass" value="org.springframework.web.servlet.view.JstlView" />
     <property name="prefix" value="/WEB-INF/views/" />
     <property name="viewNames" value="jsp/*" />
     <property name="suffix" value=".jsp" />
</bean>

Manette

@RequestMapping("/view1") 
public String thymeleafView() { 
     return "thymeleaf/mythymeleafview"; 
} 

@RequestMapping("/view2") 
public String jspView() { 
     return "jsp/myjspview"; 
}

Dossier de projet

WEB-INF/views/jsp/myjspview.jsp
WEB-INF/views/thymeleaf/mythymeleafview.jsp

Les deux solutions fonctionnent, mais ont des contraintes. Vous devez spécifier d'une manière ou d'une autre si vous souhaitez résoudre avec JSP ou Thymeleaf.

La solution "parfaite" à la chaîne JSP et à Thymeleaf - qui consisterait à tenter de résoudre la vue avec JSP quand elle ne peut pas être résolue avec Thymeleaf ou inversement - n'est pas possible et Daniel Fernández (équipe Thymeleaf) a expliqué pourquoi dans ce même message :

Thymeleaf vous permet de créer n'importe quelle implémentation d'ITemplateResolver que vous souhaitez, y compris certaines qui pourraient ne pas permettre de déterminer si le modèle existe ou non avant de l'avoir lu. [...] Il n’ya donc aucun moyen pour Thymeleaf de savoir si un modèle pourra être résolu ou non avant d’essayer de le traiter. Et c'est pourquoi ThymeleafViewResolver doit recourir à la propriété "viewNames".

15
lgd

Alternativement, deux servlets fonctionnent bien. La solution consiste à minimiser la configuration des servlets et à inclure un fichier appConfig.xml pour la base de données et d'autres services (afin d'éviter une duplication massive de la configuration).

Web.xml:

<web-app id="WebApp_ID" version="2.4"
   xmlns="http://Java.Sun.com/xml/ns/j2ee" 
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xsi:schemaLocation="http://Java.Sun.com/xml/ns/j2ee 
   http://Java.Sun.com/xml/ns/j2ee/web-app_2_4.xsd">

   <display-name>Spring MVC Application</display-name>

   <servlet>
      <servlet-name>AssessmentAdmin</servlet-name>
      <servlet-class>
         org.springframework.web.servlet.DispatcherServlet
      </servlet-class>
      <load-on-startup>1</load-on-startup>
   </servlet>
 <servlet-mapping>
      <servlet-name>AssessmentAdmin</servlet-name>
      <url-pattern>/xz/*</url-pattern>
   </servlet-mapping>
   
   
<servlet>
      <servlet-name>AssessmentAdminTL</servlet-name>
      <servlet-class>
         org.springframework.web.servlet.DispatcherServlet
      </servlet-class>
      <load-on-startup>1</load-on-startup>
   </servlet>   
   <servlet-mapping>
      <servlet-name>AssessmentAdminTL</servlet-name>
      <url-pattern>/xztl/*</url-pattern>
   </servlet-mapping>
   ........

servlet pour jsp:

<mvc:annotation-driven />
	
	<bean
		class="org.springframework.web.servlet.view.InternalResourceViewResolver">
		<property name="prefix" value="/WEB-INF/jsp/" />
		 <!--  <property name="viewNames" value="jsp/*" />-->
		  <property name="suffix" value=".jsp" />
	</bean>



	..........



	
	<import resource="applicationContext.xml" />



</beans>

servlet pour thymeleaf

<mvc:annotation-driven />
	
<!-- Thymeleaf -->

<bean id="templateResolver"
        class="org.thymeleaf.templateresolver.ServletContextTemplateResolver">
    <property name="prefix" value="/WEB-INF/html/" />
    <property name="suffix" value=".html" />
    <property name="templateMode" value="HTML5" />
    <property name="cacheable" value="false" />
  </bean>
    
  <bean id="templateEngine"
        class="org.thymeleaf.spring4.SpringTemplateEngine">
    <property name="templateResolver" ref="templateResolver" />
  </bean>
   
  <bean class="org.thymeleaf.spring4.view.ThymeleafViewResolver">
    <property name="templateEngine" ref="templateEngine" />
  </bean> 
    
 
   
  <bean class="org.thymeleaf.spring4.view.ThymeleafViewResolver">
    <property name="templateEngine" ref="templateEngine" />
  </bean> 	
  
  


	
	<import resource="applicationContext.xml" />

Essayé et ça marche bien

6
Jake

selon la réponse de @ Athanor, nous pourrions avoir un autre choix.

nous utilisons la propriété "viewNames" pour contrôler quel résolver sélectionner le modèle

<!-- jsp -->
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
    <property name="prefix" value="/" />
    <property name="suffix" value=".jsp" />
    <property name="order" value="1" />
    <property name="viewNames" value="*admin/*,*packer/*,*courier/*,/" />
</bean>
<!-- thymeleaf -->
<bean id="templateResolver" class="org.thymeleaf.templateresolver.ServletContextTemplateResolver">
    <property name="prefix" value="/" />
    <property name="suffix" value=".html" />
    <property name="templateMode" value="HTML5" />
    <property name="cacheable" value="false"/>
</bean>
<bean id="templateEngine" class="org.thymeleaf.spring3.SpringTemplateEngine">
    <property name="templateResolver" ref="templateResolver" />
</bean>
<bean class="org.thymeleaf.spring3.view.ThymeleafViewResolver">
    <property name="characterEncoding" value="UTF-8"/>
    <property name="templateEngine" ref="templateEngine" />
    <property name="viewNames" value="*thymeleaf/*" />
    <property name="order" value="2" />
</bean>

et le contrôleur

@RequestMapping(value="/test")
public ModelAndView dboxPrint(Model model){
    ModelAndView modelAndView = new ModelAndView("thymeleaf/dbox_print");

    return modelAndView;
}
0
user5606857