1

I would like to map all URLs to one main servlet, except my static files (like stylesheets, graphics and stuff) and still be able to call JSPs from my servlets..

My intent is to provide "vanity URLs" to users, such that any URL that doesn't point to a static file or resource, gets mapped to my main servlet..

How do I do that..?

If it helps, I can have all my static files and JSPs in seperate folders.. Is there a way to map to those folders before the /* mapping..?

KarmicMind
  • 166
  • 2
  • 8

5 Answers5

0

As correctly mentioned in comment, have separate Servlet for separate JSPs unless there is a justifiable reason for it. If you want to do this, you can simply have if--else block in your servlet, that is mapped by various URLs, and based on the request incoming and dispatch to relevant JSP.

Like

...
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 (....){
....

I am suggesting against this plan. better have your web.xml to do the routing. Or better use a framework that handle this for you.

Nishant
  • 54,584
  • 13
  • 112
  • 127
0

I would recommend using a framework to handle the routing for instance Spring and Struts do a better job at handling the routing. You could make a servlet or web.xml do it, but then not reusing code from a framework just seems pointless in this case. So I would recommend going with Spring or Struts 2

seeker
  • 6,841
  • 24
  • 64
  • 100
0

Two ways to do it, neither is perfect:

  • Define an extension for your 'actions' and map that to your servlet (like the .do in Struts 1).
  • Have all the servlet requests go to a specific sub-path (eg /actions/*)

The mapping rules in web.xml are pretty limited, because the container matches extensions after path rules, it's not possible to map a servlet to /*, except *.jsp.

As usual, I don't think "use a framework" is necessarily the answer - if the project is relatively small, the added complexity may not be worth it.

Dmitri
  • 8,999
  • 5
  • 36
  • 43
0

Apart from all the frameworks which can do this for you, as others already pointed out, try to map this the other way around.

So instead of trying to map everything except the exceptions, map the exceptions and let everything go through your servlet. You can easily achieve this by putting a filter upfront which maps to all your static files.

M Platvoet
  • 1,679
  • 1
  • 10
  • 14
0

Inspired by How to access static resources when mapping a global front controller servlet on /* I came up with this solution:

in /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>

in 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);
    }

}

Now you can put all your static content into subfolders in your WAR. Then if you want to link to /war/css/style.css from your HTML, you simply refer to it as "/css:/style.css".. Or you can name your folders/files with a _ at the beginning and refer to them like normal..

(Also the _ rule makes sure that Google App Engine developers can access /_ah/admin)

Community
  • 1
  • 1
KarmicMind
  • 166
  • 2
  • 8