Comment utiliser un filtre de servlet en Java pour modifier une URL de demande de servlet entrante?

186

Comment puis-je utiliser un filtre de servlet pour modifier l'URL d'une demande de servlet entrante

http://nm-java.appspot.com/Check_License/Dir_My_App/Dir_ABC/My_Obj_123

à

http://nm-java.appspot.com/Check_License?Contact_Id=My_Obj_123

?


Mise à jour : selon les étapes de BalusC ci-dessous, j'ai trouvé le code suivant:

public class UrlRewriteFilter implements Filter {

    @Override
    public void init(FilterConfig config) throws ServletException {
        //
    }

    @Override
    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws ServletException, IOException {
        HttpServletRequest request = (HttpServletRequest) req;
        String requestURI = request.getRequestURI();

        if (requestURI.startsWith("/Check_License/Dir_My_App/")) {
            String toReplace = requestURI.substring(requestURI.indexOf("/Dir_My_App"), requestURI.lastIndexOf("/") + 1);
            String newURI = requestURI.replace(toReplace, "?Contact_Id=");
            req.getRequestDispatcher(newURI).forward(req, res);
        } else {
            chain.doFilter(req, res);
        }
    }

    @Override
    public void destroy() {
        //
    }
}

L'entrée correspondante web.xmlressemble à ceci:

<filter>
    <filter-name>urlRewriteFilter</filter-name>
    <filter-class>com.example.UrlRewriteFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>urlRewriteFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

J'ai essayé la redirection côté serveur et côté client avec les résultats attendus. Cela a fonctionné, merci BalusC!

Franc
la source
Question connexe: stackoverflow.com/questions/2723829/…
BalusC
Quelle version de la spécification de servlet utilisez-vous? La façon dont vous transmettez les demandes change avec les différentes versions.
Romain Hippeau
Voir cet article il a aussi un filtre qui fait ce que vous voulez
Romain Hippeau
Veuillez noter que si votre URL d'origine contient des paramètres, c.-à- d . Nm-java.appspot.com/Check_License/Dir_My_App/Dir_ABC/My_Obj_123 ? ** param1 = A & param2 = B **, ces paramètres seront également transmis au servlet / jsp suivant. Je n'ai pas trouvé de moyen de supprimer ou de remplacer les paramètres d'origine (uniquement en utilisant HttpServletRequestWrapper). Des idées? .. Mise à jour: il semble que http://ocpsoft.org/opensource/how-to-safely-add-modify-servlet-request-parameter-values/ résout ce problème.
Lopotun
Merci Je cherchais un exemple sur la réécriture et le cryptage d'url.
Aditya Yada

Réponses:

281
  1. Mettre en œuvre javax.servlet.Filter.
  2. Dans la doFilter()méthode, transtypez le fichier entrant ServletRequestvers HttpServletRequest.
  3. Utilisez HttpServletRequest#getRequestURI()pour saisir le chemin.
  4. Utilisez simples java.lang.Stringméthodes comme substring(), split(), concat()et ainsi de suite pour extraire la partie d'intérêt et de composer le nouveau chemin.
  5. Utilisez soit ServletRequest#getRequestDispatcher()et puis RequestDispatcher#forward()pour transférer la demande / réponse vers la nouvelle URL (redirection côté serveur, non reflétée dans la barre d'adresse du navigateur), ou caster le message entrant ServletResponsevers HttpServletResponse, puis HttpServletResponse#sendRedirect()rediriger la réponse vers la nouvelle URL (redirection côté client, reflétée dans barre d'adresse du navigateur).
  6. Enregistrez le filtre web.xmlsur un url-patterndes /*ou /Check_License/*, selon le chemin de contexte, ou si vous êtes sur Servlet 3.0 déjà, utilisez l' @WebFilterannotation pour cette place.

Ne pas oublier d'ajouter un chèque dans le code si l'URL besoins à changer et si non , alors il suffit d' appeler FilterChain#doFilter(), sinon il va s'appeler dans une boucle infinie.

Vous pouvez également simplement utiliser une API tierce existante pour faire tout le travail à votre place, telle que UrlRewriteFilter de Tuckey qui peut être configuré comme vous le feriez avec Apache mod_rewrite.

BalusC
la source
1
Un exemple de code doFilter () quelque part qui fait ce qui précède? Merci.
Frank
20
À quelle étape êtes-vous exactement coincé? Ma réponse écrit presque le code lui-même. Avez-vous également noté que les références de code en bleu sont en fait des liens vers des Javadocs qui décrivent en détail le comportement de la classe / méthode? Dans tous les cas, vous pouvez trouver ici et ici de bons tutoriels JSP / Servlet, en particulier celui- ci sur les filtres.
BalusC
1
Je suppose que c'est correct, mais si le filtre est l'un des premiers de la chaîne et qu'il RequestDispatcher#forward()est exécuté, le reste des filtres ne sera pas exécuté. Alors, ne sera-t-il pas un meilleur moyen de faire cela en tant que servlet?
lucasvc
2
@datakey: réorganisez simplement l'ordre ou ajoutez <dispatcher>FORWARD</dispatcher>au mappage de filtre.
BalusC
1
@ JimJim2000: réorganisez simplement l'ordre ou ajoutez <dispatcher>FORWARD</dispatcher>au mappage de filtre.
BalusC
21

Vous pouvez utiliser le filtre de réécriture d'URL prêt à l'emploi avec une règle comme celle-ci:

<rule>
  <from>^/Check_License/Dir_My_App/Dir_ABC/My_Obj_([0-9]+)$</from>
  <to>/Check_License?Contact_Id=My_Obj_$1</to>
</rule>

Consultez les exemples pour plus ... d'exemples.

Pascal Thivent
la source
7

Un simple filtre JSF Url Prettyfier basé sur les étapes de la réponse de BalusC . Le filtre transfère toutes les requêtes commençant par le chemin / ui (en supposant que vous avez tous vos fichiers xhtml stockés ici) vers le même chemin, mais en ajoutant le suffixe xhtml.

public class UrlPrettyfierFilter implements Filter {

    private static final String JSF_VIEW_ROOT_PATH = "/ui";

    private static final String JSF_VIEW_SUFFIX = ".xhtml";

    @Override
    public void destroy() {

    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {
        HttpServletRequest httpServletRequest = ((HttpServletRequest) request);
        String requestURI = httpServletRequest.getRequestURI();
        //Only process the paths starting with /ui, so as other requests get unprocessed. 
        //You can register the filter itself for /ui/* only, too
        if (requestURI.startsWith(JSF_VIEW_ROOT_PATH) 
                && !requestURI.contains(JSF_VIEW_SUFFIX)) {
            request.getRequestDispatcher(requestURI.concat(JSF_VIEW_SUFFIX))
                .forward(request,response);
        } else {
            chain.doFilter(httpServletRequest, response);
        }
    }

    @Override
    public void init(FilterConfig arg0) throws ServletException {

    }

}
Motard Xtreme
la source