Multiple SpringDispatcherServlet to handle different url - java

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>

Related

Servlet not opening the welcome page [duplicate]

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

Override the "default servlet" behaviour for URL pattern "/" in web.xml

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>

weblogic server not serving html, js and css files

I have deployed a sample spring java application to weblogic server (11g, 10.3.6). I have index.html at the root and I set that as the welcome-file in web.xml. But when I try to access the application, I am getting 'Error 404 -- Not Found'. Also, I noticed same issue with js and css files.
index.jsp works fine at the same location.
Here is my web.xml.
<display-name>hello</display-name>
<welcome-file-list>
<welcome-file>/index.html</welcome-file>
</welcome-file-list>
<servlet>
<servlet-name>appServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:/applicationContext.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>appServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>appServlet</servlet-name>
<url-pattern>*.html</url-pattern>
</servlet-mapping>
The reason for this is the root level mapping(/) for your Spring DispatcherServlet. All the requests are forward to Spring servlet:
<servlet-mapping>
<servlet-name>appServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
I workaround this situation by using *.do for my Spring controllers and update the servlet mapping as mentioned here:
<servlet-mapping>
<servlet-name>appServlet/servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
But this will require you to update the 'calls to your Spring controller' with a .do at the end of the URLs.

I can't add a Servlet on my project

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.

Servlet Mapping using web.xml

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

Categories