Case 1
<servlet-mapping>
<servlet-name>myapp</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
Case 2
<servlet-mapping>
<servlet-name>myapp</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
If I use case 1 then I dont get any of my pages styled with <link rel="stylesheet" type="text/css" href="${contextPath}/assets/styles.css" />
, but if I use case 2 everything gets styled.
Could someone help me understand why?
Also, could someone tell me which pattern should be used so that I don't have to worry about extensions? Like should I be using /*
? The thing is that if I use /*
now when I've been using *.do
while developing my application, everything seems to be breaking, not only the styles but I don't get any pictures rendered, no JCaptcha and all that has to do with links.
And If I try to send a GET request from a REST Client like http://localhost:8080/myapp/user/1
it doesn't work and I need to add .do
at the end and send the same request like http://localhost:8080/myapp/user/1.do
.
Thanks.
Browsers sends separate HTTP requests on linked resources such as CSS files, JS files and images. The URLs of those requests also match the URL pattern of /
. So your myapp
servlet is also called on those requests. However, your myapp
servlet doesn't seem to process them properly, so those requests returns something entirely different. Try requesting those resources yourself separately to learn what your servlet is actually returning to the webbrowser:
In your case, you want to let your myapp
servlet ignore requests on those resources. The best way is to create a filter which does that. Assuming that all of those resources are in a folder called /assets
, then you can achieve this by mapping your servlet on a more specific URL pattern, such as for example /myapp/*
and creating a Filter
listening on /*
which transparently continues the request/response chain for any requests on /assets
and dispatches all other requests to /myapp
.
So, this configuration
<filter>
<filter-name>filter</filter-name>
<filter-class>com.example.Filter</filter-class>
</filter>
<filter-mapping>
<filter-name>filter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<servlet>
<servlet-name>controller</servlet-name>
<servlet-class>com.example.Controller</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>controller</servlet-name>
<url-pattern>/myapp/*</url-pattern>
</servlet-mapping>
in combination with the following in filter's doFilter()
:
String uri = ((HttpServletRequest) request).getRequestURI();
if (uri.startsWith("/assets")) {
chain.doFilter(request, response); // Goes to container's default servlet.
} else {
request.getRequestDispatcher("/myapp" + uri).forward(request, response);
}
should work for you.