Как использовать сервлет-фильтр в Java для изменения URL-адреса входящего сервлета?
Как я могу использовать фильтр сервлета для изменения URL запроса входящего сервлета из
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!
Ответы
Ответ 1
- Внедрить
javax.servlet.Filter
.
- В
doFilter()
, введите входящий ServletRequest
to HttpServletRequest
.
- Используйте
HttpServletRequest#getRequestURI()
, чтобы захватить путь.
- Используйте простые методы
java.lang.String
, такие как substring()
, split()
, concat()
и так далее для извлечения части интереса и составления нового пути.
- Используйте
ServletRequest#getRequestDispatcher()
, а затем RequestDispatcher#forward()
перенаправить запрос/ответ на новый URL-адрес (перенаправление на серверной стороне, не отображаемое в адресной строке браузера), или передать входящий ServletResponse
до HttpServletResponse
, а затем HttpServletResponse#sendRedirect()
, чтобы перенаправить ответ на новый URL-адрес (перенаправление на стороне клиента, отображаемое в адресной строке браузера).
- Зарегистрируйте фильтр в
web.xml
на url-pattern
из /*
или /Check_License/*
, в зависимости от пути контекста, или если вы уже на Servlet 3.0, используйте @WebFilter
аннотация для этого.
Не забудьте добавить код в код, если нужно изменить URL-адрес, а если нет, просто позвоните FilterChain#doFilter()
, иначе он будет вызывать себя в бесконечном цикле.
В качестве альтернативы вы также можете использовать существующий сторонний API для выполнения всей вашей работы, например Tuckey UrlRewriteFilter, который можно настроить как вы это делали бы с Apache mod_rewrite
.
Ответ 2
Вы можете использовать готовый к использованию Url Rewrite Filter с таким же правилом:
<rule>
<from>^/Check_License/Dir_My_App/Dir_ABC/My_Obj_([0-9]+)$</from>
<to>/Check_License?Contact_Id=My_Obj_$1</to>
</rule>
Проверьте Примеры для более... примеров.
Ответ 3
Обратите внимание, что если ваш исходный URL содержит параметры, то есть http://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/ устраняет эту проблему.
Ответ 4
Простой фильтр JSF Url 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 {
}
}