Can I use Jersey as both servlet and filter in Spring Boot? - 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() {
}

Related

Is it possible to use DispatcherServlet as fallback when using Jersey starter in Spring Boot and embedded Tomcat?

Is it possible to have Jersey application on / but still allow DispatcherServlet to serve static content (eg from classpath:/whatever/path/here/) as a fallback?
I have tried to map DispatcherServlet to / and use JersetContainer (or something like that) to act as Filter instead of Servlet, however Jersey fallsback to default container servlet implementation which is DefaultServlet in my case.
So is it possible to have Jersey as a filter on the same mapping path with DispatcherServlet ??

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.

Spring Boot on WildFly (or Undertow): Servlet Filter's orders are reversed

I deployed my Spring Boot Web application on WildFly 8.1, but now I have some trouble.
When application was deployed, FilterRegistrationBeans register Servlet Filters. I know FilterRegistrationBeans are oredered by AnnotationAwareOrderComparator, and those filters are registerd by that order. But when I access my application, Undertow calls filters by reversed order.
For example, if Spring Boot register filters like that:
errorPageFilter
metricFilter (from Spring Boot actuator)
characterEncodingFilter
hiddenHttpMethodFilter
springSecurityFilterChain (from Spring Security)
Undertow call those filters like that:
springSecurityFilterChain
hiddenHttpMethodFilter
characterEncodingFilter
metricFilter
errorPageFilter
How can I specify those filters order correctly? Some filter's order (like org.springframework.boot.context.web.ErrorPageFilter) was hard-coded in source, I can't specify that.
This appears to be an Undertow bug that occurs when matchAfter is false in FilterRegistrationImpl#addMappingForUrlPatterns, instead of inserting the filter before all declared filters it inserts it before all filters.

How can I include/exclude certain controllers from a DispatcherServlet

I have a DispatcherServlet which by default uses a RequestMappingHandlerMapping to find all controllers with #RequestMapping annotations.
This works fine, except that it picks up all controllers in my spring context, but I only want it to expose certain controllers.
Is there any way of doing this that doesn't involve extending a bunch of spring classes?
(Unfortunately my spring context has to contain these additional controllers as they also provide some functionality that I need to call using java, and I'm not able to split these up currently)
You can configure include/exclude filters to customize classpath scanning. This can be done both in XML Spring config or Java based #Configuration. So depending on how many #Controller annotated classes you need to exclude, you can either list them under assignable or use regex filter. See Spring docs section "Using filters to customize scanning" for details, e.g. for Spring 3.2.

Relationship between Spring DispatcherServlet and Filters

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.

Resources