web-dev-qa-db-fra.com

Comment mapper les demandes au fichier HTML dans Spring MVC?

Les fichiers de configuration de base ne semblent pas intuitifs. 

Si je crée un exemple simple, hello world, puis renomme home.jsp en home.html et édite le fichier servlet-context.xml à partir de

<beans:bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
    <beans:property name="prefix" value="/WEB-INF/views/" />
    <beans:property name="suffix" value=".jsp" />
</beans:bean> 

à 

<beans:bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
    <beans:property name="prefix" value="/WEB-INF/views/" />
    <beans:property name="suffix" value=".html" />
</beans:bean>

Je commence à avoir une erreur

WARN : org.springframework.web.servlet.PageNotFound - No mapping found for HTTP request with URI [/myapp/WEB-INF/views/home.html] in DispatcherServlet with name 'appServlet'

Pourquoi? Qu'est-ce que la propriété suffix signifie?

METTRE &AGRAVE; JOUR

Mon contrôleur est suit. Comme vous le voyez, il ne contient pas d'extension de fichier

@Controller
public class HomeController {

    private static final Logger logger = LoggerFactory.getLogger(HomeController.class);

    /**
     * Simply selects the home view to render by returning its name.
     */
    @RequestMapping(value = "/", method = RequestMethod.GET)
    public String home(Locale locale, Model model) {
        logger.info("Welcome home! The client locale is {}.", locale);

        Date date = new Date();
        DateFormat dateFormat = DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.LONG, locale);

        String formattedDate = dateFormat.format(date);

        model.addAttribute("serverTime", formattedDate );

        return "home";
    }

}
24
Suzan Cioc

La classe résolveur est utilisée pour résoudre les ressources d'une classe d'affichage, classe à son tour, génère les vues à partir des ressources. Par exemple, avec un InternalResourceViewResolver typique comme ci-dessous:

<beans:bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <beans:property name="prefix" value="/WEB-INF/views/" />
        <beans:property name="suffix" value=".jsp" />
</beans:bean>

Un nom de vue "home" sera mappé en tant que "/WEB-INT/views/home.jsp" puis traduit en vue JSP à l'aide de la classe d'affichage InternalResourceView (qui est pour JSP). Si vous remplacez la valeur de suffixe par ".html", Spring peut obtenir la ressource spécifique "/WEB-INT/views/home.html" mais ne sait pas comment la générer.

5
Megan Nguyen

Les fichiers .html simples sont statiques et ne nécessitent pas de ViewResolver spécial. Vous devriez configurer un dossier statique pour vos pages html comme indiqué ici .

Par exemple:

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

eh bien, il semble que vous n'avez pas défini l'ordre de la vue.

par exemple, si votre projet a une vue comme jsp, json, vélocité, freemarker, etc., vous pouvez toutes les utiliser (peut-être avez-vous besoin d'une nouvelle version de spring, 3.1+), mais une seule vue sera sélectionnée pour le rendu au client, cela dépend de la commande de votre vue, plus la commande est basse, plus la vue est préférée.

par exemple, vous définissez la commande jsp view sur 1, et celle de la vue freemarker sur 2, leur nom de vue est "home", le ressort choisira view.jsp (si vous définissez le suffixe sur. jsp). Eh bien, si votre nom de vue est "index", pas index.jsp mais index.ftl (supposons que vous définissiez la vue de freemarker sur .ftl), spring choisira le plus tard.

l 'exemple de code utilisant la configuration Java de spring, vous pouvez facilement convertir en style XML.

@Bean
public InternalResourceViewResolver jspViewResolver() {
    InternalResourceViewResolver jsp = new InternalResourceViewResolver();
    jsp.setOrder(4);
    jsp.setCache(true);
    jsp.setViewClass(org.springframework.web.servlet.view.JstlView.class);
    jsp.setPrefix("/WEB-INF/jsp/");
    jsp.setSuffix(".jsp");
    return jsp;
}

@Bean
public FreeMarkerViewResolver freeMarkerViewResolver() {
    FreeMarkerViewResolver viewResolver = new FreeMarkerViewResolver();
    viewResolver.setCache(true);
    viewResolver.setPrefix("");
    viewResolver.setSuffix(".ftl");
    viewResolver.setContentType(ViewConstants.MEDIA_TYPE_HTML);
    viewResolver.setRequestContextAttribute("request");
    viewResolver.setExposeSpringMacroHelpers(true);
    viewResolver.setExposeRequestAttributes(true);
    viewResolver.setExposeSessionAttributes(true);
    viewResolver.setOrder(2);
    return viewResolver;
}

veuillez voir la méthode setOrder ()!

les vues json, jsonp et autres types de vues peuvent utiliser ontentNegotiation, et vous pouvez le trouver sur la documentation de spring.

enfin, la vue html, je veux dire, fichiers totalement statiques, qui ne sont pas pris en charge par spring default. Je suppose que le fichier statique n’a pas besoin d’être rendu par Java. vous pouvez utiliser le mappage statique en utilisant le code ci-dessous:

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

ou utilisez Java config:

@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
    int cachePeriod = 3600 * 24 * 15;
    registry.addResourceHandler("/static/**").addResourceLocations("/static/").setCachePeriod(cachePeriod);
    registry.addResourceHandler("/favicon.ico").addResourceLocations("/").setCachePeriod(cachePeriod);
    registry.addResourceHandler("/robots.txt").addResourceLocations("/").setCachePeriod(cachePeriod);
}

et dans votre méthode @RequestMapping, vous devriez redirect it!

eh bien, si vous ne voulez pas de redirection, définissez simplement la vue html sur une vue dynamic (freemark, velecity, etc.), ce qui ira!

espérons que cela soit utile!

2
longkai

Spring MVC ne vous permet pas de restituer des ressources statiques sur des contrôleurs. Comme Arun l'a dit, il devrait être servi par resources

Corrigez-moi si je me trompe, mais il semble que vous souhaitiez un index.html comme page de couverture. Pour cela, vous devez avoir un contrôleur (par exemple, IndexController) mappé sur /index.html. Ensuite, vous devriez configurer dans votre web.xml votre votre dire que votre fichier de bienvenue est index.html. Ainsi, chaque fois que vous pointez sur la racine de votre application, votre conteneur recherchera un "/index.html" et, à son tour, recherchera le contrôleur mappé sur l'URL /index.html.

Donc, votre contrôleur devrait ressembler à quelque chose comme ça:

@Controller
@RequestMapping("/index.html")
public class MyIndexController {
    @RequestMapping(method=RequestMethod.GET)
    protected String gotoIndex(Model model) throws Exception {      
        return "myLandingPage";
    }
}

Et dans votre web.xml

<welcome-file-list>
<welcome-file>index.html</welcome-file>
</welcome-file-list>

J'espère que cela t'aides.

1
gnc

Je pense que le InternalResourceViewResolver supporte les servlets et les fichiers jsp. Suffixe selon les API de Spring, javadocs est celui qui "est ajouté pour afficher les noms lors de la création d'une URL". Ce n'est pas l'extension du fichier, même si c'est très trompeur. J'ai vérifié la classe UrlBasedViewResolver setSuffix ()

Probablement que s'ils l'appellent viewSuffix, cela aurait plus de sens, je suppose.

0
Indu Devanath

Vous avez ce problème car il se peut qu'aucun servlet ne soit enregistré pour le mappage * .html .
donc l'appel se termine avec le "servlet par défaut", qui est enregistré avec un mappage de servlet de/qui est probablement votre DispatcherServlet.
Maintenant, le servlet Dispatcher ne trouve pas de contrôleur pour gérer la demande de home.html et donc le message que vous voyez .
Pour résoudre ce problème, vous pouvez enregistrer l’extension * .html qui sera gérée par JSPServlet. Elle fonctionnera ensuite proprement. 

0
Renganathan V