【问题标题】:(Almost) all URLs to one servlet(几乎)一个 servlet 的所有 URL
【发布时间】:2012-02-24 08:36:33
【问题描述】:

我想将所有 URL 映射到一个主 servlet,除了我的静态文件(如样式表、图形和其他东西),并且仍然能够从我的 servlet 调用 JSP。

我的意图是向用户提供“虚 URL”,这样任何不指向静态文件或资源的 URL 都会映射到我的主 servlet..

我该怎么做..?

如果有帮助,我可以将我所有的静态文件和 JSP 放在单独的文件夹中。有没有办法在 /* 映射之前映射到这些文件夹..?

【问题讨论】:

  • 天哪,我使用这样的系统,真是让人头疼!即使我知道,我也不会告诉你。
  • 您想推出自己的框架?
  • 到目前为止我找到了这个解决方案:stackoverflow.com/questions/870150/…

标签: java jsp servlets web.xml


【解决方案1】:

正如评论中正确提到的,为单独的 JSP 使用单独的 Servlet,除非有正当理由。如果你想这样做,你可以简单地在你的 servlet 中添加if--else 块,它由各种 URL 映射,并根据传入和分派到相关 JSP 的请求。

喜欢

...
else if(request.getServletPath().equals("/user/account")){
      //relevant processing and setting request attribute goes here
      request.getRequestDispatcher("account_jsp_page.jsp").forward(request, response);  
} 
else if (....){
....

我建议反对这个计划。最好让您的web.xml 进行路由。或者更好地使用为您处理此问题的框架。

【讨论】:

    【解决方案2】:

    我建议使用框架来处理路由,例如 Spring 和 Struts 在处理路由方面做得更好。你可以让一个 servlet 或 web.xml 来做,但在这种情况下,不重用框架中的代码似乎毫无意义。所以我建议使用 Spring 或 Struts 2

    【讨论】:

      【解决方案3】:

      两种方法,都不是完美的:

      • 为您的“操作”定义一个扩展并将其映射到您的 servlet(如 Struts 1 中的 .do)。
      • 让所有 servlet 请求都转到特定的子路径(例如 /actions/*)

      web.xml 中的映射规则非常有限,因为容器在 路径规则之后匹配扩展,因此无法将 servlet 映射到 /*, except *.jsp

      像往常一样,我认为“使用框架”不一定是答案 - 如果项目相对较小,增加的复杂性可能不值得。

      【讨论】:

        【解决方案4】:

        正如其他人已经指出的那样,除了可以为您执行此操作的所有框架之外,请尝试以相反的方式进行映射。

        因此,与其尝试映​​射除异常之外的所有内容,不如映射异常并让所有内容都通过您的 servlet。您可以通过预先放置一个映射到所有静态文件的过滤器来轻松实现这一点。

        【讨论】:

          【解决方案5】:

          灵感来自How to access static resources when mapping a global front controller servlet on /* 我想出了这个解决方案:

          /war/WEB-INF/web.xml:

          <filter>
              <filter-name>MainFilter</filter-name>
              <filter-class>com.example.mywebsite.MainFilter</filter-class>
          </filter>
          <filter-mapping>
              <filter-name>MainFilter</filter-name>
              <url-pattern>/*</url-pattern>
          </filter-mapping>
          
          <servlet>
              <servlet-name>MainServlet</servlet-name>
              <servlet-class>com.example.mywebsite.MainServlet</servlet-class>
          </servlet>
          <servlet-mapping>
              <servlet-name>MainServlet</servlet-name>
              <url-pattern>/MainServlet/*</url-pattern>
          </servlet-mapping>
          

          MainFilter.java:

          public void doFilter(ServletRequest request, ServletResponse response,
                  FilterChain chain) throws IOException, ServletException {
              HttpServletRequest req = (HttpServletRequest) request;
              String path = req.getRequestURI();
              String topfolder = path.substring(1);
              if (topfolder.contains("/")) {
                  topfolder = topfolder.substring(0, topfolder.indexOf("/"));
              }
          
              if (topfolder.startsWith("_")) {
                  chain.doFilter(request, response);
              } else if (topfolder.endsWith(":")) {
                  request.getRequestDispatcher(path.replaceFirst(":", "")).forward(request, response);
              } else {
                  request.getRequestDispatcher("/MainServlet" + path).forward(request, response);
              }
          
          }
          

          现在您可以将所有静态内容放入 WAR 的子文件夹中。然后,如果您想从 HTML 链接到 /war/css/style.css,只需将其称为 "/css:/style.css".. 或者您可以在开头使用 _ 命名您的文件夹/文件,然后像平常一样引用它们..

          (还有_ 规则确保Google App Engine 开发人员可以访问/_ah/admin

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2018-01-13
            • 2019-02-25
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多