Wie verwende ich einen Servlet-Filter in Java, um eine eingehende Servlet-Anforderungs-URL zu ändern?

186

Wie kann ich einen Servlet-Filter verwenden, um eine eingehende Servlet-Anforderungs-URL von zu ändern?

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

zu

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

?


Update : Gemäß den folgenden Schritten von BalusC habe ich den folgenden Code gefunden:

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() {
        //
    }
}

Der relevante Eintrag in web.xmlsieht folgendermaßen aus:

<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>

Ich habe sowohl die serverseitige als auch die clientseitige Umleitung mit den erwarteten Ergebnissen versucht. Es hat funktioniert, danke BalusC!

Frank
quelle
Verwandte Frage: stackoverflow.com/questions/2723829/…
BalusC
Welche Version der Servlet-Spezifikation verwenden Sie? Wie Sie Anfragen weiterleiten, ändert sich mit den verschiedenen Versionen.
Romain Hippeau
Siehe diesen Beitrag es hat auch einen Filter, der macht, was Sie wollen
Romain Hippeau
Bitte beachten Sie, dass wenn Ihre ursprüngliche URL Parameter enthält, z. B. nm-java.appspot.com/Check_License/Dir_My_App/Dir_ABC/My_Obj_123 ? ** param1 = A & param2 = B **, diese Parameter auch an das nächste Servlet / jsp weitergeleitet werden. Ich habe keine Möglichkeit gefunden, die ursprünglichen Parameter zu entfernen oder zu ersetzen (nur mithilfe von HttpServletRequestWrapper). Irgendwelche Ideen? .. Update: Es scheint, dass http://ocpsoft.org/opensource/how-to-safely-add-modify-servlet-request-parameter-values/ dieses Problem behebt .
Lopotun
Vielen Dank, ich habe nach einem Beispiel für das Umschreiben und Verschlüsseln von URLs gesucht.
Aditya Yada

Antworten:

281
  1. Implementieren javax.servlet.Filter.
  2. In doFilter()Methode wandeln Sie den eingehenden ServletRequestin HttpServletRequest.
  3. Verwenden Sie HttpServletRequest#getRequestURI(), um den Pfad zu ergreifen.
  4. Verwenden Sie einfache java.lang.StringMethoden wie substring(), split(), concat()und so weiter , den Teil von Interesse zu extrahieren und den neuen Pfad zu komponieren.
  5. Verwenden Sie entweder ServletRequest#getRequestDispatcher()und dann RequestDispatcher#forward(), um die Anforderung / Antwort an die neue URL weiterzuleiten (serverseitige Umleitung, die nicht in der Adressleiste des Browsers angezeigt wird), oder wandeln Sie die eingehende Weiterleitung ServletResponsean HttpServletResponseund HttpServletResponse#sendRedirect()leiten Sie die Antwort an die neue URL um (clientseitige Umleitung, reflektiert in) Adressleiste des Browsers).
  6. Registrieren Sie den Filter in web.xmleinem url-patternvon /*oder /Check_License/*, abhängig vom Kontextpfad, oder verwenden Sie @WebFilterstattdessen die Annotation , wenn Sie bereits Servlet 3.0 verwenden.

Vergessen Sie nicht , einen Scheck im Code hinzufügen , wenn die URL Bedarf geändert werden , und wenn nicht , dann rufen Sie einfach an FilterChain#doFilter(), sonst wird es nennt sich in einer Endlosschleife.

Alternativ können Sie auch einfach eine vorhandene API eines Drittanbieters verwenden, um die gesamte Arbeit für Sie zu erledigen, z. B. UrlRewriteFilter von Tuckey , der wie bei Apache konfiguriert werden kann mod_rewrite.

BalusC
quelle
1
Gibt es irgendwo einen doFilter () - Beispielcode, der die oben genannten Aufgaben erfüllt? Vielen Dank.
Frank
20
In welchem ​​Schritt stecken Sie genau fest? Meine Antwort schreibt fast Code selbst. Haben Sie auch bemerkt, dass die blauen Code-Referenzen tatsächlich Links zu Javadocs sind, die das Verhalten von Klassen / Methoden im Detail beschreiben? Auf jeden Fall finden Sie hier und hier gute JSP / Servlet-Tutorials, insbesondere dieses über Filter.
BalusC
1
Ich nehme an, es ist richtig, aber wenn der Filter einer der ersten in der Kette ist und RequestDispatcher#forward()ausgeführt wird, werden die restlichen Filter nicht ausgeführt. Also, wird es keinen besseren Weg geben, als dies als Servlet zu tun?
Lucasvc
2
@datakey: entweder die Reihenfolge neu anordnen oder <dispatcher>FORWARD</dispatcher>zur Filterzuordnung hinzufügen .
BalusC
1
@ JimJim2000: entweder die Reihenfolge neu anordnen oder <dispatcher>FORWARD</dispatcher>zur Filterzuordnung hinzufügen .
BalusC
21

Sie können den gebrauchsfertigen URL-Umschreibfilter mit einer Regel wie der folgenden verwenden:

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

Überprüfen Sie die Beispiele für weitere ... Beispiele.

Pascal Thivent
quelle
7

Ein einfacher JSF Url Prettyfier-Filter, der auf den Schritten der Antwort von BalusC basiert . Der Filter leitet alle Anforderungen, die mit dem Pfad / ui beginnen (vorausgesetzt, Sie haben alle Ihre xhtml-Dateien dort gespeichert), an denselben Pfad weiter, fügt jedoch das xhtml-Suffix hinzu.

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 {

    }

}
Xtreme Biker
quelle