web-dev-qa-db-fra.com

Le navigateur ne peut pas accéder / trouver des ressources relatives telles que CSS, images et liens lors de l'appel d'un servlet qui est transféré à un JSP

Je ne parviens pas à charger les CSS et les images et à créer des liens vers d'autres pages lorsque je transmets une servlet à un fichier JSP. Plus précisément, lorsque je règle <welcome-file> Sur index.jsp, Le fichier CSS est en cours de chargement et mes images sont affichées. Toutefois, si je règle mon <welcome-file> Sur HomeServlet, qui transmet le contrôle à index.jsp, Le code CSS n'est pas appliqué et mes images ne sont pas affichées.

Mon fichier CSS est dans web/styles/default.css.
Mes images sont dans web/images/.

Je lie à mon CSS comme suit:

<link href="styles/default.css" rel="stylesheet" type="text/css" />

J'affiche mes images comme suit:

<img src="images/image1.png" alt="Image1" />

Comment ce problème est-il causé et comment puis-je le résoudre?


Mise à jour 1: J'ai ajouté la structure de l'application, ainsi que d'autres informations pouvant vous aider.

alt text

Le fichier header.jsp Est le fichier contenant la balise link pour le CSS. Le HomeServlet est défini comme mon welcome-file Dans web.xml:

<welcome-file-list>
    <welcome-file>HomeServlet</welcome-file>
</welcome-file-list>

Le servlet est déclaré et mappé comme suit dans le web.xml:

<servlet>
    <servlet-name>HomeServlet</servlet-name>
    <servlet-class>com.brianblog.frontend.HomeServlet</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>HomeServlet</servlet-name>
    <url-pattern>/</url-pattern>
</servlet-mapping>

Mise à jour 2: J'ai finalement trouvé le problème - ma servlet n'a pas été cartographiée correctement. Apparemment, lorsque vous définissez un Servlet comme votre <welcome-file>, Il ne peut pas avoir un modèle d'URL de /, Ce que je trouve un peu bizarre, car cela ne représenterait-il pas le répertoire racine du site?

La nouvelle correspondance est la suivante:

<servlet-mapping>
    <servlet-name>HomeServlet</servlet-name>
    <url-pattern>/HomeServlet</url-pattern>
</servlet-mapping>
76
Brian DiCasa

Toutes les URL relatives de la page HTML générées par le fichier JSP sont relatives à l’URL de la demande actuelle (l’URL telle que vous la voyez dans la barre d’adresse du navigateur) et non à l’emplacement du fichier JSP côté serveur, comme vous semblez l’attendre. Il s’agit du navigateur Web qui doit télécharger ces ressources individuellement par URL, et non du serveur Web qui doit les inclure à partir d’une disquette.

En plus de changer les URL relatives pour les rendre relatives à l’URL du servlet au lieu de l’emplacement du fichier JSP, une autre façon de résoudre ce problème consiste à les rendre relatives à la racine du domaine (c.-à-d. Commencez par un /). De cette façon, vous n'avez pas à vous soucier de modifier les chemins relatifs une fois de plus lorsque vous modifiez l'URL du servlet.

<head>
    <link rel="stylesheet" href="/context/css/default.css" />
    <script src="/context/js/default.js"></script>
</head>
<body>
    <img src="/context/img/logo.png" />
    <a href="/context/page.jsp">link</a>
    <form action="/context/servlet"><input type="submit" /></form>
</body>

Cependant, vous voudrez probablement ne pas coder en dur le chemin de contexte. Très raisonnable. Vous pouvez obtenir le chemin de contexte en EL par ${pageContext.request.contextPath}.

<head>
    <link rel="stylesheet" href="${pageContext.request.contextPath}/css/default.css" />
    <script src="${pageContext.request.contextPath}/js/default.js"></script>
</head>
<body>
    <img src="${pageContext.request.contextPath}/img/logo.png" />
    <a href="${pageContext.request.contextPath}/page.jsp">link</a>
    <form action="${pageContext.request.contextPath}/servlet"><input type="submit" /></form>
</body>

(qui peut facilement être raccourci de <c:set var="root" value="${pageContext.request.contextPath}" /> et utilisé comme ${root} ailleurs)

Ou, si vous n'avez pas peur de XML illisible et d'une mise en surbrillance de la syntaxe XML cassée, utilisez JSTL <c:url> :

<head>
    <link rel="stylesheet" href="<c:url value="/css/default.css" />" />
    <script src="<c:url value="/js/default.js" />"></script>
</head>
<body>
    <img src="<c:url value="/img/logo.png" />" />
    <a href="<c:url value="/page.jsp" />">link</a>
    <form action="<c:url value="/servlet" />"><input type="submit" /></form>
</body>

Quoi qu'il en soit, cela est assez fastidieux si vous avez beaucoup d'URL relatives. Pour cela, vous pouvez utiliser le <base> tag. Toutes les URL relatives deviendront instantanément relatives à celle-ci. Il doit cependant commencer par le schéma (http://, https://, etc). Il n’existe aucun moyen astucieux d’obtenir le chemin de contexte de base en plain EL, nous avons donc besoin d’un peu d’aide de JSTL ici.

<%@taglib prefix="c" uri="http://Java.Sun.com/jsp/jstl/core" %>
<%@taglib prefix="fn" uri="http://Java.Sun.com/jsp/jstl/functions" %>
<c:set var="req" value="${pageContext.request}" />
<c:set var="uri" value="${req.requestURI}" />
<c:set var="url">${req.requestURL}</c:set>
...
<head>
    <base href="${fn:substring(url, 0, fn:length(url) - fn:length(uri))}${req.contextPath}/" />
    <link rel="stylesheet" href="css/default.css" />
    <script src="js/default.js"></script>
</head>
<body>
    <img src="img/logo.png" />
    <a href="page.jsp">link</a>
    <form action="servlet"><input type="submit" /></form>
</body>

Cela a (encore) quelques mises en garde. Ancres (les #identifier _URL) deviendront également relatifs au chemin de base! Vous souhaitez plutôt le rendre relatif à l'URL de la demande (URI). Alors, change comme

<a href="#identifier">jump</a>

à

<a href="${uri}#identifier">jump</a>

Chaque voie a ses avantages et ses inconvénients. C'est à vous de choisir. Au moins, vous devriez maintenant comprendre comment ce problème est causé et comment le résoudre :)

Voir également:

96
BalusC

J'ai rencontré un problème similaire avec l'application Spring MVC. J'ai utilisé < mvc:resources > tag pour résoudre ce problème.

S'il vous plaît trouver le lien suivant ayant plus de détails.

http://www.mkyong.com/spring-mvc/spring-mvc-how-to-include-js-or-css-files-in-a-jsp-page/

6
Ashwini Patil

Vous devez analyser la sortie HTML réelle, pour le conseil.

En donnant le chemin comme cela signifie "à partir de la position actuelle", par contre si vous commencez par un / cela voudrait dire "du contexte".

2
Adeel Ansari

Si vous utilisez Spring MVC, vous devez déclarer le servlet d'action par défaut pour les contenus statiques. Ajoutez les entrées suivantes dans spring-action-servlet.xml. Cela a fonctionné pour moi.

REMARQUE: conservez tous les contenus statiques en dehors de WEB-INF.

<!-- Enable annotation-based controllers using @Controller annotations -->
<bean id="annotationUrlMapping" class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping">
    <property name="order" value="0" />
</bean>

<bean id="controllerClassNameHandlerMapping" class="org.springframework.web.servlet.mvc.support.ControllerClassNameHandlerMapping">
    <property name="order" value="1" />
</bean>

<bean id="annotationMethodHandlerAdapter" class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter"/>
0
AjayP

réponse courte - ajoute la ligne suivante dans le jsp qui définira la base
base href = "/ {racine de votre application} /"

0
Ankit Pandoh

En ce qui concerne votre mise à jour, j'ai été dérouté par le raisonnement derrière. Dug un peu plus profond et a trouvé ce petit bijou:

  • yoursite.com devient yoursite.com/
  • yoursite.com/ est un répertoire, donc la liste de fichiers de bienvenue est analysée
  • yoursite.com/CMS est le premier fichier de bienvenue ("CMS" dans la liste de fichiers de bienvenue). Un mappage de/CMS vers le servlet MyCMS permet d'accéder à ce dernier.

Source: http://wiki.metawerx.net/wiki/HowToUseAServletAsYourMainWebPage

La cartographie a donc du sens.

Et on peut maintenant utiliser librement $ {pageContext.request.contextPath}/path/as src/href pour les liens relatifs!

0
Justin Cuaresma

Votre page d'accueil est définie en tant que Ce Servlet. Donc, tous les css, le chemin des images doivent être donnés par rapport à ce servlet DIR. ce qui est une mauvaise idée! pourquoi avez-vous besoin du servlet comme page d'accueil? définir .jsp comme page d’index et rediriger vers une page à partir de là?

essayez-vous de renseigner des champs de la base de données, c’est pourquoi vous utilisez servlet?

0
GoodSp33d

Le code ci-dessous a fonctionné pour moi.

au lieu d'utiliser <% @ include file = "styles/default.css"%>

0
Chamika Ravinda