2012-01-17 95 views
10

我试图按照Design Patterns web based applications的模式进行操作。从涉及到映射“根”URL时起,这一切都起到了很好的作用。在Tomcat中将URL映射到FrontController servlet

我想通过“前端控制器”把所有的要求,所以我已经把

<servlet-mapping> 
    <servlet-name>ControllerServlet</servlet-name> 
    <url-pattern>/*</url-pattern> 
</servlet-mapping> 

web.xml。步进通过与Netbeans的显示未来的请求,并操作工作正常,但随后行

request.getRequestDispatcher("/WEB-INF/" + view + ".jsp").forward(request, response); 

还获得由控制器抓到,这是不言而喻的行动再次和这一切失败。

我可以通过不从网址的根目录开始工作,例如

<servlet-mapping> 
     <servlet-name>ControllerServlet</servlet-name> 
     <url-pattern>/pages/*</url-pattern> 
    </servlet-mapping> 

但这不是我想要的。有什么办法可以使它与“根”URL一起工作吗?

回答

8

/* URL模式涵盖一切,还转发的JSP文件和静态资源,如CSS/JS /图像。你不希望在前端控制器servlet上拥有这个功能。

保持您的控制器servlet处于更具体的URL模式,如/pages/*。您可以实现通过像/resources一个共同的文件夹分组的静态资源和创造这是对/*映射一个Filter摆脱在URL“/页”的功能要求,并执行以下任务的doFilter()方法:

HttpServletRequest req = (HttpServletRequest) request; 
String path = req.getRequestURI().substring(req.getContextPath().length()); 

if (path.startsWith("/resources/")) { 
    // Just let container's default servlet do its job. 
    chain.doFilter(request, response); 
} else { 
    // Delegate to your front controller. 
    request.getRequestDispatcher("/pages" + path).forward(request, response); 
} 

转发的JSP资源在默认情况下不会与此过滤器匹配,因此它将由容器自己的JspServlet正确拾取。

+0

感谢您的答复,它看起来复杂,所以它要带我一段时间才能到达过滤器,现在我就离开一切/页/ – Mark 2012-01-18 19:06:47

+0

您可以将无延伸请求与path.match(“^。* \\/[^ \\。] * $”)匹配并将其转发给您的前端控制器。 – Ring 2014-02-05 18:09:32

+0

@BalusC'substring'有什么意义? – user2418306 2016-01-23 14:55:37

0

/* url模式匹配应用程序中的所有servlet,jsp和静态内容。

Whay你需要的是定义一个* .JSP模式,让Tomcat的使用默认的JSP Servlet:

<servlet-mapping> 
    <servlet-name>jsp</servlet-name> 
    <url-pattern>*.jsp</url-pattern> 
</servlet-mapping> 
3

为什么我们需要映射每个URL。如果您需要映射所有网址,则可能需要在过滤器中跳过网址。

<filter> 
    <display-name>SessionFilter</display-name> 
    <filter-name>SessionFilter</filter-name> 
    <filter-class>com.colabcom.goshare.app.base.filter.SessionFilter</filter-class> 
    </filter> 
    <filter-mapping> 
    <filter-name>sessionFilter</filter-name> 
    <url-pattern>/*</url-pattern> 
    </filter-mapping> 

在你的过滤器,

 HttpServletRequest request = (HttpServletRequest) req; 
     HttpServletResponse response = (HttpServletResponse) res; 
     String url = request.getServletPath(); 
     boolean allowedRequest = Utility.filterURL(url, avoidUrls); 
     if(allowedRequest){ 
      chain.doFilter(request, response); 
     }else{ 
      //Main Filter Code   
     } 

工具类来过滤网址:

public static boolean filterURL(String str, List<String> avoidURLList) { 
    boolean exist = false; 

    if(avoidURLList == null){ 
     return exist; 
    } 
    for (int i = 0; i < avoidURLList.size(); i++) { 
     if (str.contains(avoidURLList.get(i))) { 
      exist = true; 
      break; 
     } 
    } 
    return exist; 
} 

否则,你可以在你的web.xml映射特定的URL像

<filter-mapping> 
    <filter-name>sessionFilter</filter-name> 
    <url-pattern>*.action</url-pattern> 
    </filter-mapping> 
+0

感谢您的回复,它看起来很复杂,所以我需要一段时间才能过滤,现在我只是将所有内容都留在/ pages/ – Mark 2012-01-18 19:06:56

0

您可以扩展DefaultServlet您的Web服务器。扩展的servlet将成为您的前端控制器。在doGET或doPOST方法中,将静态页面转发给超类。 DefaultServlet是默认映射到url“/”的servlet。我用它与jetty服务器,但它也可以在tomcat中实现。

public class FrontController extends DefaultServlet { 

@Override 
public void init() throws UnavailableException { 
    super.init(); 
} 

@Override 
protected void doGet(HttpServletRequest request, 
     HttpServletResponse response) throws ServletException, IOException { 

    String uri = request.getRequestURI(); 

    /* 
    * if request is trying to access inside /static then use the default 
    * servlet. YOU CAN USE YOUR OWN BUSINESS LOGIC TO FORWARD REQUESTS 
    * TO DEFAULTSERVLET 
    */ 
    if (uri.startsWith("/static/")) { 

     super.doGet(request, response); 
     return; 
    } else { 

     // else use your custom action handlers 
    } 
} 

}

在上面的代码样品我已转发开始/静态/到默认的servlet来处理所有请求。通过这种方式,您可以将FrontController映射到“/”级别。

<servlet> 
<description></description> 
<display-name>FrontController</display-name> 
<servlet-name>FrontController</servlet-name> 
<servlet-class>FrontController</servlet-class> 

<servlet-mapping> 
<servlet-name>FrontController</servlet-name> 
<url-pattern>/</url-pattern> 

+0

这是否将您的解决方案绑定到特定容器?换句话说,一旦我将这段代码写入到我的应用程序中,然后我就会使用Tomcat或Jetty或之后的任何其他代码,直到我稍后必须返回并更改此代码为止? – Ring 2014-02-05 17:05:38