Relationship between Spring DispatcherServlet and Filters - spring

Spring MVC uses a DispatcherServlet to route control to an appropriate Controller. But where do filters fit into the flow? If I specify a filter to perform session management or authentication, will the filters always be called before DispatcherServlet?
My confusion comes from the fact that they both specify a URL pattern. What happens if they both provide the same url pattern?

This is not really specific to Spring and Spring MVC. In general fitlers are always called before servlets. When you have several filters and one servlet matching given URL pattern, all filters are executed first in the order of <filter-mapping> definitions and the servlet is executed last.
This way you can modify the request on the fly or even ignore the servlet altogether.

Related

Will multiple dispatcherservlet will share controller and other components in spring MVC?

Will multiple dispatcherservlet will share controller and other components in spring MVC
They are working by servlet specification which means that they won't share. It will just for different URI mappings dispatch by different servlets as it suppose to be for servlet. Those controllers should present in web application context provided for dispatcherServlet instance. You can reuse controllers from different contexts.
Dispatcher servlet should be just one as it implements front controller pattern. I don't understand why you need multiple instances in the first place.

Can I use Jersey as both servlet and filter in Spring Boot?

According to Spring documentation:
You can also use a Filter instead of a Servlet by setting spring.jersey.type=filter (in which case the #Bean to replace or override is jerseyFilterRegistration).
According to the answers to this question:
Use a Filter when you want to filter and/or modify requests based on specific conditions. Use a Servlet when you want to control, preprocess and/or postprocess requests.
So what if want to use Jersey with Spring Boot, to both serve json content and apply filters such as checking for authorisation and adding headers to all responses? The spring documentation reads like I have to choose either filter or servlet role for Jersey.
Can I do both with Jersey in a Spring Boot application and if so, how ?
So what if want to use Jersey with Spring Boot, to both serve json content and apply filters such as checking for authorisation and adding headers to all responses?
This question doesn't really make much sense.
Jersey itself is a processing engine. All it needs from the servlet container is the HttpServeltRequest and HttpServletResponse to start processing the request. These can be obtained both as a servlet Filter, or as a servlet HttpServlet. And if you look at the main Jersey servlet container component, ServletContainer, you will see that it both extends HttpServlet and implements Filter.
So being able to configure Jersey as a filter or as a servlet is not anything specific to Spring Boot; Jersey is designed this way. You could configure Jersey as a filter or servlet without Spring Boot.
As far as the filter system, Jersey has it's own filter system, independent of any servlet APIs. But if you want to use servlet filters, there's no reason you can't, whether or not you configure Jersey as a filter or as a servlet. If you understand the servlet filter chain, then you will know that filters get called one after the next, then the servlets are called. So if you want to add a filter and have it perform before the Jersey filter, you can do that. Or if Jersey is a servlet, your filter will be called before the Jersey servlet. Either way it is the same result. Jersey doesn't change any processing behavior just because it is a filter or if is a servlet.
The spring documentation reads like I have to choose either filter or servlet role for Jersey
Yes Servlet or Filter. Should be clear from what I mentioned above. You can have more than one servlet filter. Filters happen one after the other. You can add a filter that has nothing to do with Jersey. They all get passed the same ServletRequest and ServletResponse, so they all interacting with the same request and response. If you want to create a filter to add headers, then do it. It doesn't need to know anything about Jersey.
If you want to create Jersey specific filters (which is independent of any servlet filter mechanisms) for auth/headers and such, you can look at Filters and Interceptors (you can see an auth example in this great answer).
If you want to add servlet filters, then you can do so with FilterRegistrationBeans in Spring Boot.
#Bean
public FilterRegistrationBean anotherFilter() {
}

Servlets in spring mvc

I have fundamental idea about servlet and spring mvc. But I don't know that there is a usage of servlets in spring mvc or not. In spring mvc we have controller classes. My thinking is servlet is used in spring mvc as a controller. If I'm incorrect please correct me.
Yes,you are perfectly right. Servlets are used in Spring-MVC. In Spring-MVC when you write annotation like #Controller, indirectly you are using a Servlet called Dispatcher Servlet. Dispatcher Servlet is defined in web.xml file with properties and class name which is mapped to .jsp pages and Controller part.
Related / Duplicated to When to use Servlet or #Controller. The question is not the same but quite the explanation on that question you will be able to understand:
If you're a student interested in learning the language then I would stick with servlets for now. It's possible to write a web app using just servlets but in practice you'll probably want to look at JSP's too.
A JSP is a convenient way to write a servlet that allows you to mix html with scripting elements (although it's recommended to avoid Java code in your jsp in favour of tags and el expressions). Under the covers it will be compiled as a servlet but it avoids you having to use lots of messy print statements.
It's important to have at least a basic understanding of servlets and JSP's. Spring MVC is one of many frameworks built on top of servlets to try make the task of writing a web application a bit easier. Basically all requests are mapped to the DispatcherServlet which acts as a front controller.
The DispatcherServlet will then call the controller whose annotations match the incoming request. This is neater than having to write these mappings yourself in the web.xml (although with servlet 3.0 you can annotate servlets now). But you also get many other benefits that can be used like mapping form fields to an object, validating that object with jsr303 annotations, map inputs and outputs to xml or json etc etc. Plus it's tightly integrated with core spring so you can easily wire in your services for the controller to call.
It's worth noting that there are a plethora of competing frameworks built on top of servlets. Spring MVC is one of the most popular so it's not a bad choice to look into.
Controllers are not Servlets! Controllers are normal Spring MVC beans that do not extend HttpServlet. Instead what Spring has is a custom extension of HttpServlet called DispacherServlet. Looking at the DispacherServlet's source code you can see that the class hierarchy goes: DispatcherServlet extends FrameworkServlet → FrameworkServlet extends HttpServletBean → HttpServletBean extends HttpServlet.
The DispatcherServlet, like any other Servlet, is declared in the web.xml. It handles all incoming HTTP requests. It is called a front controller which provides a single point of entry in your application. It is responsible for request handling by delegating requests to additional components of Spring MVC controllers which do not extend the HTTP Servlet API.
Look at the following diagram
In this picture DispacherServlet is the only HttpServlet. The Controllers, HandlerMapping and ViewResolver are all Spring MVC beans.

Integrating Spring request scope with JSF controllers

I am working on a project that uses a hybrid of JSF and Spring-MVC. User interface endpoints are accessed through a JSF front controller (javax.faces.webapp.FacesServlet), whereas REST service calls are accessed through a Spring-MVC front controller (org.springframework.web.servlet.DispatcherServlet). Deeper layers are Spring-managed (more-or-less). I don't like this arrangement, but I'm not in a position to change it.
The problem is that Spring's request-scoped beans aren't initialized when processing requests that come in through the JSF front controller. Is there an off-the-shelf solution for integrating Spring's WebApplicationContext with the JSF machinery so that the Spring request-scoped beans are initialized for each request regardless of whether that request comes through the JSF or Spring servlet?
There are two ways to integrate JSF with Spring, depending on which framework you want to give most control:
JSF front controller:
One way is to route all requests via the JSF faces servlet and let JSF route them to controllers, let JSF manage navigation state via faces-config. Then inject spring beans into JSF managed beans and access spring beans from the facelets view using value expressions via SpringBeanFacesELResolver.
See this post for a working example.
Spring front controller: put spring as a front controller with a dispatcher servlet and put in place spring webflow. This is the preferred and most powerful way to integrate the two frameworks, see this section of the documentation.
Spring webflow will manage the navigation state and the faces config file is mostly empty. There is no need for the JSF managed beans layer, request get directly handled by webflow.
Actions in JSF buttons trigger webflow transitions directly, and spring beans can also be used in value expressions to build the view. With this solution the integration with Spring is more seamless as webflow offers more possibilities then the JSF navigation mechanism: trigger bean methods between transitions, post redirect get pattern for avoiding double submissions.
Namelly the problem with the initialization of spring request scoped beans is solved with this direction, altough an alternative for this is to add a RequestContextListener OR a RequestContextFilter to web.xml (see section 3.4.4.1 of the docs).

LocaleResolver in filter null yet shows it has been autowired! Spring MVC 3.1.1/Spring Security 3.1.0

I am using Spring Security 3.1.0 and Spring MVC 3.1.1.
I would like to be able to change the locale based on URL i.e.:
http://localhost:8080/abc?lang=fr
Now, this works under "normal" circumstances, i.e. going from one page to another page HOWEVER, in my application, if I go from a non-secure page to a secure page, it first hit's my login page, courtesy of Spring Security BEFORE it hits the page I want.
This is normal Spring Security behaviour (to intercept a secure resource) so there are no problems with this behavuour.
The problem is rather that the locale does not change when I arrive at the secured page! It stays as the default locale. i..e lang=fr is not parsed out.
I have played with defining the locale related beans inside dispatcher-servlet.xml AND outside, in an app-context file to do the following:
<mvc:interceptors>
<bean class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor" p:paramName="lang" />
</mvc:interceptors>
<bean id="localeResolver" class="org.springframework.web.servlet.i18n.SessionLocaleResolver" p:defaultLocale="en" />
I have also tried to split up the above 2 beans, having just localResolver in the app-context config.
I have done TONS of research on this and basically, I understand I need to change the locale manually.
Even the Spring Docs for Spring Security 3.1.0 say that you need your own "filter" or you can use RequestContextFilter. RequestContextFilter, however does not parse out the locale param in the query String.
Spring Security relies on Spring's localization support in order to actually lookup
the appropriate message. In order for this to work, you have to make sure that the
locale from the incoming request is stored in Spring's
org.springframework.context.i18n.LocaleContextHolder. Spring MVC's DispatcherServlet
does this for your application automatically, but since Spring Security's filters are
invoked before this, the LocaleContextHolder needs to be set up to contain the correct
Locale before the filters are called. You can either do this in a filter yourself
(which must come before the Spring Security filters in web.xml) or you can use
Spring's RequestContextFilter.
I would like to intercept the request BEFORE it hits the Controller and so, I have written my own filter.
My solution, based on what others have done as well, is to autowire the LocaleResolver. When tomcat fires up, it shows in my logs that "localeResolver" has been autowired (otherwise the app would fail right there) HOWEVER at run time, localeResolver is NULL.
Again, there have been posts that say to define LocaleResolver in the application-context...I have done so but I still end up getting a null LocaleResolver when a request happens.
Any ideas?? Much appreciated.
p.s. the filter I have defined comes before the Spring Security filters. I can debug it, it hits it first but then it dies because of the NPE on LocaleResolver.
Appreciate this, thanks.
Did you define the filter in web.xml? If so, then the filter class is not instantiated by Spring, it is instantiated by the servlet container. Spring cannot autowire what it does not know about.
The general solution here is to declare the <filter-class> in web.xml as org.springframework.web.filter.DelegatingFilterProxy and point the targetBeanName at a bean in your context, such as:
<filter>
<filter-name>My Locale Filter</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
<init-param>
<param-name>targetBeanName</param-name>
<param-value>myLocaleFilter</param-value>
</init-param>
</filter>
And in your Spring context, <bean id="myLocaleFilter"> should point at your Filter class.
You might also find it convenient for your custom Filter class to extend GenericFilterBean rather than implementing the Filter interface directly.

Resources