Como usar um filtro de servlet em Java para alterar um URL de solicitação de servlet de input?

Como posso usar um filtro de servlet para alterar um URL de solicitação de servlet de input de

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

para

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

?


Atualização : de acordo com os passos do BalusC abaixo, eu criei o seguinte código:

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

A input relevante no web.xml parece com isto:

  urlRewriteFilter com.example.UrlRewriteFilter   urlRewriteFilter /*  

Eu tentei o redirecionamento do lado do servidor e do lado do cliente com os resultados esperados. Funcionou, graças ao BalusC!

  1. Implemente o javax.servlet.Filter .
  2. No método doFilter() , doFilter() o ServletRequest input em HttpServletRequest .
  3. Use HttpServletRequest#getRequestURI() para capturar o caminho.
  4. Use methods java.lang.String simples como substring() , split() , concat() e assim por diante para extrair a parte de interesse e compor o novo caminho.
  5. Use ServletRequest#getRequestDispatcher() e, em seguida, RequestDispatcher#forward() para encaminhar a solicitação / resposta para o novo URL (redirecionamento do lado do servidor, não refletido na barra de endereço do navegador) ou transmitir o ServletResponse input para HttpServletResponse e HttpServletResponse#sendRedirect() redirect a resposta para o novo URL (redirecionamento do lado do cliente, refletido na barra de endereço do navegador).
  6. Registre o filtro em web.xml em um url-pattern de url-pattern de /* ou /Check_License/* , dependendo do caminho do contexto, ou se você já estiver no Servlet 3.0, use a anotação @WebFilter para isso.

Não esqueça de adicionar uma checagem no código se a URL precisar ser mudada e se não , então apenas chame FilterChain#doFilter() , senão ela irá se chamar em um loop infinito.

Alternativamente, você também pode simplesmente usar uma API de terceiros existente para fazer todo o trabalho para você, como o UrlRewriteFilter da Tuckey, que pode ser configurado da maneira que você faria com o mod_rewrite do Apache.

Você pode usar o pronto para usar o filtro de reescrita de URL com uma regra como esta:

  ^/Check_License/Dir_My_App/Dir_ABC/My_Obj_([0-9]+)$ /Check_License?Contact_Id=My_Obj_$1  

Verifique os exemplos para mais exemplos.

Um simples filtro JSF Url Prettyfier baseado nas etapas da resposta do BalusC . O filtro encaminha todas as solicitações iniciando com o caminho / ui (supondo que você tenha todos os seus arquivos xhtml armazenados lá) para o mesmo caminho, mas adicionando o sufixo 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 { } } 

Tenha em atenção que, se o URL original contiver parâmetros, ou seja, http://nm-java.appspot.com/Check_License/Dir_My_App/Dir_ABC/My_Obj_123 ? param1 = A & param2 = B, então esses parâmetros também serão encaminhados para o próximo servlet / jsp. Eu não encontrei uma maneira de se livrar ou replace os parâmetros originais (somente usando HttpServletRequestWrapper). Alguma ideia?..

Atualização: parece que http://ocpsoft.org/opensource/how-to-safely-add-modify-servlet-request-parameter-values/ resolve esse problema.