Як використовувати фільтр сервлетів у Java для зміни URL-адреси запиту сервлета?


186

Як я можу використовувати фільтр сервлетів, щоб змінити вхідний запит сервлета

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

?


Оновлення : згідно з кроками BalusC нижче, я придумав такий код:

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

Відповідний запис web.xmlвиглядає так:

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

Я спробував і перенаправлення на сторону сервера, і на клієнта, з очікуваними результатами. Це спрацювало, дякую BalusC!


Пов'язані питання: stackoverflow.com/questions/2723829 / ...
BalusC

Яку версію специфікації сервлетів ви використовуєте? Як ви пересилаєте запити змін у різних версіях.
Ромен Хіппо

Дивіться цю публікацію, у неї також є фільтр, який робить те, що ви хочете
Ромен Хіппо,

Зауважте, що якщо ваша початкова URL-адреса містить параметри, тобто nm-java.appspot.com/Check_License/Dir_My_App/Dir_ABC/My_Obj_123 ? ** param1 = A & param2 = B **, ці параметри також будуть передані наступному сервлету / jsp. Я не знайшов способу позбутися або замінити вихідні параметри (лише за допомогою HttpServletRequestWrapper). Будь-які ідеї? .. Оновлення: схоже, що http://ocpsoft.org/opensource/how-to-safely-add-modify-servlet-request-parameter-values/ вирішує цю проблему.
Лопотун

Дякую, я шукав приклад переписування та шифрування URL-адрес.
Адітя Яда

Відповіді:


281
  1. Реалізація javax.servlet.Filter.
  2. У doFilter()методі передавайте вхід ServletRequestна HttpServletRequest.
  3. Використовуйте, HttpServletRequest#getRequestURI()щоб схопити шлях.
  4. Користуйтеся простими java.lang.Stringметоди , такі як substring(), split(), concat()і так далі , щоб витягти частину інтересу і скласти новий шлях.
  5. Використовуйте або ServletRequest#getRequestDispatcher()потім, RequestDispatcher#forward()щоб переслати запит / відповідь на нову URL-адресу (переадресація на стороні сервера, не відображена в адресному рядку веб-переглядача), або введіть вхідну ServletResponseінформацію, HttpServletResponseа потім HttpServletResponse#sendRedirect()перенаправляйте відповідь на нову URL-адресу (перенаправлення на стороні клієнта, відображене в адресний рядок браузера).
  6. Зареєструйте фільтр web.xmlна умовах url-patternз /*або /Check_License/*, в залежності від контексту шляху, або якщо ви на Servlet 3.0 вже, використовувати @WebFilterанотацію , що замість цього.

Не забудьте додати галочку в код, якщо URL-адресу потрібно змінити, а якщо ні , то просто зателефонуйте FilterChain#doFilter(), інакше вона зателефонує собі у нескінченному циклі.

Крім того, ви можете просто використовувати існуючий сторонній API, щоб виконати всю роботу за вас, наприклад UrlRewriteFilter Tuckey, який можна налаштувати так, як ви робите з Apache mod_rewrite.


1
Будь-який код зразка doFilter (), десь зроблено вище? Дякую.
Френк

20
На якому кроці ви точно застрягаєте? Моя відповідь майже пише сам код. Ви також зазначили, що посилання на код синім кольором - це фактично посилання на Javadocs, що докладно описує поведінку класу / методу? У будь-якому випадку, ви можете знайти тут і тут гарні підручники JSP / Servlet, в зокрема , це один про фільтри.
BalusC

1
Я вважаю, що це правильно, але якщо фільтр є одним із перших у ланцюзі, і RequestDispatcher#forward()він виконується, решта фільтрів не виконуватимуться. Отже, не буде кращого способу, ніж робити це як сервлет?
lucasvc

2
@datakey: просто переставити впорядкування або додати <dispatcher>FORWARD</dispatcher>до фільтрування.
BalusC

1
@ JimJim2000: просто переставити впорядкування або додати <dispatcher>FORWARD</dispatcher>до фільтрування.
BalusC


7

Простий фільтр JSF Urt Prettyfier, заснований на кроках відповіді BalusC . Фільтр пересилає всі запити, починаючи з шляху / ui (припустимо, у вас збережені всі ваші файли xhtml) на той самий шлях, але додаючи суфікс 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 {

    }

}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.