Come utilizzare un filtro servlet in Java per modificare l'URL di una richiesta servlet in arrivo?


186

Come posso utilizzare un filtro servlet per modificare l'URL di una richiesta servlet in arrivo

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

per

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

?


Aggiornamento : secondo i passaggi di seguito di BalusC, ho trovato il seguente codice:

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

La voce pertinente web.xmlappare così:

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

Ho provato il reindirizzamento sia lato server che lato client con i risultati previsti. Ha funzionato, grazie BalusC!



Quale versione delle specifiche servlet stai usando? Come inoltrare le richieste di modifiche con le diverse versioni.
Romain Hippeau,

Vedi questo post ha anche un filtro che fa quello che vuoi
Romain Hippeau,

Si noti che se l'URL originale contiene parametri, ovvero nm-java.appspot.com/Check_License/Dir_My_App/Dir_ABC/My_Obj_123 ? ** param1 = A & param2 = B **, questi parametri verranno inoltrati anche al servlet / jsp successivo. Non ho trovato il modo di eliminare o sostituire i parametri originali (solo utilizzando HttpServletRequestWrapper). Qualche idea? .. Aggiornamento: sembra che http://ocpsoft.org/opensource/how-to-safely-add-modify-servlet-request-parameter-values/ risolve questo problema.
Lopotun,

Grazie stavo cercando un esempio di riscrittura e crittografia degli URL.
Aditya Yada,

Risposte:


281
  1. Implementare javax.servlet.Filter.
  2. Nel doFilter()metodo, cast l'arrivo ServletRequesta HttpServletRequest.
  3. Utilizzare HttpServletRequest#getRequestURI()per afferrare il percorso.
  4. Utilizzare semplici java.lang.Stringmetodi come substring(), split(), concat()e così via per estrarre la parte di interesse e comporre il nuovo percorso.
  5. Utilizzare ServletRequest#getRequestDispatcher()e quindi RequestDispatcher#forward()per inoltrare la richiesta / risposta al nuovo URL (reindirizzamento lato server, non riflesso nella barra degli indirizzi del browser), oppure trasmettere l' arrivo ServletResponsea HttpServletResponsee quindi HttpServletResponse#sendRedirect()reindirizzare la risposta al nuovo URL (reindirizzamento lato client, riflesso in barra degli indirizzi del browser).
  6. Registra il filtro web.xmlsu url-patterndi /*o /Check_License/*, a seconda del percorso di contesto, o se sei già su Servlet 3.0, usa invece l' @WebFilterannotazione per quello.

Non dimenticare di aggiungere un segno di spunta nel codice se l'URL deve essere modificato e, in caso contrario , chiama FilterChain#doFilter(), altrimenti si chiamerà in un ciclo infinito.

In alternativa puoi anche semplicemente usare un'API di terze parti esistente per fare tutto il lavoro per te, come UrlRewriteFilter di Tuckey che può essere configurato come faresti con Apache mod_rewrite.


1
Qualche codice di esempio doFilter () da qualche parte che fa quanto sopra? Grazie.
Frank,

20
A che punto stai esattamente bloccando? La mia risposta quasi scrive il codice stesso. Hai anche notato che i riferimenti al codice in blu sono in realtà collegamenti a Javadocs che descrivono in dettaglio il comportamento di classe / metodo? In ogni caso, puoi trovare qui e qui buoni tutorial JSP / Servlet, in particolare questo sui filtri.
BalusC,

1
Suppongo che sia corretto, ma se il filtro è uno dei primi nella catena e RequestDispatcher#forward()viene eseguito, il resto dei filtri non verrà eseguito. Quindi, non sarà un modo migliore di farlo come un servlet?
lucasvc,

2
@datakey: basta riorganizzare l'ordinamento o aggiungere <dispatcher>FORWARD</dispatcher>alla mappatura del filtro.
BalusC,

1
@ JimJim2000: basta riorganizzare l'ordinamento o aggiungere <dispatcher>FORWARD</dispatcher>alla mappatura filtro.
BalusC,

21

È possibile utilizzare il filtro riscrittura URL pronto per l'uso con una regola come questa:

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

Controlla gli esempi per ulteriori ... esempi.


7

Un semplice filtro JSF Url Prettyfier basato sui passaggi della risposta di BalusC . Il filtro inoltra tutte le richieste che iniziano con il percorso / ui (supponendo di avere tutti i file xhtml memorizzati lì) sullo stesso percorso, ma aggiungendo il suffisso 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 {

    }

}
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.