2010-04-27 24 views
154

如何使用Servlet篩選器來從如何在Java中使用servlet過濾器來更改傳入的servlet請求url?

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

改變傳入servlet請求的URL

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!

+0

相關問題:http://stackoverflow.com/questions/2723829/how-to-catch-non-exist-requested-url-in-java-servlet – BalusC 2010-04-27 21:06:32

+0

是否使用的是Servlet規範的版本?如何使用不同版本轉發請求更改。 – 2010-04-27 21:11:03

+0

[看到這篇文章](http://stackoverflow.com/questions/2283237/most-useful-java-servlet-filter-out-there)它也有一個過濾器,做你想做的 – 2010-04-27 21:38:33

回答

242
  1. 執行javax.servlet.Filter
  2. doFilter()方法中,將傳入的ServletRequest投射到HttpServletRequest
  3. 使用HttpServletRequest#getRequestURI()來抓住路徑。
  4. 直接使用java.lang.String方法如substring(),split(),concat()等來提取感興趣的部分並組成新的路徑。
  5. 選其一ServletRequest#getRequestDispatcher()然後RequestDispatcher#forward()轉發請求/響應新的URL(服務器端重定向,不反映在瀏覽器的地址欄),投傳入ServletResponseHttpServletResponse然後HttpServletResponse#sendRedirect()重定向到響應新的URL(客戶端重定向,反映在瀏覽器地址欄中)。
  6. 註冊在web.xml過濾器上的/*/Check_License/*url-pattern,根據上下文路徑上,或者如果你是在Servlet的3.0已,用@WebFilter標註爲代替。

不要忘了在代碼中添加一個檢查,如果要改變需要的URL,如果不,則只需撥打FilterChain#doFilter(),否則它會調用自身無限循環。

或者,您也可以使用現有的第三方API來爲您完成所有工作,如Tuckey's UrlRewriteFilter,可以按照您對Apache的mod_rewrite所做的那樣配置。

+1

任何doFilter()示例代碼的地方做了上述?謝謝。 – Frank 2010-04-27 21:21:17

+18

你到底在哪一步?我的答案几乎寫代碼本身。你是否還注意到,藍色的代碼引用實際上是指向Javadocs的鏈接,它詳細描述了類/方法的行爲?無論如何,你可以找到[這裏](http://courses.coreservlets.com/Course-Materials/csajsp2.html)和[這裏](http://courses.coreservlets.com/Course-Materials/msajsp。 html)良好的JSP/Servlet教程,特別是[this](http://courses.coreservlets.com/Course-Materials/pdf/msajsp/05-Filters.pdf)一個關於過濾器。 – BalusC 2010-04-27 21:26:50

+0

我遵循相同的實現過濾器,但沒有成功。請幫忙。該請求不會重定向到服務的目標資源類。 – 2013-09-30 11:22:44

16

您可以使用準備用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> 

檢查Examples更多...例子。

1

請注意,如果您的原始URL包含參數,即http://nm-java.appspot.com/Check_License/Dir_My_App/Dir_ABC/My_Obj_123param1 = A & param2 = B然後這些參數也將被轉發到下一個servlet/jsp。 我沒有找到擺脫或替換原始參數的方法(僅通過使用HttpServletRequestWrapper)。任何想法?..

更新:似乎http://ocpsoft.org/opensource/how-to-safely-add-modify-servlet-request-parameter-values/解決此問題。

+7

答案並不是要問問題。 – Mot 2013-04-14 07:31:48

2

一個基於BalusC's answer步驟的簡單JSF Url Prettyfier過濾器。過濾器將所有以/ 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 { 

    } 

} 
相關問題