I have a particular JSP which I would like to serve at the root page of my website (the URL "/"). All other requests should be served statically. So naturally I configured my web.xml like so:
<servlet>
<servlet-name>index</servlet-name>
<jsp-file>/index.jsp</jsp-file>
</servlet>
<servlet-mapping>
<servlet-name>index</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>default</servlet-name>
<servlet-class>org.apache.catalina.servlets.DefaultServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>default</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
Unfortunately it seems that <url-pattern>/</url-pattern> does not do what I need it to do. Instead of only handling the "/" URL, it is special-cased, and functions as the "default mapping", handling all requests not captured by other URL patterns.
In this particular case, the default servlet's <url-pattern>/*</url-pattern> handles all URLs. A request to "/" comes up as a 404, and the index servlet never gets invoked no matter what request is made.
Is there a way to explicitly map the "/" URL, and only that URL, to a particular servlet?
Use an empty pattern string to match the context root:
<servlet-mapping>
<servlet-name>index</servlet-name>
<url-pattern></url-pattern>
</servlet-mapping>
Related
I'm trying to add a servlet on my project. But it seems not to work.
The first, I inserted the and tags in web.xml file.
And the I tried to accesss the address "/App/newrmt?~~". But the browser showed 404 error message.
I think the system don't recognize the mapping pattern I described.
Is there anything I should do to add a new servlet and a pattern before insert tags in web.xml files?
It's original web.xml code is below.
<servlet>
<servlet-name>action</servlet-name>
<servlet-class>org.apache.struts.action.ActionServlet</servlet-class>
<init-param>
<param-name>config</param-name>
<param-value>/WEB-INF/struts-config.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet>
<servlet-name>HttpReceiver</servlet-name>
<servlet-class>myProject.HttpReceiver</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet>
<servlet-name>RmtlImg</servlet-name>
<servlet-class>myProject.ImageServlet</servlet-class>
<init-param>
<param-name>dir</param-name>
<param-value>/APP/WAS/FILES/A/</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>action</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>HttpReceiver</servlet-name>
<url-pattern>*.http</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>RmtlImg</servlet-name>
<url-pattern>/rmtlimgdown</url-pattern>
</servlet-mapping>
Then, I changed the code like below
<servlet>
<servlet-name>action</servlet-name>
<servlet-class>org.apache.struts.action.ActionServlet</servlet-class>
<init-param>
<param-name>config</param-name>
<param-value>/WEB-INF/struts-config.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet>
<servlet-name>HttpReceiver</servlet-name>
<servlet-class>myProject.HttpReceiver</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet>
<servlet-name>RmtlImg</servlet-name>
<servlet-class>myProject.ImageServlet</servlet-class>
<init-param>
<param-name>dir</param-name>
<param-value>/APP/WAS/FILES/A/</param-value>
</init-param>
</servlet>
**<servlet>
<servlet-name>NewRmtlImg</servlet-name>
<servlet-class>myProject.ImageServlet</servlet-class>
<init-param>
<param-name>dir</param-name>
<param-value>/APP/WAS/FILES/A/</param-value>
</init-param>
</servlet>**
<servlet-mapping>
<servlet-name>action</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>HttpReceiver</servlet-name>
<url-pattern>*.http</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>RmtlImg</servlet-name>
<url-pattern>/rmtlimgdown</url-pattern>
</servlet-mapping>
**<servlet-mapping>
<servlet-name>NewRmtlImg</servlet-name>
<url-pattern>/newrmt</url-pattern>
</servlet-mapping>**
When I change just pattern in the tag like below, It works well. It means servlet-class itself is well coded. Just the WAS don't understand the pattern.
<servlet-mapping>
<servlet-name>NewRmtlImg</servlet-name>
<url-pattern>/newrmt</url-pattern>
</servlet-mapping>
===>
<servlet-mapping>
<servlet-name>NewRmtlImg</servlet-name>
<url-pattern>/rmtlimgdown</url-pattern>
</servlet-mapping>
Anyboday helps me!
When I change just pattern in the tag like below, It works well. It means servlet-class itself is well coded. Just the WAS don't understand the pattern.
It might help you to understand the url-pattern
Servlet Matching Procedure
A request may match more than one servlet-mapping in a given context. The servlet container uses a straightforward matching procedure to determine the best match.
The matching procedure has four simple rules.
First, the container prefers an exact path match over a wildcard path match.
Second, the container prefers to match the longest pattern.
Third, the container prefers path matches over filetype matches.
Finally, the pattern <url-pattern>/</url-pattern> always matches any request that no other pattern matches.
Have a look at my post How does a servlets filter identify next destination is another filter or a servlet/jsp? for detailed description.
I solved this problem.
I found out that I need to change the setting file which is "httpd.conf".
The system has been configured several virtual-host with "MatchExpression".
So what I have to do is to add a single of url-pattern in the config file.
sorry for my bad English.
I want to redirect all connections (/*) to a specific servlet, except a specific file (someFile.xml).
I have the following section in web.xml:
<servlet-mapping>
<servlet-name>someServlet</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
How can I modify it so that /someFile.xml will not be mapped to this servlet.
If I cannot do it using web.xml, is there some other way?
You can create a Servlet and map it to receive /someFile.xml.
<servlet-mapping>
<servlet-name>someServlet</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>SomeFileServlet</servlet-name>
<url-pattern>/someFile.xml</url-pattern>
</servlet-mapping>
In this way all request except /someFile.xml will go to someServlet and request for /someFile.xml will go to SomeFileServlet.
**/* mapping in web.xml it answers all requests except other path mappings.**
I have a confusion regarding the structure of the web.xml for the servlet mapping, I don't have any problem by executing it but I am trying to figure it how why we have such a pattern in the deployment descriptor.
<web-app>
<servlet>
<servlet-name>Servlet1</servlet-name>
<servlet-path>foo.Servlet</servlet-path>
</servlet>
<servlet-mapping>
<servlet-name>Servlet1</servlet-name>
<url-pattern>/enroll</url-pattern>
</servlet-mapping>
</web-app>
Now as far as my understanding whenever a request is comes for url-pattern "/enroll", servlet container is going to match the servlet-name with the url-pattern and will try to find the corresponding servlet-path and will forward the control to foo.Servlet. so basically there would be two passes one for finding servlet-name and another for servlet-path, my question is if container is designed to work in the following way
<web-app>
<servlet>
<servlet-name>foo.Servlet</servlet-path>
<url-pattern>/enroll</url-pattern>
</servlet>
</web-app>
what would be the drawback if we use the following approach. Wouldn't that be more efficient and the response time would be fast.
It allows servlets to have multiple servlet mappings:
<servlet>
<servlet-name>Servlet1</servlet-name>
<servlet-path>foo.Servlet</servlet-path>
</servlet>
<servlet-mapping>
<servlet-name>Servlet1</servlet-name>
<url-pattern>/enroll</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>Servlet1</servlet-name>
<url-pattern>/pay</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>Servlet1</servlet-name>
<url-pattern>/bill</url-pattern>
</servlet-mapping>
It allows filters to be mapped on the particular servlet:
<filter-mapping>
<filter-name>Filter1</filter-name>
<servlet-name>Servlet1</servlet-name>
</filter-mapping>
Your proposal would support neither of them. Note that the web.xml is read and parsed only once during application's startup, not on every HTTP request as you seem to think.
Since Servlet 3.0, there's the #WebServlet annotation which minimizes this boilerplate:
#WebServlet("/enroll")
public class Servlet1 extends HttpServlet {
See also:
How do servlets work? Instantiation, sessions, shared variables and multithreading
Difference between each instance of servlet and each thread of servlet in servlets?
Our Servlets wiki page
<servlet-mapping>
<servlet-name> s1</servlet-name>
<url-pattern> /abc </url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name> s2</servlet-name>
<url-pattern> /abc </url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name> s3</servlet-name>
<url-pattern> /* </url-pattern>
</servlet-mapping>
Which servlet will be called if a request /abc comes?and why?
Check this. In short:
if the mappings have exactly the same pattern, there is no guarantee which servlet one will be invoked. So avoid that.
If the patterns are overlapping, the most specific one is picked. (/abc is more specific than /*)
Is it ok to have more than 1 DispatcherServlet in web.xml to handle different URL ?
What's the downside?
<servlet>
<servlet-name>servlet1</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>2</load-on-startup>
</servlet>
<servlet>
<servlet-name>servlet2</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>2</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>servlet1</servlet-name>
<url-pattern>/url2/*</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>servlet2</servlet-name>
<url-pattern>/url1/*</url-pattern>
</servlet-mapping>
Yes, it is absolutely OK. Depending on app complexity and architecture, it actually may become very useful. You can use it to structure the application on dispatcher level (rather than on controllers). Or when you want certain URL classes to have different dispatcher configuration (view resolvers, locale resolvers, etc.)
You don't necessarily need multiple instances of the same servlet, unless you'd like to give them each different init-param values. I'd rather just assign different mappings to the same servlet like so:
<servlet>
<servlet-name>springDispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>2</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>springDispatcherServlet</servlet-name>
<url-pattern>/url1/*</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>springDispatcherServlet</servlet-name>
<url-pattern>/url2/*</url-pattern>
</servlet-mapping>
That's also perfectly valid for the case you didn't knew that.
Yeah, that's fine. The only downside is that the application contexts for each of the servlets won't be able to talk to each other, but it's a perfectly valid approach.
I would suggest, though, that it's generally better to have just the one DispatcherServlet, and handle all request routing within that. It's one less thing to go wrong.
Depends on your needs of course, but in most cases better to have one servlet.
So you can simplify you config to:
<servlet>
<servlet-name>servlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>2</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>servlet</servlet-name>
<url-pattern>/url2/*</url-pattern>
<url-pattern>/url1/*</url-pattern>
</servlet-mapping>