After Request Filtering Why It Is Going to Filter Again Sprring Boot App
Spring Web applications and RESTful services contain controllers responsible to process requests and send back responses. At times y'all might demand to perform sure operations on client requests before it reaches the controller. Similarly, yous might demand to perform operations on responses sent back by controllers to clients. You tin achieve this using filters in Spring Web applications.
Filters are implementations of the Filter
interface of Java EE. Bound brings in its ain filter implementation with the GenericFilterBean
abstract class.
Some of the common employ cases of filters are:
- Logging requests and response
- Logging asking processing fourth dimension
- Formatting of asking torso or header
- Verifying authentication tokens
- Compressing response
- Performing Image conversions
In this mail service, y'all will learn how to configure filters in Spring Boot applications.
Filter Interface Methods
The Filter
Interface contains the following three methods:
-
init()
: The web container calls this method to indicate to a filter that it is beingness placed into service. The container calls this method only once. during the lifecycle of the filter instance. Theinit()
method must complete successfully before the filter is asked to practice whatsoever filtering work. The web container cannot identify the filter into service if theinit()
method either:- Throws a
ServletException
- Does not return within a time period divers by the web container
- Throws a
-
doFilter()
: The Web container invokes this method every time whenever the client sends a asking or the application sends dorsum a response. It is in this method where you perform functioning on the request and response objects. -
destroy()
: The Spider web container calls this method to signal to a filter that it is being taken out of service. The container calls this method only one time during the lifecycle of the filter case. This method gives the filter an opportunity to clean upwards any resources that are being held. For example, memory, file handles, and threads.
Notation: The GenericFilterBean
abstract class of Jump implements the Filter
interface. The course leaves bodily filtering to subclasses, which have to implement the doFilter()
method.
Filter Example
This example demonstrates configuring filters in Spring Web applications.
Maven Dependency
For this demo, you volition need the spring-boot-starter-web
andlombok
dependencies in your pom.xml
.
pom.xml
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-kick-starter-web</artifactId> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.eighteen.twenty</version> </dependency>
The Domain Form
The lawmaking of the MemeMaker
domain class is this.
Mememaker.java
@Getter @Setter public class MemeMaker { private int memeId; private String memeMaker; individual String memeTopic; individual String memeLevel; }
The preceding code uses Lombok
to reduce boilerplate code. If you are new to Lombok
, I suggest going through my post on Lombok.
This is code for the MemeController
class.
MemeController.java
@RestController @RequestMapping("/meme") public course MemeController { @GetMapping @ResponseBody public MemeMaker getMemeMakerDetails() { MemeMaker memeMaker = new MemeMaker(); memeMaker.setMemeId(one); memeMaker.setMemeMaker("Alex"); memeMaker.setMemeLevel("Noobie"); memeMaker.setMemeTopic("Trending"); return memeMaker; } }
The preceding code annotates the controller class with @RestController
. It has one handler method getMemeMakerDetails()
for GET request. This method returns a MemeMaker
object.
The Filter Class
The side by side pace is to create a filter, like this
MemeFilter.java
parcel guru.springframework.springfilter.filter; import ch.qos.logback.archetype.Level; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Component; import javax.servlet.*; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; @Component @Slf4j public class MemeFilter implements Filter { @Override public void init(FilterConfig filterConfig) { log.debug("init() method has been get invoked"); log.debug("Filter name is "+filterConfig.getFilterName()); log.debug("ServletContext proper name is"+filterConfig.getServletContext()); log.debug("init() method is concluded"); } @Override public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { log.debug("doFilter() method is invoked"); HttpServletRequest httpServletRequest = (HttpServletRequest)servletRequest; HttpServletResponse httpServletResponse = (HttpServletResponse)servletResponse; filterChain.doFilter(httpServletRequest, httpServletResponse); log.debug("doFilter() method is concluded"); } @Override public void destroy() { log.debug("destroy() method is invoked"); } }
The preceding code creates a filter class named MemeFilter
that implements the Filter
interface. The code annotates the grade with @Component
so that Spring detects it during component scanning. In addition, the MemeFilter
form overrides the methods of the Filter
interface to access the request and response objects and log information. To set the log level for logging to the console, add the following configuration to your application.backdrop file.
logging.level.guru.springframework=DEBUG
On running the application, the container invokes the init()
method. Nonetheless, the container is nevertheless to invoke thedoFilter()
method.
Open a browser and access http://localhost:8080/meme. This invokes the doFilter()
method.
Finally, stop the application. This invokes the destroy()
method.
Filter Apply Cases in Spring
The Spring Framework provides the GenericFilterBean grade to configure filters in Spring Web applications. This course is a Bound specific base implementation of the Filter
interface. Allow us look how to use GenericFilterBean
to perform some common operations in filters.
Verifying Authentication Tokens
JSON Web Tokens (JWT) is ane of the common authentication mechanism in Spring Boot Balance services. In this blazon of hallmark, client sends a JWT token to access a service. If you are working with microservices, instead of validating the token in each service, you can offload it to a filter. Such filter can intercept the request and validate the token before passing the request to a service for processing.
The following code shows an case of such filter.
packet guru.springframework.springfilter.filter; import javax.servlet.FilterChain; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.springframework.web.filter.GenericFilterBean; import java.io.IOException; import io.jsonwebtoken.*; public class JwtFilter extends GenericFilterBean { @Override public void doFilter(ServletRequest req, ServletResponse res, FilterChain filterChain)throws IOException, ServletException { final HttpServletRequest request = (HttpServletRequest) req; final HttpServletResponse response = (HttpServletResponse) res; terminal String authHeader = request.getHeader("authorization"); if ("OPTIONS".equals(request.getMethod())) { response.setStatus(HttpServletResponse.SC_OK); filterChain.doFilter(req, res); } else { if (authHeader == zip || !authHeader.startsWith("Bearer ")) { throw new ServletException("Missing or invalid Authorization header"); } concluding String token = authHeader.substring(7); final Claims claims = Jwts.parser() .setSigningKey("secretkey") .parseClaimsJws(token) .getBody(); request.setAttribute("claims", claims); filterChain.doFilter(req, res); } } }
Logging Request Processing Time
You can use filters to log asking processing time.
The following lawmaking shows an case of such a filter.
package guru.springframework.springfilter.filter; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Component; import org.springframework.web.filter.GenericFilterBean; import javax.servlet.FilterChain; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletRequest; import java.io.IOException; @Component @Slf4j public grade RequestProcessingTimeFilter extends GenericFilterBean { @Override public void doFilter(ServletRequest req, ServletResponse res, FilterChain filterChain)throws IOException, ServletException { long time = System.currentTimeMillis(); effort { filterChain.doFilter(req, res); } finally { time = System.currentTimeMillis() - time; log.debug("Asking was processed in: {}: {} ms ", ((HttpServletRequest) req).getRequestURI(), time); } } }
On running the application and sending a request, you can see the request processing time in milliseconds on the console.
Filter Ordering in Filter Chain
I accept shown configuring multiple filters in a Spring Web awarding. These filters tin together form a filter chain in an application. A request goes through the concatenation of filters and reach the controller unless a filter throws some exception to stop the request flow.
When you have multiple filters forming a filter chain, you tin ready the invocation club of the filters. There are 2 approaches.
If you are using the @Component
notation in the filter course, yous can set the ordering using the @Order
notation, like this.
@Component @Slf4j @Order(0) public class MemeFilter implements Filter { .... @Order(0) } @Component @Slf4j @Order(1) public class JwtFilter implements Filter { .... } @Component @Slf4j @Order(2) public course RequestProcessingTimeFilter implements Filter { .... }
The preceding configuration volition ready the filter chain, similar this.
The second arroyo is through Java configuration. In this arroyo you lot would have filter beans ordered and defined similar this.
packet guru.springframework.springfilter.config; import guru.springframework.springfilter.filter.MemeFilter; import guru.springframework.springfilter.filter.RequestProcessingTimeFilter; import org.springframework.boot.web.servlet.FilterRegistrationBean; import org.springframework.context.note.Bean; import org.springframework.context.annotation.Configuration; @Configuration public course FilterBeanConfig { @Bean public FilterRegistrationBean requestMemeFilter() { MemeFilter memeFilter=new MemeFilter(); final FilterRegistrationBean reg = new FilterRegistrationBean(memeFilter); reg.addUrlPatterns("/*"); reg.setOrder(1); //defines filter execution order render reg; } @Edible bean public FilterRegistrationBean requestRequestProcessingTimeFilter() { RequestProcessingTimeFilter requestProcessingTimeFilter =new RequestProcessingTimeFilter(); final FilterRegistrationBean reg = new FilterRegistrationBean(requestProcessingTimeFilter); reg.addUrlPatterns("/*"); reg.setOrder(two); //defines filter execution order return reg; } }
Summary
Developers often misfile between filters and Springs handler interceptor every bit both performs similar functions.
Handler interceptor is basically similar to a Servlet filter, but in contrast to the latter information technology just allows custom pre-processing with the pick of prohibiting the execution of the handler itself. Handler interceptor likewise allows custom postal service-processing. Filters are more powerful, for example they allow for exchanging the request and response objects that are handed downwardly the concatenation. Annotation that a filter gets configured in web.xml
, and handler interceptor in the application context.
As a basic guideline, fine-grained handler-related pre-processing tasks are candidates for handler interceptors, especially factored-out common handler code and authorization checks. On the other hand, a filter is well-suited for request content and view content treatment, similar multipart forms and GZIP compression. This typically shows when one needs to map the filter to certain content types (e.thousand. images), or to all requests.
You tin can notice the source code of this mail here on Github.
For in-depth knowledge on filters, you tin cheque my Udemy Best Seller Course Jump Framework 5: Beginner to Guru
Source: https://springframework.guru/using-filters-in-spring-web-applications/
0 Response to "After Request Filtering Why It Is Going to Filter Again Sprring Boot App"
Post a Comment