web-dev-qa-db-fra.com

Comment servir des fichiers .html avec Spring

Je développe un site Web avec Spring et j'essaie de servir des ressources qui ne sont pas des fichiers .jsp (.html par exemple)

en ce moment, j'ai commenté cette partie de la configuration de mon servlet

    <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver" 
        p:prefix="/WEB-INF/jsp/" p:suffix=".jsp" />

Et essayé de retourner du contrôleur le chemin complet à la ressource.

@Controller
public class LandingPageController {

protected static Logger logger = Logger.getLogger(LandingPageController.class);

@RequestMapping({"/","/home"})
public String showHomePage(Map<String, Object> model) {
    return "/WEB-INF/jsp/index.html";   
   }
}

le fichier index.html existe dans ce dossier.

REMARQUE: lorsque je remplace index.html par index.jsp, mon serveur affiche désormais correctement la page.

Je vous remercie.

65
Gleeb

Le problème initial est que la configuration spécifie une propriété suffix=".jsp". Par conséquent, la classe d'implémentation ViewResolver ajoutera .jsp à la fin du nom de la vue renvoyée par votre méthode.

Cependant, étant donné que vous avez commenté la variable InternalResourceViewResolver, il se peut que, en fonction du reste de la configuration de votre application, aucun autre ViewResolver ne soit enregistré. Vous constaterez peut-être que rien ne fonctionne maintenant.

Puisque les fichiers .html sont static et ne nécessitent pas de traitement par un servlet, il est donc plus efficace et plus simple d’utiliser un <mvc:resources/> mappage . Cela nécessite Spring 3.0.4+.

Par exemple:

<mvc:resources mapping="/static/**" location="/static/" />

ce qui transmettrait toutes les demandes commençant par /static/ au répertoire webapp/static/.

Donc, en mettant index.html dans webapp/static/ et en utilisant return "static/index.html"; à partir de votre méthode, Spring devrait trouver la vue.

95
andyb

J'ajouterais simplement que vous n'avez pas besoin d'implémenter une méthode de contrôleur pour cela car vous pouvez utiliser le tag view-controller / (Spring 3) dans le fichier de configuration du servlet:

<mvc:view-controller path="/" view-name="/WEB-INF/jsp/index.html"/>
8
Ivan

Contexte du problème 

La première chose à comprendre est la suivante: ce n’est PAS Spring qui rend les fichiers jsp. C'est JspServlet (org.Apache.jasper.servlet.JspServlet) qui le fait. Cette servlet est fournie avec Tomcat (compilateur jasper) et non avec un ressort. Ce JspServlet sait comment compiler une page jsp et comment le renvoyer sous forme de texte html au client. JspServlet dans Tomcat par défaut ne traite que les demandes correspondant à deux modèles: * .jsp et * .jspx.

Maintenant, lorsque le printemps rend la vue avec InternalResourceView (ou JstlView), trois choses se produisent réellement:

  1. obtenir tous les paramètres de modèle à partir de modèle (renvoyés par votre méthode de gestionnaire de contrôleur, à savoir "public ModelAndView doSomething() { return new ModelAndView("home") }")
  2. exposer ces paramètres de modèle en tant qu'attributs de requête (pour que JspServlet puisse les lire)
  3. transmettre la demande à JspServlet. RequestDispatcher sait que chaque demande * .jsp doit être transmise à JspServlet (car il s'agit de la configuration par défaut de Tomcat)

Lorsque vous changez simplement le nom de la vue en home.html, Tomcat ne sait pas comment gérer la demande. En effet, il n'y a pas de requêtes de traitement de servlets * .html.

Solution

Comment résoudre ce problème Il y a trois solutions les plus évidentes:

  1. exposer le code HTML en tant que fichier de ressources 
  2. ordonne à JspServlet de gérer également les requêtes * .html
  3. écrivez votre propre servlet (ou passez à une autre requête de servlet existante à * .html). 

Pour obtenir des exemples de code complets, reportez-vous à ma réponse dans un autre article: Comment mapper les demandes au fichier HTML dans Spring MVC?

8
walkeros

Vous pouvez toujours continuer à utiliser le même résolveur de vues, mais définissez le suffixe sur vide. 

<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver" 
    p:prefix="/WEB-INF/jsp/" p:suffix="" />

Votre code peut maintenant choisir de renvoyer index.html ou index.jsp, comme indiqué dans l'exemple ci-dessous 

@RequestMapping(value="jsp", method = RequestMethod.GET )
public String startJsp(){
    return "/test.jsp";
}

@RequestMapping(value="html", method = RequestMethod.GET )
public String startHtml(){
    return "/test.html";
}   
7
Sashi

Configuration Java pour les fichiers HTML (dans ce cas, index.html):

@Configuration
@EnableWebMvc
public class DispatcherConfig extends WebMvcConfigurerAdapter {

    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {

        registry.addResourceHandler("/index.html").addResourceLocations("/index.html");
    }

}
1
zygimantus

J'ai fait face au même problème et j'ai essayé diverses solutions pour charger le code HTML page de Spring MVC, la solution suivante a fonctionné pour moi

La première étape du web.xml du serveur commente ces deux lignes

<!--     <mime-mapping>
        <extension>htm</extension>
        <mime-type>text/html</mime-type>
    </mime-mapping>--> 
<!--     <mime-mapping>
        <extension>html</extension>
        <mime-type>text/html</mime-type>
    </mime-mapping>
 -->

Étape 2 entrez le code suivant dans l'application Web xml

  <servlet-mapping>
    <servlet-name>jsp</servlet-name>
    <url-pattern>*.htm</url-pattern>
</servlet-mapping>

Étape 3 créer une classe de contrôleur statique 

@Controller 
public class FrontController {
     @RequestMapping("/landingPage") 
    public String getIndexPage() { 
    return "CompanyInfo"; 

    }

}

Étape 4 du fichier de configuration Spring, remplacez le suffixe par .htm .htm

Étape 5: Renommez la page en tant que fichier .htm, enregistrez-la dans WEB-INF et construisez/démarrez le serveur. 

localhost:8080/.../landingPage
1
Animesh

changez la valeur p: suffix = ". jsp", sinon nous pouvons développer un résolveur de vue personnalisé 

http://static.springsource.org/spring/docs/3.1.x/javadoc-api/org/springframework/web/servlet/view/UrlBasedViewResolver.html

0
AnilHoney

On dirait que vous essayez de faire quelque chose comme ça:

  • Vues HTML statiques
  • Contrôleurs à ressort desservant AJAX 

Si tel est le cas, comme indiqué précédemment, le moyen le plus efficace consiste à laisser le serveur Web (et non pas Spring) gérer les demandes HTML sous forme de ressources statiques. Donc, vous voudrez ce qui suit:

  1. Transférez toutes les demandes .html, .css, .js, .png, etc. au gestionnaire de ressources du serveur Web
  2. Mapper toutes les autres demandes aux contrôleurs Spring

Voici un moyen d'accomplir cela ...

web.xml - Mappe le servlet sur la racine (/)

<servlet>
            <servlet-name>sprung</servlet-name>
            <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
            ...
<servlet>

<servlet-mapping>
            <servlet-name>sprung</servlet-name>
            <url-pattern>/</url-pattern>
</servlet-mapping>

Spring JavaConfig

public class SpringSprungConfig extends DelegatingWebMvcConfiguration {

    // Delegate resource requests to default servlet
    @Bean
    protected DefaultServletHttpRequestHandler defaultServletHttpRequestHandler() {
        DefaultServletHttpRequestHandler dsrh = new DefaultServletHttpRequestHandler();
        return dsrh;
    }

    //map static resources by extension
    @Bean
    public SimpleUrlHandlerMapping resourceServletMapping() {
        SimpleUrlHandlerMapping mapping = new SimpleUrlHandlerMapping();

        //make sure static resources are mapped first since we are using
        //a slightly different approach
        mapping.setOrder(0);
        Properties urlProperties = new Properties();
        urlProperties.put("/**/*.css", "defaultServletHttpRequestHandler");
        urlProperties.put("/**/*.js", "defaultServletHttpRequestHandler");
        urlProperties.put("/**/*.png", "defaultServletHttpRequestHandler");
        urlProperties.put("/**/*.html", "defaultServletHttpRequestHandler");
        urlProperties.put("/**/*.woff", "defaultServletHttpRequestHandler");
        urlProperties.put("/**/*.ico", "defaultServletHttpRequestHandler");
        mapping.setMappings(urlProperties);
        return mapping;
    }

    @Override
    @Bean
    public RequestMappingHandlerMapping requestMappingHandlerMapping() {
        RequestMappingHandlerMapping handlerMapping = super.requestMappingHandlerMapping();

        //controller mappings must be evaluated after the static resource requests
        handlerMapping.setOrder(1);
        handlerMapping.setInterceptors(this.getInterceptors());
        handlerMapping.setPathMatcher(this.getPathMatchConfigurer().getPathMatcher());
        handlerMapping.setRemoveSemicolonContent(false);
        handlerMapping.setUseSuffixPatternMatch(false);
        //set other options here
        return handlerMapping;
    }
}

Considérations supplémentaires

  • Hide .html extension - Cela sort du cadre de Spring si vous déléguez les demandes de ressources statiques. Rechercher dans un filtre de réécriture d'URL.
  • Templating - Vous ne voulez pas dupliquer le balisage dans chaque page HTML pour les éléments communs. Cela ne peut probablement pas être fait sur le serveur si HTML est utilisé comme ressource statique. Rechercher dans un cadre VC * côté client. Je suis fan de YUI, qui possède de nombreux mécanismes de gabarit, dont le guidon.
0
Stoney