Вопрос-ответ

How to use a servlet filter in Java to change an incoming servlet request url?

Как использовать фильтр сервлетов в 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

  1. Реализовать javax.servlet.Filter.

  2. В doFilter() методе приведите входящий запрос к ServletRequest. HttpServletRequest

  3. Используйте HttpServletRequest#getRequestURI() для получения пути.

  4. Используйте простые java.lang.String методы, такие как substring(), split(), concat() и так далее, чтобы извлечь интересующую часть и составить новый путь.

  5. Используйте либо ServletRequest#getRequestDispatcher() and then 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.

Ответ 2

Вы могли бы использовать готовый к использованию фильтр перезаписи URL с правилом, подобным этому:

<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

Простой фильтр для улучшения JSF URL, основанный на шагах, описанных в ответе 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 {

}

}
Ответ 4

В моем случае я использую Spring и по какой-то причине forward у меня не сработало, поэтому я сделал следующее:

public class OldApiVersionFilter implements Filter {

@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
HttpServletRequest httpServletRequest = (HttpServletRequest) request;
if (httpServletRequest.getRequestURI().contains("/api/v3/")) {
HttpServletRequest modifiedRequest = new HttpServletRequestWrapper((httpServletRequest)) {
@Override
public String getRequestURI() {
return httpServletRequest.getRequestURI().replaceAll("/api/v3/", "/api/");
}
};
chain.doFilter(modifiedRequest, response);
} else {
chain.doFilter(request, response);
}
}

@Override
public void init(FilterConfig filterConfig) throws ServletException {}

@Override
public void destroy() {}
}

Убедитесь, что вы передаете modifiedRequest в цепочку

java servlets