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. The init() method must complete successfully before the filter is asked to practice whatsoever filtering work. The  web container cannot identify the filter into service if the init() method either:
    • Throws a ServletException
    • Does not return within a time period divers by the web container
  • 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.

Output of init method
Open a browser and access http://localhost:8080/meme. This invokes the doFilter() method.
Output of doFilter method

Finally, stop the application. This invokes the destroy() method.

output of 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.

request processing time filter

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.

filter chain ordering

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

taylortomer1998.blogspot.com

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

Iklan Atas Artikel

Iklan Tengah Artikel 1

Iklan Tengah Artikel 2

Iklan Bawah Artikel