Difference between "dispatcherServlet" and "appServlet" in spring MVC - spring

Difference between "dispatcherServlet" and "appServlet" in spring MVC. Can I get any samples or references?

Technically both are HttpServlet implementation to handle incoming requests. DispatcherServlet is Spring provided servlet implemenation having all essential features like exception handling ..
You have to just write your Request mappers ,it will handle all request.
AppServlet is nothing different, just your implementation for specific handling of requests.
Both will work in same way .If you dont have any specific handling than you can just go with Spring DispatcherServlet.
For example..
<servlet>
<servlet-name>DispatcherServlet</servlet-name>
<servlet-class>
org.springframework.web.servlet.DispatcherServlet
</servlet-class>
<load-on-startup>1</load-on-startup>
<!-- Custom Servlet -->
<servlet>
<servlet-name>CustomServlet</servlet-name>
<servlet-class>org.abc.CustomServlet</servlet-class>
<init-param>
<param-name>debug</param-name>
<param-value>false</param-value>
</init-param>
<init-param>
<param-name>any-other-Parameter</param-name>
<param-value>false</param-value>
</init-param>
<servlet-mapping>
<servlet-name>DispatcherServlet</servlet-name>
<url-pattern>*.do</url-pattern>
<url-pattern>/myapp/*</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>CustomServlet</servlet-name>
<url-pattern>/myapp2/*</url-pattern>
</servlet-mapping>
For reference of DispatcherServlet you can see http://www.mkyong.com/spring-mvc/spring-mvc-hello-world-example/

to understand this, you can have a look on below configuration :
<servlet>
<servlet-name>appServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring/servlet-context.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
In above configuration DispatcherServlet is the servlet class provided by spring framework.
The job of the DispatcherServlet is to take an incoming URI and find the
right combination of handlers (generally methods on Controller classes)
and views (generally JSPs) that combine to form the page or resource
that's supposed to be found at that location.
while appServlet is the custom name given by you in your web.xml file.

Related

Location of groovy based bean definition configuration in a Spring MVC application

I have seen that Spring 4 has a feature to define / having a groovy file for bean definitions instead of an XML file. I already have a Spring MVC application with mvc-dispatcher-servlet.xml for my bean definitions. But I want to go with Groovy based bean definition for my Spring MVC application. But, I am not sure where to place the groovy file and where do I need to refer it/ configure it to Load the bean definitions properly. Can somebody help or provide refrence?
use the GroovyWebApplicationContext ,
Web.xml
<servlet>
<servlet-name>mvc-dispatcher</servlet-name>
<servlet-class>
org.springframework.web.servlet.DispatcherServlet
</servlet-class>
<init-param>
<param-name>contextClass</param-name>
<param-value>
org.springframework.web.context.support.GroovyWebApplicationContext
</param-value>
</init-param>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:/spring/dispatcherServlet.groovy</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
this is not a full example, but it is a good start

cometd spring Request method 'POST' not supported for /cometd/handshake

Am try to integrate cometd(spring-jquery-jetty7) with the appfuse spring MVC project.
my web.xml is
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>2</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>/app/*</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>cometd</servlet-name>
<servlet-class>org.cometd.server.CometdServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>cometd</servlet-name>
<url-pattern>/cometd/*</url-pattern>
</servlet-mapping>
and did all other configuration like spring-jquery-jetty7 example, When i try cometd.handshake() from the script, it's failed and got error from the log like follows
WARN [http-8080-6] PageNotFound.handleHttpRequestMethodNotSupported(183) | Request method 'POST' not supported
115117 [http-8080-6] WARN org.springframework.web.servlet.PageNotFound - Request method POST' not supported
Anybody experience this? hope the dispatcher servlet process the request instead of cometd servlet, i dont know whats wrong in this, suggestion regarding this are welcome.
thank you
I resolve the issue by changing the servlet orders like cometd servlet first and dispatcher servlet second. The dispatcher servlet handle the cometd request first and throw the error always so i change the order like follows
<servlet>
<servlet-name>cometd</servlet-name>
<servlet-class>org.cometd.server.CometdServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>cometd</servlet-name>
<url-pattern>/cometd/*</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>2</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>/app/*</url-pattern>
</servlet-mapping>
and also add load-on-startup for initialize the comet servlet when application start. thank you

How to make Spring MVC and plain JSP live together in one application

Say I have a Spring MVC application with JPA as backend. Now here we want to provide simple UI to user to perform simple configuration to some properties file. It would make sense to make it separate from the main Spring application because some configuration is related to Spring MVC so it will fail when start the main application by the main UI through Spring MVC.
But how to register both servlet(Spring and plain JSP)in the same web application?
<!-- Handles Spring requests -->
<servlet>
<servlet-name>SpringApplication</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring/mvc-config.xml</param-value>
</init-param>
<load-on-startup>2</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>SpringApplication</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>PlainJSPApplication</servlet-name> <!--Is it ok to separate request to different servlet like this?-->
<servlet-class>com.app.plainJSP</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>PlainJSPApplication</servlet-name>
<url-pattern>/config</url-pattern> <!--How to handle mapping so not conflict to Spring main application-->
</servlet-mapping>
I think it is common to register another servlet class to in the SAME web.xml, is it OK? and also how to handle that request URL pattern, as "/" has been assign to Spring servlet?
Any advice would be appreciated.
You can separate Spring managed controllers and your own servlet by mapping both with different url patterns.
The requests for Spring controllers are managed by DispatcherServlet. Basically, it is just a Servlet that, when you map urls to it, it will automatically be seen by Spring, thus mapping it to the right controller, views etc.
web.xml
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>PlainJSPApplication</servlet-name> <!--Is it ok to separate request to different servlet like this?-->
<servlet-class>com.app.plainJSP</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>PlainJSPApplication</servlet-name>
<url-pattern>*.htm</url-pattern>
<url-pattern>*.html</url-pattern>
<url-pattern>*.bmk</url-pattern>
<!-- other url pattern ... -->
<!-- other url pattern ... -->
<!-- other url pattern ... -->
</servlet-mapping>
Here, all the requests end with .do will be seen by Spring. Others will then be seen by your servlets.
So, as long as you don't harm this mapping, Spring MVC & your normal servlets will integrate gracefully.

Spring-jersey how to expose services under more than one context

I use spring-jersey to expose rest services. My web.xml looks as follows:
<servlet>
<servlet-name>Jersey REST Service</servlet-name>
<servlet-class>com.sun.jersey.spi.spring.container.servlet.SpringServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>Jersey REST Service</servlet-name>
<url-pattern>/rest/*</url-pattern>
</servlet-mapping>
Let say standard.
I have a lot of rest services in many packages and I need to goup them in two context, let say "base" and "advanced" services. Moreover I need to get rid of the "rest" prefix in url-pattern. So I thought about group them into two packages and then in web.xml define two jersey servlets with com.sun.jersey.config.property.packages init param:
<servlet>
<servlet-name>Jersey REST Service</servlet-name>
<servlet-class>com.sun.jersey.spi.spring.container.servlet.SpringServlet</servlet-class>
<init-param>
<param-name>com.sun.jersey.config.property.packages</param-name>
<param-value>com.example.app.rest.base</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>Jersey REST Service</servlet-name>
<url-pattern>/base/*</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>Another Jersey REST Service</servlet-name>
<servlet-class>com.sun.jersey.spi.spring.container.servlet.SpringServlet</servlet-class>
<init-param>
<param-name>com.sun.jersey.config.property.packages</param-name>
<param-value>com.example.app.rest.advanced</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>Another Jersey REST Service</servlet-name>
<url-pattern>/advanced/*</url-pattern>
</servlet-mapping>
Unfortunately due to component scan set in applicationContext.xml
<context:component-scan base-package="com.example.app" />
property com.sun.jersey.config.property.packages is ignored (all rest services can be accessed under each context) and it cannot be handle like that.
I am wondering how can I deal with that in other way. The only thing which I don't want to do is to set
<url-pattern>/*</url-pattern>
that catch everyting.
You can specify multiple packages. Just separate them by a comma.
<context:component-scan base-package="com.example.app,com.sun.jersey" />
You can also define two component-scan items and they should work just as well, too.
If the package differentiation won't help, use a filter.
<context:component-scan base-package="org.example">
<context:include-filter type="regex" expression=".*Repository"/>
</context:component-scan>
And then, just make a separate applicationContext for each service but use an init-param of contextConfigLocation and init-value of the location/name of that app context. So, if you make a specific app context to load for each service, the component scan filtering will load everything you need for one service and exclude the other one.
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>WEB-INF/rest-service1.xml</param-value>
</init-paraam>
Actually, if you make a separate xml file for each, you can just go back to using the different package at that point, I believe.

How to add a Filter in Spring (with BlazeDS)

I want to add a filter to map a specific path in URL.
My server side used Spring 2.5.x, BlazeDS (servlet) with TomCat server.
So, my web.xml file is composed like that :
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/spring-main-config.xml
</param-value>
</context-param>
<filter>
<filter-name>FacebookOAuthFilter</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
<filter-name>FacebookOAuthFilter</filter-name>
<url-pattern>/fbauth</url-pattern>
</filter-mapping>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- Spring MVC Servlet (that will route HTTP requests to BlazeDS) -->
<servlet>
<servlet-name>Spring MVC Dispatcher Servlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring-main-config.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
When I start my TomCat server, an exception is catched :
[BlazeDS][ERROR] [Configuration] MessageBroker failed to start: Exception: flex.messaging.config.ConfigurationException: MessageBroker already defined from MessageBrokerServlet with init parameter messageBrokerId = '_messageBroker'
at flex.messaging.MessageBroker.registerMessageBroker(MessageBroker.java:1916)
COuld you help me please ?
Thank you very much,
Anthony
I believe you are loading the incorrect configuration file here...
<servlet>
<servlet-name>Spring MVC Dispatcher Servlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring-main-config.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
you have alreaded loaded /WEB-INF/spring-main-config.xml in the first few lines of the file
http://www.springbyexample.org/examples/simple-flex-webapp.html
This isn't really a Flex or BlazeDS issue, it's a more basic mis-configuration of Spring.
You're configured two separate Spring app-contexts, both with the same set of bean definitions (/WEB-INF/spring-main-config.xml).
The app-context defined by the <context-param> is the app-context associated with the webapp. The app-context defined by the ` is associated with the servlet.
Since you've given the same beans file to both, it'll instantiate and initialize the same set of beans twice, and the second time seems to be failing because the MessageBroker has already been defined.
You either need to break up your bean definitions into two sets, or just remove the first one, and just use the servlet context.

Resources