Як використовувати фільтр сервлетів у 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.