Bagaimana cara menambahkan kelas filter di Spring Boot?

229

Saya ingin tahu, apakah ada penjelasan untuk Filterkelas (untuk aplikasi web) di Spring Boot? Mungkin @Filter?

Saya ingin menambahkan filter khusus di proyek saya.

Panduan Referensi Boot Spring menyebutkan tentang FilterRegistrationBean, tetapi saya tidak yakin bagaimana menggunakannya.

petugas kebersihan
sumber
Perhatikan, bahwa Filter yang ditambahkan dengan @WebFilter tidak berperilaku seperti filter asli dalam spesifikasi Servlet. Ini akan menjadi kacang musim semi dipanggil setelah banyak kacang musim semi lainnya dan tidak seperti filter nyata sebelum kode servlet.
lrxw
dapatkah Anda memberi tahu saya persyaratan yang tepat. Jika Anda ingin memfilter kelas untuk ComponentScan maka ada anotasi untuk "@ ComponentScan.Filter" itu
Keaz

Jawaban:

159

Jika Anda ingin menyiapkan filter pihak ketiga yang dapat Anda gunakan FilterRegistrationBean. Misalnya setara dengan web.xml

<filter>
     <filter-name>SomeFilter</filter-name>
        <filter-class>com.somecompany.SomeFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>SomeFilter</filter-name>
    <url-pattern>/url/*</url-pattern>
    <init-param>
       <param-name>paramName</param-name>
       <param-value>paramValue</param-value>
    </init-param>
</filter-mapping>

Ini akan menjadi dua kacang di @Configurationfile Anda

@Bean
public FilterRegistrationBean someFilterRegistration() {

    FilterRegistrationBean registration = new FilterRegistrationBean();
    registration.setFilter(someFilter());
    registration.addUrlPatterns("/url/*");
    registration.addInitParameter("paramName", "paramValue");
    registration.setName("someFilter");
    registration.setOrder(1);
    return registration;
} 

public Filter someFilter() {
    return new SomeFilter();
}

Di atas diuji dengan spring-boot 1.2.3

Haim Raman
sumber
1
bagaimana jika saya ingin menambahkan beberapa filter? @Opal
verystrongjoe
8
Cukup tambahkan @Bean publik FilterRegistrationBean additionalFilterRegistration ()
Haim Raman
Bagaimana cara mengetahui urutan penerapan filter?
BeepDog
7
FilterRegistrationBean.setOrder
Haim Raman
Anda tidak perlu filter bean ketika Anda memanggil metode someFilter()secara langsung.
Minggu
117

Berikut ini adalah contoh dari salah satu metode termasuk filter khusus dalam aplikasi Spring Boot MVC. Pastikan untuk memasukkan paket dalam pemindaian komponen:

package com.dearheart.gtsc.filters;

import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletResponse;

import org.springframework.context.annotation.Profile;
import org.springframework.stereotype.Component;

@Component
public class XClacksOverhead implements Filter {

  public static final String X_CLACKS_OVERHEAD = "X-Clacks-Overhead";

  @Override
  public void doFilter(ServletRequest req, ServletResponse res,
      FilterChain chain) throws IOException, ServletException {

    HttpServletResponse response = (HttpServletResponse) res;
    response.setHeader(X_CLACKS_OVERHEAD, "GNU Terry Pratchett");
    chain.doFilter(req, res);
  }

  @Override
  public void destroy() {}

  @Override
  public void init(FilterConfig arg0) throws ServletException {}

}
tegatai
sumber
4
Haruskah filter terdaftar di suatu tempat?
gstackoverflow
1
Ketika saya mencoba pendekatan itu, Filter dibuat sebagai kacang dan bahkan disuntikkan ke kelas lain tetapi metode init () tidak berjalan . Mungkin, init () hanya berfungsi di register 'normal' bukan oleh wadah pegas. Saya pikir, orang dapat menggunakan PostConstruct bukannya init () tapi saya tidak mencobanya karena saya menolak menyatakan Filter sebagai Spring bean.
Baurzhan
Bagaimana dengan pemesanan filter menggunakan pendekatan ini?
Pavel Vlasov
Bagaimana kita bisa mendapatkan tubuh RS dari ServletResponse?
user2602807
1
Satu hal penting yang perlu diperhatikan adalah bahwa nama kacang Anda (berdasarkan nama kelas Anda) tidak boleh sama dengan kacang Spring. Misalnya, Anda mungkin tergoda untuk membuat MetricsFilter, tetapi kacang ini akan dibayangi oleh kacang aktuator Spring dengan nama yang sama. Belajar ini dengan cara yang sulit ...
kinbiko
78

Tidak ada penjelasan khusus untuk menunjukkan filter servlet. Anda cukup mendeklarasikan @Beantipe Filter(atau FilterRegistrationBean). Contoh (menambahkan tajuk khusus ke semua respons) ada dalam Boot's EndpointWebMvcAutoConfiguration ;

Jika Anda hanya menyatakan Filteritu akan diterapkan untuk semua permintaan. Jika Anda juga menambahkan, Anda juga FilterRegistrationBeandapat menentukan masing-masing servlet dan pola url untuk diterapkan.

catatan:

Pada Spring Boot 1.4, FilterRegistrationBeantidak usang dan hanya memindahkan paket dari org.springframework.boot.context.embedded.FilterRegistrationBeankeorg.springframework.boot.web.servlet.FilterRegistrationBean

Dave Syer
sumber
Maukah Anda memberi tahu saya cara memasukkan entri yang sesuai di build.gradle? Saya menambahkan yang berikut, tetapi tidak bisa dikompilasi: providedCompile ('javax.servlet: servlet-api: 2.5') runtime ('javax.servlet: jstl: 1.1.2')
janetsmith
2
Spring Boot tidak akan berfungsi dengan Servlet 2.5, dan belum ada banyak dukungan untuk JSP. Saya bukan benar-benar seorang grader, jadi saya tidak tahu apa yang Anda coba lakukan. Apa yang salah dengan "kompilasi"? Apakah ini berfungsi jika Anda hanya bergantung pada "spring-boot-starter-web"? (Saya tidak berpikir pertanyaan-pertanyaan ini terkait dengan pertanyaan awal, jadi mungkin Anda harus memposting lagi dengan pertanyaan-pertanyaan baru?)
Dave Syer
Saya menambahkan filter dengan mengimplementasikan antarmuka Filter, namun Eclipse tidak dapat menemukan antarmuka. Jadi saya mencoba mencari cara menambahkannya ke classpath untuk dikompilasi.
janetmith
1
Ya, tentu saja Anda harus memiliki Filterdi kelas Anda. Biasanya saya hanya akan menggunakan spring-boot-starter-webuntuk menarik semua dependensi yang relevan (misalnya di sini ).
Dave Syer
Sebagai detail tanggapan lainnya, Anda juga bisa membuat anotasi kelas Filter Anda dengan @Component dan akan didaftarkan secara otomatis (untuk semua URL).
Jakub Holý
72

Ada tiga cara untuk menambahkan filter Anda,

  1. Beri anotasi filter Anda dengan salah satu stereotip Spring seperti @Component
  2. Daftarkan @Beandengan Filtertipe di Musim Semi@Configuration
  3. Daftarkan @Beandengan FilterRegistrationBeantipe di Musim Semi@Configuration

# 1 atau # 2 akan dilakukan jika Anda ingin filter Anda berlaku untuk semua permintaan tanpa penyesuaian, gunakan # 3 sebaliknya. Anda tidak perlu menentukan pemindaian komponen untuk # 1 agar berfungsi selama Anda menempatkan kelas filter Anda di sub-paket yang sama atau SpringApplicationkelas Anda . Untuk # 3, gunakan bersama dengan # 2 hanya diperlukan ketika Anda ingin Spring mengelola kelas filter Anda seperti memilikinya dependensi kabel otomatis. Ini berfungsi dengan baik bagi saya untuk baru filter saya yang tidak memerlukan autowiring / injeksi ketergantungan.

Meskipun menggabungkan # 2 dan # 3 berfungsi dengan baik, saya terkejut itu tidak berakhir dengan dua filter yang diterapkan dua kali. Dugaan saya adalah bahwa Spring menggabungkan dua kacang sebagai satu ketika memanggil metode yang sama untuk membuat keduanya. Jika Anda ingin menggunakan # 3 sendirian dengan authowiring, Anda bisa AutowireCapableBeanFactory. Berikut ini adalah contoh,

private @Autowired AutowireCapableBeanFactory beanFactory;

    @Bean
    public FilterRegistrationBean myFilter() {
        FilterRegistrationBean registration = new FilterRegistrationBean();
        Filter myFilter = new MyFilter();
        beanFactory.autowireBean(myFilter);
        registration.setFilter(myFilter);
        registration.addUrlPatterns("/myfilterpath/*");
        return registration;
    }
barryku
sumber
Jawaban yang sangat bagus. Terima kasih telah merinci semua opsi dan juga membahas cara autowire Filtersaat Anda menggunakanFilterRegistrationBean
sbk
Jawaban yang bagus Ini persis seperti apa yang telah aku lakukan !!
haykart
Ini juga dijelaskan di sini: baeldung.com/spring-boot-add-filter
Jakub Holý
31

PEMBARUAN: 2017-12-16:

Ada 2 cara sederhana untuk melakukan ini di Spring Boot 1.5.8.RELEASE, tidak perlu untuk XML.

Cara pertama: Jika Anda tidak memiliki pola URL spacific, Anda dapat menggunakan @Component seperti ini: (Kode lengkap dan detailnya di sini https://www.surasint.com/spring-boot-filter/ )

@Component
public class ExampleFilter implements Filter{
   ...
}

Cara kedua: Jika Anda ingin menggunakan pola url, Anda dapat menggunakan @WebFilter seperti ini: (Kode lengkap dan detailnya di sini https://www.surasint.com/spring-boot-filter-urlpattern/ )

@WebFilter(urlPatterns = "/api/count")
public class ExampleFilter implements Filter{
 ...
}

Tetapi Anda juga perlu menambahkan anotasi @ServletComponentScan di kelas @SpringBootApplication Anda:

@ServletComponentScan
@SpringBootApplication
public class MyApplication extends SpringBootServletInitializer {
...
}

Perhatikan bahwa @Component adalah anotasi Spring, tetapi @WebFilter tidak. @WebFilter adalah anotasi Servlet 3.

Kedua cara, Anda hanya perlu ketergantungan Boot Musim Semi dasar di pom.xml (tidak perlu untuk jasper tertanam tomcat eksplisit)

    <?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.5.8.RELEASE</version>
    </parent>

    <groupId>com.surasint.example</groupId>
    <artifactId>spring-boot-04</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>jar</packaging>
    <properties>
        <maven.compiler.target>1.8</maven.compiler.target>
        <maven.compiler.source>1.8</maven.compiler.source>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>

PERINGATAN: Cara pertama, jika Controller di Spring Boot kembali ke file JSP, permintaan akan melewati filter dua kali.

Sementara, dengan cara kedua, permintaan akan melewati filter hanya sekali.

Saya lebih suka cara kedua karena lebih mirip dengan perilaku default dalam spesifikasi Servlet ( https://docs.oracle.com/cd/E19879-01/819-3669/6n5sg7b0b/index.html )

Anda dapat melihat lebih banyak log uji di sini https://www.surasint.com/spring-boot-webfilter-instead-of-component/

Surasin Tancharoen
sumber
Saya telah melihat Filterantarmuka dipanggil berkali-kali selama peluncuran applicationContext. Apakah ada cara untuk menjalankannya hanya sekali?
Pra_A
@PAA yang Anda maksud dari contoh saya?
Surasin Tancharoen
20

Berikut adalah contoh kelas Filter kustom saya:

package com.dawson.controller.filter;

import org.springframework.stereotype.Component;
import org.springframework.web.filter.GenericFilterBean;

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;


@Component
public class DawsonApiFilter extends GenericFilterBean {

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        HttpServletRequest req = (HttpServletRequest) request;
        if (req.getHeader("x-dawson-nonce") == null || req.getHeader("x-dawson-signature") == null) {
            HttpServletResponse httpResponse = (HttpServletResponse) response;
            httpResponse.setContentType("application/json");
            httpResponse.sendError(HttpServletResponse.SC_BAD_REQUEST, "Required headers not specified in the request");
            return;
        }
        chain.doFilter(request, response);
    }
}

Dan saya menambahkannya ke konfigurasi boot Spring dengan menambahkannya ke kelas Konfigurasi sebagai berikut:

package com.dawson.configuration;

import com.fasterxml.jackson.datatype.hibernate5.Hibernate5Module;
import com.dawson.controller.filter.DawsonApiFilter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;

@SpringBootApplication
public class ApplicationConfiguration {
    @Bean
    public FilterRegistrationBean dawsonApiFilter() {
        FilterRegistrationBean registration = new FilterRegistrationBean();
        registration.setFilter(new DawsonApiFilter());
// In case you want the filter to apply to specific URL patterns only
        registration.addUrlPatterns("/dawson/*");
        return registration;
    }
}
DPancs
sumber
14

Dari Spring docs,

Wadah servlet tertanam - Tambahkan Servlet, Saring atau Listener ke aplikasi

Untuk menambahkan Servlet, Filter, atau Servlet * Listener, berikan definisi @Bean untuknya.

Misalnya:

@Bean
public Filter compressFilter() {
    CompressingFilter compressFilter = new CompressingFilter();
    return compressFilter;
}

Tambahkan @Beankonfigurasi ini ke @Configurationkelas Anda dan filter akan terdaftar pada saat startup.

Anda juga dapat menambahkan Servlets, Filter, dan Pendengar menggunakan pemindaian classpath,

@WebServlet, @WebFilter, dan @WebListener kelas beranotasi dapat didaftarkan secara otomatis dengan wadah servlet tertanam dengan membubuhi keterangan kelas Konfigurasi @ dengan @ServletComponentScan dan menentukan paket yang berisi komponen yang ingin Anda daftarkan. Secara default, @ServletComponentScan akan memindai dari paket kelas beranotasi.

Beruntung
sumber
7

Jika Anda menggunakan Spring Boot + Spring Security, Anda dapat melakukannya di konfigurasi keamanan.

Dalam contoh di bawah ini, saya menambahkan filter khusus sebelum UsernamePasswordAuthenticationFilter (lihat semua filter Spring Security default dan urutannya ).

@EnableWebSecurity
class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired FilterDependency filterDependency;

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .addFilterBefore(
                new MyFilter(filterDependency),
                UsernamePasswordAuthenticationFilter.class);
    }
}

Dan kelas filter

class MyFilter extends OncePerRequestFilter  {
    private final FilterDependency filterDependency;

    public MyFilter(FilterDependency filterDependency) {
        this.filterDependency = filterDependency;
    }

    @Override
    protected void doFilterInternal(HttpServletRequest request,
        HttpServletResponse response,
        FilterChain filterChain)
        throws ServletException, IOException {
       // filter
       filterChain.doFilter(request, response);
    }
}
Andrei Epure
sumber
5

Menggunakan anotasi @WebFilter, dapat dilakukan sebagai berikut:

@WebFilter(urlPatterns = {"/*" })
public class AuthenticationFilter implements Filter{

    private static Logger logger = Logger.getLogger(AuthenticationFilter.class);

    @Override
    public void destroy() {
        // TODO Auto-generated method stub

    }

    @Override
    public void doFilter(ServletRequest arg0, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {

         logger.info("checking client id in filter");
        HttpServletRequest request = (HttpServletRequest) arg0;
        String clientId = request.getHeader("clientId");
        if (StringUtils.isNotEmpty(clientId)) {
            chain.doFilter(request, response);
        } else {
            logger.error("client id missing.");
        }
    }

    @Override
    public void init(FilterConfig arg0) throws ServletException {
        // TODO Auto-generated method stub

    }

}
KayV
sumber
3
Juga tambahkan @ServletComponentScan
Justas
5

Kami memiliki sekitar empat opsi berbeda untuk mendaftarkan filter menggunakan Spring .

Pertama, kita bisa membuat Filter implementasi kacang Spring atau memperluas HttpFilter :

@Component
public class MyFilter extends HttpFilter {

    @Override
    protected void doFilter(HttpServletRequest request, HttpServletResponse response, FilterChain chain) 
        throws IOException, ServletException {
        // Implementation details...

        chain.doFilter(request, response);
    }
}

Kedua, kita bisa membuat kacang Spring yang memperpanjang GenericFilterBean :

@Component
public class MyFilter extends GenericFilterBean {

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain chain)
  throws IOException, ServletException {
    //Implementation details...

        chain.doFilter(currentRequest, servletResponse);
    }
}

Atau kita bisa menggunakan kelas FilterRegistrationBean :

@Configuration
public class FilterConfiguration {

    private final MyFilter myFilter;

    @Autowired
    public FilterConfiguration(MyFilter myFilter) {
        this.myFilter = myFilter;
    }

    @Bean
    public FilterRegistrationBean<MyFilter> myFilterRegistration() {
        FilterRegistrationBean<DateLoggingFilter> filterRegistrationBean = new FilterRegistrationBean<>();
        filterRegistrationBean.setFilter(myFilter);
        filterRegistrationBean.setUrlPatterns(Collections.singletonList("/*"));
        filterRegistrationBean.setDispatcherTypes(DispatcherType.REQUEST);
        filterRegistrationBean.setOrder(Ordered.LOWEST_PRECEDENCE - 1);
        return filterRegistrationBean;
    }
}

Dan terakhir kita dapat menggunakan @WebFilter penjelasan dengan @ServletComponentScan :

@WebFilter(urlPatterns = "/*", dispatcherTypes = {DispatcherType.REQUEST})
public class MyFilter extends HttpFilter {

    @Override
    protected void doFilter(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
  throws IOException, ServletException {
        // Implementation details...

        chain.doFilter(request, response);
    }
}
isaolmez
sumber
Filter mana yang digunakan dan mengapa?
Pra_A
3

Ini lebih merupakan saran daripada jawaban, tetapi jika Anda menggunakan Spring MVC dalam aplikasi web Anda, ide baiknya adalah menggunakan Spring HandlerInterceptor alih-alih Filter

Ini dapat melakukan pekerjaan yang sama, tetapi juga - Dapat bekerja dengan ModelAndView - Metodenya dapat dipanggil sebelum dan sesudah pemrosesan permintaan, atau setelah permintaan selesai.
- Dapat dengan mudah diuji

1 Terapkan antarmuka HandlerInterceptor dan tambahkan anotasi @Component ke kelas Anda

@Component
public class SecurityInterceptor implements HandlerInterceptor {

    private static Logger log = LoggerFactory.getLogger(SecurityInterceptor.class);

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        request.getSession(true);
        if(isLoggedIn(request))
            return true;

        response.getWriter().write("{\"loggedIn\":false}");
        return false;
    }

    private boolean isLoggedIn(HttpServletRequest request) {
        try {
            UserSession userSession = (UserSession) request.getSession(true).getAttribute("userSession");
            return userSession != null && userSession.isLoggedIn();
        } catch(IllegalStateException ex) {
            return false;
        }
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable ModelAndView modelAndView) throws Exception {

    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable Exception ex) throws Exception {

    }
}

2 Konfigurasikan Interceptor Anda

@Configuration
public class WebConfig implements WebMvcConfigurer {

    private HandlerInterceptor securityInterceptor;

    @Autowired
    public void setSecurityInterceptor(HandlerInterceptor securityInterceptor) {
        this.securityInterceptor = securityInterceptor;
    }

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(securityInterceptor).addPathPatterns("/**").excludePathPatterns("/login", "/logout");
    }

}
Dengan mudah Komarov
sumber
Sederhana dan elegan! Terima kasih
MrMins
3

Filter ini juga akan membantu Anda mengizinkan akses lintas asal

@Component
@Order(Ordered.HIGHEST_PRECEDENCE)
public class SimpleCORSFilter implements Filter {

    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {

            HttpServletResponse response = (HttpServletResponse) res;
            HttpServletRequest request = (HttpServletRequest) req;
            response.setHeader("Access-Control-Allow-Origin", "*");
            response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");
            response.setHeader("Access-Control-Max-Age", "20000");
            response.setHeader("Access-Control-Allow-Headers", "x-requested-with, authorization, Content-Type, Authorization, credential, X-XSRF-TOKEN");

            if("OPTIONS".equalsIgnoreCase(request.getMethod())) {
                response.setStatus(HttpServletResponse.SC_OK);
            } else {
                chain.doFilter(req, res);
            }
    }


    public void destroy() {}

    @Override
    public void init(FilterConfig arg0) throws ServletException {
        // TODO Auto-generated method stub

    }

}
Ghulam Murtaza
sumber
2

Anda bisa menggunakan @WebFilter javax.servlet.annotation.WebFilter pada kelas yang mengimplementasikan javax.servlet.Filter

@WebFilter(urlPatterns = "/*")
public class MyFilter implements Filter {}

Kemudian gunakan @ServletComponentScan untuk mendaftar

Cwrwhaf
sumber
2

Saya melihat banyak jawaban di sini tetapi saya tidak mencoba salah satu dari mereka. Saya baru saja membuat filter seperti pada kode berikut.

import org.springframework.context.annotation.Configuration;
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import java.io.IOException;

@WebFilter(urlPatterns = "/Admin")
@Configuration
public class AdminFilter implements Filter{
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse  servletResponse, FilterChain filterChain) throws IOException, ServletException      {
    System.out.println("happened");

    }

    @Override
    public void destroy() {

    }
}

Dan meninggalkan aplikasi Spring Boot yang tersisa seperti itu.

Shaaban Ebrahim
sumber
2

Anda memerlukan 2 hal utama: - Tambahkan @ServletComponentScanke Kelas Utama Anda - Anda dapat menambahkan paket bernama filter di dalamnya Anda membuat FilterKelas yang memiliki yang berikut:

@Component
@Order(Ordered.HIGHEST_PRECEDENCE)
public class RequestFilter implements Filter {

 // whatever field you have

public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) {
    HttpServletResponse response = (HttpServletResponse) res;
    HttpServletRequest request = (HttpServletRequest) req;

 // whatever implementation you want

        try {
            chain.doFilter(req, res);
        } catch(Exception e) {
            e.printStackTrace();
        }

}

public void init(FilterConfig filterConfig) {}

public void destroy() {}
}
Slimane Deb
sumber
1

Anda juga dapat membuat filter dengan menggunakan @WebFilter dan mengimplementasikan Filter, itu akan dilakukan.

 @Configuration
        public class AppInConfig 
        {
        @Bean
      @Order(1)
      public FilterRegistrationBean aiFilterRegistration() {
            FilterRegistrationBean registration = new FilterRegistrationBean();
            registration.setFilter(new TrackingFilter());
            registration.addUrlPatterns("/**");
            registration.setOrder(1);
            return registration;
        } 
    @Bean(name = "TrackingFilter")
        public Filter TrackingFilter() {
            return new TrackingFilter();
        }   
    }
Muni
sumber
1

Filter seperti namanya disarankan untuk melakukan pemfilteran baik pada permintaan ke sumber daya atau pada respons dari sumber daya, atau keduanya. Spring Boot menyediakan beberapa opsi untuk mendaftarkan filter khusus dalam aplikasi Spring Boot. Mari kita lihat opsi yang berbeda.

1. Tentukan Spring Boot Filter dan Invocation Order

Terapkan antarmuka Filter untuk membuat filter baru di Spring Boot.

@Configuration
@Order(Ordered.HIGHEST_PRECEDENCE)
public class CustomFilter implements Filter {

 private static final Logger LOGGER = LoggerFactory.getLogger(CustomFilter.class);

 @Override
 public void init(FilterConfig filterConfig) throws ServletException {
  LOGGER.info("########## Initiating Custom filter ##########");
 }

 @Override
 public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {

  HttpServletRequest request = (HttpServletRequest) servletRequest;
  HttpServletResponse response = (HttpServletResponse) servletResponse;

  LOGGER.info("Logging Request  {} : {}", request.getMethod(), request.getRequestURI());

  //call next filter in the filter chain
  filterChain.doFilter(request, response);

  LOGGER.info("Logging Response :{}", response.getContentType());
 }

 @Override
 public void destroy() {
  // TODO: 7/4/18
 }
}

Mari kita cepat melihat beberapa poin penting dalam kode di atas

  • Filter terdaftar oleh anotasi @Component .
  • Untuk mengaktifkan filter dengan urutan yang benar – kami harus menggunakan anotasi @Order .

    @Component
    @Order(1)
    public class CustomFirstFilter implements Filter {
    
    }
    @Component
    @Order(2)
    public class CustomSecondFilter implements Filter {
    
    }

Dalam kode di atas, CustomFirstFilter akan berjalan sebelum CustomSecondFilter.

Semakin rendah angkanya, semakin tinggi prioritasnya

2. Pola URL

Jika pemetaan berbasis konvensi tidak cukup fleksibel, kita dapat menggunakan FilterRegistrationBean untuk kontrol penuh aplikasi. Di sini, jangan gunakan @Component annotation untuk kelas filter tetapi daftarkan filter menggunakan FilterRegistrationBean .

 public class CustomURLFilter implements Filter {

 private static final Logger LOGGER = LoggerFactory.getLogger(CustomURLFilter.class);

 @Override
 public void init(FilterConfig filterConfig) throws ServletException {
  LOGGER.info("########## Initiating CustomURLFilter filter ##########");
 }

 @Override
 public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {

  HttpServletRequest request = (HttpServletRequest) servletRequest;
  HttpServletResponse response = (HttpServletResponse) servletResponse;

  LOGGER.info("This Filter is only called when request is mapped for /customer resource");

  //call next filter in the filter chain
  filterChain.doFilter(request, response);
 }

 @Override
 public void destroy() {

 }
}

Daftarkan Filter khusus menggunakan FilterRegistrationBean .

@Configuration
public class AppConfig {

 @Bean
 public FilterRegistrationBean < CustomURLFilter > filterRegistrationBean() {
  FilterRegistrationBean < CustomURLFilter > registrationBean = new FilterRegistrationBean();
  CustomURLFilter customURLFilter = new CustomURLFilter();

  registrationBean.setFilter(customURLFilter);
  registrationBean.addUrlPatterns("/greeting/*");
  registrationBean.setOrder(2); //set precedence
  return registrationBean;
 }
}
Yogesh
sumber
1

    @WebFilter(urlPatterns="/*")
    public class XSSFilter implements Filter {

        private static final org.apache.log4j.Logger LOGGER = LogManager.getLogger(XSSFilter.class);

        @Override
        public void init(FilterConfig filterConfig) throws ServletException {
            LOGGER.info("Initiating XSSFilter... ");

        }

        @Override
        public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
                throws IOException, ServletException {
            HttpServletRequest req = (HttpServletRequest) request;
            HttpRequestWrapper requestWrapper = new HttpRequestWrapper(req);
            chain.doFilter(requestWrapper, response);
        }

        @Override
        public void destroy() {
            LOGGER.info("Destroying XSSFilter... ");
        }

    }

Anda perlu menerapkan Filter dan perlu dijelaskan dengan @WebFilter (urlPatterns = "/ *")

Dan di kelas Aplikasi atau Konfigurasi Anda perlu menambahkan @ServletComponentScan. Dengan ini, filter Anda akan didaftarkan.

Rahul Anand
sumber
Ini @WebFilterhanya sejak Servlet 3.0. Jadi mungkin tidak berfungsi dengan baik untuk 2,5
ha9u63ar
1

Langkah 1: Buat komponen filter dengan menerapkan antarmuka Filter.

@Component
public class PerformanceFilter implements Filter {

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {

            ......
            ......
    }

}

Langkah 2: Atur filter ini ke pola uri menggunakan FilterRegistrationBean.

@Configuration
public class FilterConfig {
    @Bean
    public FilterRegistrationBean<PerformanceFilter> perfFilter() {
        FilterRegistrationBean<PerformanceFilter> registration = new FilterRegistrationBean<>();
        registration.setFilter(new PerformanceFilter());
        registration.addUrlPatterns("/*");
        return registration;
    }
}

Anda dapat merujuk tautan ini untuk aplikasi lengkap.

Hari Krishna
sumber
0

Pertama, tambahkan @ServletComponentScanke kelas SpringBootApplication Anda.

@ServletComponentScan
public class Application {

Kedua, buat file filter yang memperpanjang Filter atau kelas filter pihak ketiga dan tambahkan @WebFilterke file ini seperti ini:

@Order(1) //optional
@WebFilter(filterName = "XXXFilter", urlPatterns = "/*",
    dispatcherTypes = {DispatcherType.REQUEST, DispatcherType.FORWARD},
    initParams = {@WebInitParam(name = "confPath", value = "classpath:/xxx.xml")})
public class XXXFilter extends Filter{
ooit
sumber
0

Saya melihat jawaban oleh @Vasily Komarov. Pendekatan yang serupa, tetapi menggunakan kelas HandlerInterceptorAdapter abstrak daripada menggunakan HandlerInterceptor .

Berikut ini sebuah contoh ...

@Component
public class CustomInterceptor extends HandlerInterceptorAdapter {
   @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
            throws Exception {
    }
}

@Configuration
public class InterceptorConfig extends WebMvcConfigurerAdapter {

    @Autowired
    private CustomInterceptor customInterceptor ;

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(customInterceptor );
    }

}
Shaunak Patel
sumber
0

Seperti yang Anda ketahui, Spring Boot adalah cara luar biasa untuk mengembangkan WebApp atau StandaloneApp dengan konfigurasi minimum dan Pengaturan yang disarankan.

Ini adalah bagaimana saya telah mencapai Pengembangan Web Filter di aplikasi Spring Boot

Spesifikasi SpringBootApp Saya: -

Versi Spring Boot: 2.0.4.RELEASE
Versi Java: 8.0
Spesifikasi Servlet: Servlet 3.0 (Wajib dan Penting)

Saya mendeklarasikan Filter Web saya dengan cara berikut, mengikuti Servlet Spesifikasi 3.0

masukkan deskripsi gambar di sini Ini adalah cara terprogram untuk mendefinisikan Filter sebagai pengganti definisi berbasis web.xml.

"@Webfilter" anotasi akan diproses oleh wadah selama penyebaran, kelas Filter tempat ditemukan akan dibuat sesuai konfigurasi dan diterapkan ke pola URL, javax.servlet.Servlets dan javax.servlet.DispatcherTypes.

Untuk menghindari Web.xml sepenuhnya dan mencapai WebApp "Deployable": -

Untuk menggunakan Aplikasi Boot Spring sebagai "PERANG Tradisional", kelas aplikasi harus memperluas SpringBootServletInitializer.

CATATAN :: SpringBootServletInitializer adalah "Implementasi Programmatic" dari web.xml dengan mengacu pada spesifikasi Servlet 3.0+, yang memerlukan implementasi WebApplicationInitializer.

Dengan demikian, SpringBootApplication tidak memerlukan "web.xml" sebagai kelas Aplikasi (setelah memperpanjang SpringBootServletInitializer) memindai
- @WebFilter,
- @WebListener dan
- @WebServlet.

Anotasi @ServletComponentScan

Anotasi ini memungkinkan pemindaian paket dasar untuk komponen web yang dianotasi dengan @WebFilter, @WebListener dan @WebServlet.

Karena kenyataan bahwa wadah yang disematkan tidak mendukung anotasi @WebServlet, @WebFilter dan @WebListener, Spring Boot, sangat bergantung pada wadah yang disematkan, memperkenalkan anotasi baru ini @ServletComponentScan untuk mendukung beberapa toples dependen yang menggunakan 3 anotasi ini.

Pemindaian hanya dilakukan saat menggunakan wadah Servlet tertanam.

Berikut ini adalah Definisi Kelas Aplikasi Boot Spring saya: -

masukkan deskripsi gambar di sini

Inisialisasi Custom Servlet: -

Di sini: Saya telah mendefinisikan Kelas Kustom: "ServletInitializer" yang memperluas Kelas: SpringBootServletInitializer.

Seperti yang dijelaskan sebelumnya, SpringBootServletInitializer bertanggung jawab untuk memindai anotasi: -
- @WebFilter,
- @WebListener dan
- @WebServlet.

Dan karenanya Kelas Aplikasi Boot Musim Semi seharusnya

  • Baik memperpanjang kelas: SpringBootServletInitializer OR
  • rentangkan kelas Kustom yang memperluas kelas: SpringBootServletInitializer

masukkan deskripsi gambar di sini

Philip Dilip
sumber
-6

Filter sebagian besar digunakan dalam file logger bervariasi sesuai dengan logger yang Anda gunakan dalam proyek biar jelaskan untuk log4j2:

<Filters>
                <!-- It prevents error -->
                <ThresholdFilter level="error" onMatch="DENY" onMismatch="NEUTRAL"/>
                <!-- It prevents debug -->
                <ThresholdFilter level="debug" onMatch="DENY" onMismatch="NEUTRAL" />
                <!-- It allows all levels except debug/trace -->
                <ThresholdFilter level="info" onMatch="ACCEPT" onMismatch="DENY" /> 
            </Filters>

Filter digunakan untuk membatasi data dan saya menggunakan filter ambang batas lebih lanjut untuk membatasi level data dalam aliran yang saya sebutkan level yang dapat dibatasi di sana. Untuk referensi Anda lebih lanjut lihat urutan tingkat log4j2 - Tingkat Log4J: ALL> TRACE> DEBUG> INFO> PERINGATAN> KESALAHAN> FATAL> MATI

saravanan
sumber
FilterRegistrationBeanseperti yang disebutkan dalam pertanyaan adalah untuk javax.servlet.Filter, jawaban ini berbicara tentangorg.apache.logging.log4j.core.Filter
Steve Buzonas