web-dev-qa-db-fra.com

Comment puis-je mapper un servlet "racine" pour que les autres scripts soient toujours exécutables?

J'essaie de créer un servlet qui appelle une page JSP similaire à la suivante:

public void doGet(HttpServletRequest req, HttpServletResponse resp)
        throws IOException, ServletException {
    req.getRequestDispatcher("/WEB-INF/main.jsp").forward(req, resp);
}

J'ai besoin de ce servlet pour répondre à la racine du domaine (par exemple: http://example.com/ ) donc j'utilise le mappage suivant dans le web.xml:

<servlet-mapping>
    <servlet-name>MainServlet</servlet-name>
    <url-pattern>/*</url-pattern>
</servlet-mapping>

Le problème que j'ai est que cela correspond à TOUT, donc lorsque le répartiteur transmet à "/WEB-INF/main.jsp" cela correspond au modèle d'URL afin que le servlet soit à nouveau exécuté. Il en résulte une boucle qui s'exécute jusqu'à sa mort avec un Java.lang.StackOverflowError .

Comment puis-je faire correspondre la racine sans empêcher l'exécution d'autres scripts?

53
Jeremy Logan

Utilisez un motif vide, par ex.

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

La spécification servlet 3.0 a clarifié ceci:

La chaîne vide ("") est un modèle d'URL spécial qui correspond exactement à la racine de contexte de l'application

Donc, cela devrait au moins fonctionner sur un conteneur 3.0, et j'ai vérifié que cela fonctionne sur Jetty 8

46
nilskp

L'utilisation de l'élément de fichier de bienvenue de web.xml a fonctionné pour moi, sur le moteur d'application. Voici la mienne:

<web-app>
    <servlet>
        <servlet-name>RootServlet</servlet-name>
        <servlet-class>com.foo.RootServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>RootServlet</servlet-name>
        <url-pattern>/foo</url-pattern>
    </servlet-mapping>
    <welcome-file-list>
        <welcome-file>foo</welcome-file>
    </welcome-file-list>
</web-app>
29
Jeb

La question d'origine ne mentionne pas qu'ils essaient de mapper un servlet racine sur App Engine - c'est facile sur Tomcat (et d'autres conteneurs de servlet pour autant que je sache), mais App Engine n'est pas un conteneur de servlet normal.

Ma façon normale de créer une application Web avec des servlets est d'étendre HttpServlet, d'ajouter un objet "page" avec le titre, le contenu, les erreurs, les messages, etc. et de les transmettre vers un modèle JSP. Cela a été un véritable cauchemar de travailler dans App Engine.

  • Les fichiers JSP ne peuvent pas être "nommés" sans un "/" au début.
  • Les fichiers JSP ne peuvent pas être dans un sous-répertoire
  • Les servlets ne peuvent pas être mappés à la racine de votre application avec un modèle d'URL "/"

Voici mon web.xml (édité par souci de concision) qui a finalement fonctionné.

<web-app>
  <servlet>
    <!-- this servlet needs to redirect to a NamedDispatcher
         called "template" -->
    <servlet-name>Home</servlet-name>
    <servlet-class>my.domain.HomeSv</servlet-class>
  </servlet>
  <servlet>
    <!-- jsp file must apparently be in root directory and have "/" at
         start of path -->
    <servlet-name>template</servlet-name>
    <jsp-file>/template.jsp</jsp-file>
  </servlet>
  <servlet-mapping>
    <!-- map your home servlet to somewhere other than "/" -->
    <servlet-name>Home</servlet-name>
    <url-pattern>/home</url-pattern>
  </servlet-mapping>
  <welcome-file-list>
    <!-- make your Home servlet the welcome file -->
    <welcome-file>home</welcome-file>
  </welcome-file-list>
</web-app>

Je n'ai pas été particulièrement scientifique sur la validation de tout cela - mais cela semble fonctionner pour moi maintenant et j'en suis assez content.

7
Sam Lowry

Vous pouvez créer un fichier de bienvenue nommé index.jsp à la racine avec le code suivant à l'aide de JSTL ou autrement.

<c:redirect url="/main"/>

Donc, dans le fichier web.xml, vous aurez ceci:

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

Ainsi, toute personne demandant la racine sera redirigée vers/main. Maintenant, votre servlet peut être mappé sur main.

<servlet-mapping>
    <servlet-name>MainServlet</servlet-name>
    <url-pattern>/main</url-pattern>
</servlet-mapping>
4
Vincent Ramdhanie

Essayez simplement de supprimer '*' du motif, c'est-à-dire.

<url-pattern>/</url-pattern>
1
Gennady Shumakher

Une solution est mentionnée dans un autre thread Modèle d'URL pour le mappage de servlet dans web.xml en utilisant URLrewrite -> http://tuckey.org/urlrewrite/

1
Tomasz

Avez-vous essayé ce qui suit? (Notez le *, qui est un caractère générique et est la raison pour laquelle votre configuration capture tout.)

<servlet-mapping>
        <servlet-name>MainServlet</servlet-name>
        <url-pattern>/index.jsp</url-pattern>
</servlet-mapping>

(Modifié selon les commentaires de seulement /.)

0
Stu Thompson

Vous ne pouvez pas rediriger vers WEB-INF. Un conteneur de servlet ne servira jamais les demandes de documents dans ce dossier.

Si vous souhaitez que votre application (pas seulement un servlet, mais l’application entière) soit disponible sous le contexte racine ("/" de " http://www.domainname.com/ "), alors vous devez lui configurer une entrée de contexte - pas un mappage de servlet.

Avec Tomcat, vous ajoutez un nouveau <Context> mapping (dans l'un des 3 endroits différents possibles).

0
matt b