Asked  7 Months ago    Answers:  5   Viewed   71 times

I deploy a webapp on two different containers (Tomcat and Jetty), but their default servlets for serving the static content have a different way of handling the URL structure I want to use (details).

I am therefore looking to include a small servlet in the webapp to serve its own static content (images, CSS, etc.). The servlet should have the following properties:

  • No external dependencies
  • Simple and reliable
  • Support for If-Modified-Since header (i.e. custom getLastModified method)
  • (Optional) support for gzip encoding, etags,...

Is such a servlet available somewhere? The closest I can find is example 4-10 from the servlet book.

Update: The URL structure I want to use - in case you are wondering - is simply:

    <servlet-mapping>
            <servlet-name>main</servlet-name>
            <url-pattern>/*</url-pattern>
    </servlet-mapping>
    <servlet-mapping>
            <servlet-name>default</servlet-name>
            <url-pattern>/static/*</url-pattern>
    </servlet-mapping>

So all requests should be passed to the main servlet, unless they are for the static path. The problem is that Tomcat's default servlet does not take the ServletPath into account (so it looks for the static files in the main folder), while Jetty does (so it looks in the static folder).

 Answers

39

I ended up rolling my own StaticServlet. It supports If-Modified-Since, gzip encoding and it should be able to serve static files from war-files as well. It is not very difficult code, but it is not entirely trivial either.

The code is available: StaticServlet.java. Feel free to comment.

Update: Khurram asks about the ServletUtils class which is referenced in StaticServlet. It is simply a class with auxiliary methods that I used for my project. The only method you need is coalesce (which is identical to the SQL function COALESCE). This is the code:

public static <T> T coalesce(T...ts) {
    for(T t: ts)
        if(t != null)
            return t;
    return null;
}
Tuesday, June 1, 2021
 
ammezie
answered 7 Months ago
48

Yes that's what is needed and good for SEO too. Multiple url for same content is not a good thing. You need to make changes in htaccess file written below.

RewriteBase / RewriteCond %{HTTP_HOST} ^example.com [NC] RewriteRule ^(.*)$ http://www.example.com/$1 [L,R=301]

Saturday, May 29, 2021
 
Litty
answered 7 Months ago
92

To start, create a Servlet which listens on a certain url-pattern, e.g. /pages/*. Implement the service() method to lookup the action associated with the request method (GET, POST, etc) and pathinfo (the URL part after the servlet's url-pattern).

Basic example:

protected void service(HttpServletRequest request, HttpServletResponse response) 
  throws ServletException, IOException {
  View view = new View(request, response);
  Action action = ActionFactory.getAction(request);
  action.execute(view);
  view.navigate();
}

The Action interface should represent an unit of work. You can implement it to do the necessary business logic:

public interface Action {
  void execute(View view);
}

The ActionFactory should maintain the classes implementing Action in sort of Map<String, Action> where the String key represents less or more a combination of the request method and pathinfo. You could then get an Action as follows:

public static Action getAction(HttpServletRequest request) {
  return actions.get(request.getMethod() + request.getPathInfo());
}

The View should represent the request scoped context which the Action can work with. In the navigate() you could forward the request to a JSP for display:

public void navigate() {
  String path = "/WEB-INF" + request.getPathInfo() + ".jsp";
  request.getRequestDispatcher(path).forward(request, response);
}

That should get you started (note that I left all obvious checks such as null pointers away to make the examples less cluttered, that's up to you now).

There is however more to take account with in the whole story, such as validation, conversion, event handling, input value mappings, localization, dependency injection, etcetera. That's all with all quite a work. The more decent MVC frameworks takes most of this all into account, such as Sun JSF, Apache Struts, Spring MVC, Stripes, etcetera. If you have never done any of them, then I strongly recommend to do so before homegrowing one, otherwise you would end up with a waste of time.

Thursday, June 10, 2021
 
iceduck
answered 6 Months ago
63

Its not a standard practice or valid as per the J2EE spec (I know using most of the java Web development frameworks like Struts, Spring MVC, Stripes you can do this). As per the spec, all our publicly accessibly pages should be out side of WEB-INF. But if you want the pages to be in web-inf, what you can do is to create a servlet along the lines of a controller servlet and forward the requests to jsp pages from your servlet and those pages can be in WEB-INF, and there is no special configuration that can be done to do this.

Wednesday, June 30, 2021
 
Manju
answered 5 Months ago
18

is there a way in HTML to request that the browser buffer the entire audio file on playing in order to allow replays rather than the server needing necessarily to support range requests?

Even if there is, it will not be supported on all browsers, especially mobiles/ipads/etc.

does anyone have any experience of responding to range requests from a Servlet?

There's implementation provided by BalusC. I have ported it to my environment and, apart some minor issues, (which are most likely unrelated to the implementation but to the client side specifics) it works great.

Friday, August 6, 2021
 
Matt
answered 4 Months ago
Only authorized users can answer the question. Please sign in first, or register a free account.
Not the answer you're looking for? Browse other questions tagged :
 
Share