Dispatcher Servlet Mapping - Spring Framework - spring

I am new to Spring Framework and I was wondering why every time we create a new Spring project and we set the dispatcher mapping as / instead of the default *.htm.
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
Thanks!

1.<url-pattern>*.html</url-pattern>:
we are specifying the servlet class DispatcherServlet that acts as the front controller in Spring Web MVC. All the incoming request for the .html file will be forwarded to the DispatcherServlet.
2.<url-pattern>/</url-pattern> :
A mapping that contains the pattern <url-pattern>/</url-pattern> matches a request if no other pattern matches. This is the default mapping. The servlet mapped to this pattern is called the default servlet.The default mapping is often directed to the first page of an application.
Thanks..

Related

java.lang.IllegalStateException: Cannot forward after response has been committed while including HTML files using jsp:include

When <jsp:include> is used for including HTML file DispatcherServlet is throwing
java.lang.IllegalStateException: Cannot forward after response has been committed
I have one servlet:
<servlet-mapping>
<servlet-name>web</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
In it, I have enabled Spring MVC annotations and have handler mapping and adapter for JSP files without controllers (converting old webapp to Spring). And I have enabled DefaultServletHttpRequestHandler in this Servlet.
Any idea how to avoid that IllegalStateException when including html files?
So if you let spring handle all html files, it will always fail on jsp:include because spring cannot handle html includes.
Best way around this for me was to leave html files on default servlet.
<servlet-mapping>
<servlet-name>default</servlet-name>
<url-pattern>*.html</url-pattern>
<url-pattern>*.htm</url-pattern>
</servlet-mapping>
and leave rest on DispatcherServlet.
<servlet>
<servlet-name>web</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>web</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
This is definitely not a best solution, but until I convert all jsps (around 1000 of them) to mvc and something like tiles this is the only way I can see it working.
It is illegal to call forward() after some response is written to the output stream. The response may have been already sent to the client.
This article Causes of Response already committed explains why response is already committed.
I tried the proposed solution which declares the default servlet mapping for *.html url patterns and it worked fine. The only problem was that it introduced some side effects in my case (an hybrid webapp, spring and non-spring managed): html files that should have been managed by Spring's front controller now were managed by Tomcat's default controller.Fortunately, I found a couple of solutions with zero impact on the rest of the webapp.
Use .jsp file extension instead of .html. Spring won't complain if
it finds <jsp:include page="file.jsp" /> instead of <jsp:include page="file.html" />
Include the .html file in a scriptlet <%=file.html %> and avoid using the jsp "include" tag

Spring MVC DispatcherServlet mapping / vs /*

<servlet>
<servlet-name>springmvcdemo</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>springmvcdemo</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
vs
<servlet>
<servlet-name>springmvcdemo</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>springmvcdemo</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
I know there are duplicated questions but i'm still confused. My understanding is that when using /* , every request will go through this servlet (It means all .jsp, .html,etc will end up in this ). / will make this servlet the default servlet ( if there are exact URL installed..., return ) But it seem to me that when using / every request all still go through The DispatcherServlet no matter what. I can't open any .jsp file directly. Can someone explain to me more about this?
As per the Servlet specification, mapping for "/" means default servlet meaning if there is no explicit servlet matching the request, then this default servlet would be serving the request. For e.g., there is a servlet named "default" defined in Tomcat server common configuration web.xml which is inherited by all applications. This servlet serves the static contents like css,images etc which are typically not mapped in applications web.xml. Similarly there is a special Servlet which handles requests for jsp files ( all request ending with *.jsp as naturally these will be needed to be compiled to Servlets which would then process the request). So if you override the default servlet to be any other servlet in the application web.xml, then all requests not handled by any other servlet goes to this servlet and if this Servlet is not capable to serving request, it will not work.
If you declare Spring dispatcher servlet as the default Servlet, then you will not be able to serve static contents from container provided Servlet. Instead there is a special handler provided which can load static resources from configurable path pattern from directory / classpath. You need to use <mvc:resources/> tag for this feature. However if you still want to use container provided Servlet for serving resource you would need to use
<mvc:default-servlet-handler/> in the spring configuration. You can read more about this approach and its prons/cons here - section 15.12.4

What's the different between url-pattern

I am learning Spring MVC .
To configure servlet mapping in web.xml.
Who can tell what's difference between them
<servlet-name>login</servlet-name>
<url-pattern>/login/</url-pattern>
<servlet-name>login</servlet-name>
<url-pattern>/login</url-pattern>
<servlet-name>login</servlet-name>
<url-pattern>/</url-pattern>
<servlet-name>login</servlet-name>
<url-pattern>/*</url-pattern>
<servlet-name>login</servlet-name>
<url-pattern>/*.do</url-pattern>
Maybe more...
It is really necessary for me to know ,so that a new servlet will not be Intercept by other ones.
<servlet-name>login</servlet-name>
<url-pattern>/login</url-pattern>
This is exact url pattern, this servlet will be invoked only if the url is like someThing.com/login
<servlet-name>login</servlet-name>
<url-pattern>/*</url-pattern>
This is directory url pattern. So /someString or /someOtherString or /some/someOther will invoke the same login servlet.
<servlet-name>login</servlet-name>
<url-pattern>/*.do</url-pattern>
This is extension url pattern. Anything that is suffixed as .do will map to this. e.g. /someUrl.do or /some/someOther.do will invoke the login servlet.
this looks rather strange,you have this
<servlet-name>login</servlet-name>
<url-pattern>/*</url-pattern>
and thats all you need, the rest of the mapping are supercilious. But calling your spring servlet login is a bit weird. Normally you would call it spring-servlet or similar, everything is then mapped to that servlet, and specific request mappings are handled by different controllers - you can use RequestMappign annoation on controller methods.

Spring: How to redirect non-dispatcher requests to dispatcher?

I have standard servlet-mapping for Dispatcher Servlet - /app/*. I have controller that handle /notify requests. I need to expose this controller as servlet on http://[SERVER]/notify. How to simple redirect all requests from http://[SERVER]/notify to http://[SERVER]/app/notify (but without other tools, like urlrewrite) ? I know i can write simple servlet instead of, and set servlet-mapping in web.xml, but want to have controller, not servlet ;)
<servlet-mapping>
<servlet-name>Spring MVC Dispatcher Servlet</servlet-name>
<url-pattern>/app/*</url-pattern>
</servlet-mapping>
Controller:
#Controller
public class PaymentNotificationController {
#RequestMapping("/notify")
void notify() { ... }
}
You can put another Dispatcher Servlet in
<servlet-mapping>
<servlet-name>Notification Spring MVC Dispatcher Servlet</servlet-name>
<url-pattern>/notify/*</url-pattern>
</servlet-mapping>
and configure it with the same XML file as your main dispatcher servlet.
Don't discount urlrewrite - it only takes nanoseconds to execute, and years have gone into making it as fast as possible.
If you do throw up another Spring MVC servlet, you'll wind up with a second application context, which may not be desirable. DispatcherServlet is a front controller, of which there is supposed to be one - so yes - you can put as many as you want in, but they're almost like little mini-apps inside your WAR.

Loading spring context in web application after some servlet

We need to load the spring application context in our web application after one of our servlets is initialized, so I wonder what is the best way to do it?
I know that it's recommended to use the listener in web.xml, but it's obviously not good for us because in this case the context will be loaded before the first servlet. I saw that there was this class - ContextLoaderServet - in Spring 2.5, but it's absent in Spring 3.0. So I guess we should write some dummy servlet ourselves with the sole purpose of loading the context? Is there any better way?
Thanks.
OK, so if you have this legacy servlet that sets stuff up, then you will need to persuade the Spring servlet to load after it.
This is straightforward - use Spring's DispatcherServlet to load the Spring context, and use the standard <load-on-startup> in web.xml to dictate the startup order, e.g.
<servlet>
<servlet-name>LegacyServlet</servlet-name>
<servlet-class>com.xy.LegacyServlet</servlet-class>
<load-on-startup>0</load-on-startup>
</servlet>
<servlet>
<servlet-name>SpringServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>

Resources