After Request Filtering Why It Is Going to Filter Again

Cover image for JAVA SpringBoot request filters

Ahmed Ashraf

Coffee SpringBoot request filters

Intro

Filter provides a user-friendly mechanism for inspecting and filtering HTTP requests entering your application. For instance, you want to inject a custom header to a request/response based on some conditions, or y'all desire to run some checks before accessing the controller and serve the request.

Bad

Sometimes nosotros meet people implement those kinds of checks and assertions in the controller. aye, information technology works but it's non the all-time place to put information technology there.

Skillful

Use Filters which it runs before accessing the controllers and serve your requests.

Filters period

filters-flow

Easily On

How to write?

In lodge to create a request filter. you just need to create a class that implements the Filter interface.

                          package              com.ahmedash95.instance.filters              ;              import              javax.servlet.*              ;              @Component              public              class              RoomsCreateFilter              implements              Filter              {              @Override              public              void              doFilter              (              ServletRequest              request              ,              ServletResponse              response              ,              FilterChain              chain              )              throws              IOException              ,              ServletException              {              // your code goes here.              // then you lot demand to laissez passer it in the concatenation.                            chain              .              doFilter              (              request              ,              response              );              }              }                      

Enter fullscreen manner Exit fullscreen style

If you lot are non familiar with the code in a higher place. hither are some clarifications:

  • @Component is an note that allows us to register the class equally a edible bean in the ApplicationContext
  • implements Filter interface tells Spring how this class should be used when register via @Component
  • import javax.servlet.*; imports Filter, ServletRequest, ServletResponse, FilterChain, and ServletException.
  • chain.doFilter(request, response); at the end is a must. every bit it tells bound how to continue handling the asking. without it the response will be empty equally the chain got broken.

Return response on errors

If you validate something and want to end processing the request and merely render the response. you can simply modify the Response object and render it from your Filter class.

                          @Override              public              void              doFilter              (              ServletRequest              request              ,              ServletResponse              response              ,              FilterChain              chain              )              throws              IOException              ,              ServletException              {              boolean              valid              =              false              ;              // check for something              if              (!              valid              )              {              ((              HttpServletResponse              )              response              ).              setStatus              (              422              );              response              .              getOutputStream              ().              write              (              "Validation error"              .              getBytes              ());              return              ;              }              concatenation              .              doFilter              (              request              ,              response              );              }                      

Enter fullscreen way Exit fullscreen mode

Examples

Let's write some existent-world examples and some unlike scenarios to make certain you get the full picture show.

i.Ensure API key is provided and valid

Let's say you are working on API that provides something. and you want to ensure that all requests to your application will have the API central and the key is valid. of course, you don't want to do the key validation to be in every controller and method.

Let'southward start by creating our filter first

                          package              com.example.demo              ;              import              coffee.io.IOException              ;              import              javax.servlet.*              ;              import              javax.servlet.http.HttpServletRequest              ;              import              javax.servlet.http.HttpServletResponse              ;              import              org.springframework.stereotype.Component              ;              @Component              public              class              APIKeyValidatorFilter              implements              Filter              {              @Override              public              void              doFilter              (              ServletRequest              request              ,              ServletResponse              response              ,              FilterChain              concatenation              )              throws              IOException              ,              ServletException              {              HttpServletRequest              req              =              (              HttpServletRequest              )              request              ;              String              key              =              req              .              getHeader              (              "X-API-Primal"              );              if              (              key              ==              cypher              )              {              ((              HttpServletResponse              )              response              ).              setStatus              (              401              );              response              .              getOutputStream              ().              write              (              "API Key is missing!"              .              getBytes              ());              return              ;              }              if              (!              KeyValidator              .              valid              (              fundamental              ))              {              ((              HttpServletResponse              )              response              ).              setStatus              (              403              );              response              .              getOutputStream              ().              write              (              "API Key is invalid"              .              getBytes              ());              return              ;              }              chain              .              doFilter              (              asking              ,              response              );              }              }                      

Enter fullscreen style Leave fullscreen mode

As you lot run into. we basically do some checks. if the cardinal is not provided we show the key missing error message. if is provided but not valid nosotros evidence The cardinal is an invalid message.

2.Ratelimit some endpoints

Let's say you want to protect the Post /annotate endpoint. so your users must not be able to submit more than than 2 comments in one minute. Again it can be washed in the controller simply It's not the all-time place to practice it.

Let's create the Filter form

                          bundle              com.example.demo              ;              import              javax.servlet.Filter              ;              import              java.io.IOException              ;              import              javax.servlet.*              ;              import              javax.servlet.http.HttpServletResponse              ;              public              course              PostCommentRateLimit              implements              Filter              {              RateLimiter              rateLimiter              ;              public              PostCommentRateLimit              (              RateLimiter              rateLimiter              )              {              this              .              rateLimiter              =              rateLimiter              ;              }              @Override              public              void              doFilter              (              ServletRequest              asking              ,              ServletResponse              response              ,              FilterChain              chain              )              throws              IOException              ,              ServletException              {              int              userId              =              1              ;              // Become User              boolean              valid              =              rateLimiter              .              validate              (              Cord              .              format              (              "ratelimit.user.comments:%d"              ,              userId              ),              two              );              if              (!              valid              )              {              ((              HttpServletResponse              )              response              ).              setStatus              (              429              );              response              .              getOutputStream              ().              write              (              "Also Many Requests"              .              getBytes              ());              return              ;              }              chain              .              doFilter              (              request              ,              response              );              }              }                      

Enter fullscreen mode Get out fullscreen style

Few things to explain here:

  • We did non employ @Component hither. because we want to use the filter on Mail service /comment endpoint only. so nosotros will annals information technology ourself next.
  • We have RateLimiter in constructor. and you lot don't need to worry about it. use whatever library fits your needs.

Equally mentioned nosotros did not use @Component considering information technology would apply the filter for all requests. instead nosotros will create some other class to annals our filters the way we want.

                          package              com.example.demo              ;              import              org.springframework.beans.factory.annotation.Autowired              ;              import              org.springframework.boot.spider web.servlet.FilterRegistrationBean              ;              import              org.springframework.context.note.Bean              ;              import              org.springframework.context.annotation.Configuration              ;              @Configuration              public              class              RequestsFilterRegister              {              @Autowired              RateLimiter              rateLimiter              ;              @Bean              public              FilterRegistrationBean              <              PostCommentRateLimit              >              registerPostCommentsRateLimiter              (){              FilterRegistrationBean              <              PostCommentRateLimit              >              registrationBean              =              new              FilterRegistrationBean              <>();              registrationBean              .              setFilter              (              new              PostCommentRateLimit              (              rateLimiter              ));              registrationBean              .              addUrlPatterns              (              "/comment"              );              return              registrationBean              ;              }              }                      

Enter fullscreen fashion Leave fullscreen mode

  • We created RequestsFilterRegister as @Configuration class
  • The but method there registerPostCommentsRateLimiter to annals the filter as nosotros want.
  • we used addUrlPatterns to apply the filter only on /comment endpoint.

Now we have i minor problem. the filter is applied to any method on /annotate either GET or Postal service. and to fix that we just demand to modify the PostCommentRateLimit@doFilter to skip if the method is not post

                          HttpServletRequest              req              =              (              HttpServletRequest              )              request              ;              if              (!              req              .              getMethod              ().              equals              (              "Mail service"              ))              {              concatenation              .              doFilter              (              request              ,              response              );              render              ;              }                      

Enter fullscreen mode Exit fullscreen mode

Now the full class is

                          packet              com.instance.demo              ;              import              javax.servlet.Filter              ;              import              coffee.io.IOException              ;              import              javax.servlet.*              ;              import              javax.servlet.http.HttpServletRequest              ;              import              javax.servlet.http.HttpServletResponse              ;              public              class              PostCommentRateLimit              implements              Filter              {              RateLimiter              rateLimiter              ;              public              PostCommentRateLimit              (              RateLimiter              rateLimiter              )              {              this              .              rateLimiter              =              rateLimiter              ;              }              @Override              public              void              doFilter              (              ServletRequest              asking              ,              ServletResponse              response              ,              FilterChain              chain              )              throws              IOException              ,              ServletException              {              HttpServletRequest              req              =              (              HttpServletRequest              )              request              ;              if              (!              req              .              getMethod              ().              equals              (              "POST"              ))              {              concatenation              .              doFilter              (              asking              ,              response              );              return              ;              }              int              userId              =              one              ;              // Get User              boolean              valid              =              rateLimiter              .              validate              (              String              .              format              (              "ratelimit.user.comments:%d"              ,              userId              ),              2              );              if              (!              valid              )              {              ((              HttpServletResponse              )              response              ).              setStatus              (              429              );              response              .              getOutputStream              ().              write              (              "Too Many Requests"              .              getBytes              ());              render              ;              }              chain              .              doFilter              (              request              ,              response              );              }              }                      

Enter fullscreen mode Get out fullscreen mode

Conclution

Now you know What is Request Filters, how to write them, and y'all applied some real-world examples. also you saw how to customize the routes and methods to utilize filters on.

The full source code https://github.com/ahmedash95/java-spring-request-filters

For more, you can check baeldung.com/spring-boot-add-filter

Note

I'thou yet learning Java and jump. and then if yous encounter any mistakes or a better mode in writing Filters Your comments and suggestions volition be greatly appreciated.

eastercombehe.blogspot.com

Source: https://dev.to/ahmedash95/java-springboot-request-filters-15ha

0 Response to "After Request Filtering Why It Is Going to Filter Again"

Post a Comment

Iklan Atas Artikel

Iklan Tengah Artikel 1

Iklan Tengah Artikel 2

Iklan Bawah Artikel